summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.osdl.org>2003-09-08 23:34:41 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-09-08 23:34:41 -0700
commit968736ca224c73c8c3ab1ee67198dc77e2277409 (patch)
treee58754de0bf0258fd37e9f300dc413a5bc0cdae7
parentbc1055789a55240e922b1a5b1c420f0e120e88da (diff)
parentcfd86a52b932be625accb516373833b71009cb17 (diff)
Merge bk://ppc.bkbits.net/for-linus-ppc
into home.osdl.org:/home/torvalds/v2.5/linux
-rw-r--r--arch/i386/kernel/reboot.c2
-rw-r--r--arch/ia64/Kconfig3
-rw-r--r--arch/ia64/Makefile1
-rw-r--r--arch/ia64/hp/common/sba_iommu.c5
-rw-r--r--arch/ia64/hp/sim/boot/boot_head.S8
-rw-r--r--arch/ia64/hp/sim/boot/bootloader.c10
-rw-r--r--arch/ia64/ia32/elfcore32.h5
-rw-r--r--arch/ia64/kernel/acpi.c4
-rw-r--r--arch/ia64/kernel/efi.c2
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/fsys.S4
-rw-r--r--arch/ia64/kernel/init_task.c6
-rw-r--r--arch/ia64/kernel/perfmon.c301
-rw-r--r--arch/ia64/kernel/perfmon_hpsim.h75
-rw-r--r--arch/ia64/kernel/smpboot.c4
-rw-r--r--arch/ia64/kernel/time.c79
-rw-r--r--arch/ia64/oprofile/Kconfig22
-rw-r--r--arch/ia64/oprofile/Makefile9
-rw-r--r--arch/ia64/oprofile/init.c25
-rwxr-xr-xarch/ia64/scripts/toolchain-flags2
-rw-r--r--arch/ia64/sn/io/drivers/ioconfig_bus.c16
-rw-r--r--arch/ia64/sn/io/machvec/pci_bus_cvlink.c2
-rw-r--r--arch/ia64/sn/io/machvec/pci_dma.c2
-rw-r--r--arch/ia64/sn/io/sn2/ml_SN_intr.c4
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_config.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_error.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c1
-rw-r--r--arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c1
-rw-r--r--arch/ia64/sn/io/sn2/pic.c1
-rw-r--r--drivers/block/ll_rw_blk.c8
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/agp/via-agp.c2
-rw-r--r--drivers/char/hw_random.c2
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/char/watchdog/amd7xx_tco.c2
-rw-r--r--drivers/char/watchdog/i810-tco.c2
-rw-r--r--drivers/ide/ide-default.c8
-rw-r--r--drivers/ide/ide-io.c8
-rw-r--r--drivers/isdn/hardware/eicon/Kconfig20
-rw-r--r--drivers/isdn/hardware/eicon/Makefile7
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c187
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.h8
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c56
-rw-r--r--drivers/isdn/hardware/eicon/dadapter.c23
-rw-r--r--drivers/isdn/hardware/eicon/debug.c21
-rw-r--r--drivers/isdn/hardware/eicon/debuglib.c8
-rw-r--r--drivers/isdn/hardware/eicon/debuglib.h40
-rw-r--r--drivers/isdn/hardware/eicon/di.c34
-rw-r--r--drivers/isdn/hardware/eicon/diddfunc.c14
-rw-r--r--drivers/isdn/hardware/eicon/diva.c29
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c54
-rw-r--r--drivers/isdn/hardware/eicon/diva_pci.h7
-rw-r--r--drivers/isdn/hardware/eicon/divacapi.h2
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c64
-rw-r--r--drivers/isdn/hardware/eicon/divasfunc.c27
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c75
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c103
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c32
-rw-r--r--drivers/isdn/hardware/eicon/dlist.c36
-rw-r--r--drivers/isdn/hardware/eicon/dlist.h14
-rw-r--r--drivers/isdn/hardware/eicon/idifunc.c16
-rw-r--r--drivers/isdn/hardware/eicon/io.c140
-rw-r--r--drivers/isdn/hardware/eicon/io.h11
-rw-r--r--drivers/isdn/hardware/eicon/message.c34
-rw-r--r--drivers/isdn/hardware/eicon/mntfunc.c14
-rw-r--r--drivers/isdn/hardware/eicon/os_4bri.c175
-rw-r--r--drivers/isdn/hardware/eicon/os_bri.c116
-rw-r--r--drivers/isdn/hardware/eicon/os_pri.c150
-rw-r--r--drivers/isdn/hardware/eicon/platform.h96
-rw-r--r--drivers/isdn/hardware/eicon/s_4bri.c130
-rw-r--r--drivers/isdn/hardware/eicon/s_bri.c95
-rw-r--r--drivers/isdn/hardware/eicon/s_pri.c107
-rw-r--r--drivers/isdn/hardware/eicon/um_idi.c17
-rw-r--r--drivers/isdn/hardware/eicon/xdi_adapter.h5
-rw-r--r--drivers/isdn/hisax/config.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c2
-rw-r--r--drivers/net/dgrs.c2
-rw-r--r--drivers/net/fc/iph5526.c2
-rw-r--r--drivers/net/hp100.c2
-rw-r--r--drivers/net/irda/via-ircc.c2
-rw-r--r--drivers/net/skfp/skfddi.c2
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/wan/sdladrv.c2
-rw-r--r--drivers/serial/8250.c24
-rw-r--r--drivers/serial/8250.h4
-rw-r--r--drivers/serial/8250_pci.c22
-rw-r--r--drivers/serial/Kconfig32
-rw-r--r--drivers/serial/Makefile4
-rw-r--r--drivers/serial/clps711x.c12
-rw-r--r--drivers/serial/sa1100.c8
-rw-r--r--drivers/serial/serial_core.c (renamed from drivers/serial/core.c)94
-rw-r--r--drivers/serial/serial_cs.c (renamed from drivers/serial/8250_cs.c)0
-rw-r--r--drivers/video/i810/i810_main.c2
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/afs/Makefile2
-rw-r--r--fs/afs/cache-layout.h224
-rw-r--r--fs/afs/cache.h27
-rw-r--r--fs/afs/callback.c2
-rw-r--r--fs/afs/cell.c108
-rw-r--r--fs/afs/cell.h27
-rw-r--r--fs/afs/cmservice.c36
-rw-r--r--fs/afs/dir.c30
-rw-r--r--fs/afs/file.c211
-rw-r--r--fs/afs/inode.c70
-rw-r--r--fs/afs/internal.h21
-rw-r--r--fs/afs/kafsasyncd.c9
-rw-r--r--fs/afs/kafstimod.c20
-rw-r--r--fs/afs/main.c90
-rw-r--r--fs/afs/mntpt.c182
-rw-r--r--fs/afs/mount.h2
-rw-r--r--fs/afs/server.c3
-rw-r--r--fs/afs/super.c392
-rw-r--r--fs/afs/super.h2
-rw-r--r--fs/afs/types.h15
-rw-r--r--fs/afs/vlclient.c97
-rw-r--r--fs/afs/vlclient.h9
-rw-r--r--fs/afs/vlocation.c280
-rw-r--r--fs/afs/vnode.c74
-rw-r--r--fs/afs/vnode.h30
-rw-r--r--fs/afs/volume.c177
-rw-r--r--fs/afs/volume.h87
-rw-r--r--fs/eventpoll.c41
-rw-r--r--fs/ext2/symlink.c3
-rw-r--r--fs/fat/file.c8
-rw-r--r--fs/proc/generic.c23
-rw-r--r--fs/proc/kcore.c5
-rw-r--r--fs/proc/kmsg.c8
-rw-r--r--fs/proc/proc_misc.c14
-rw-r--r--fs/ufs/namei.c6
-rw-r--r--fs/xattr.c38
-rw-r--r--include/asm-ia64/acpi.h68
-rw-r--r--include/asm-ia64/hw_irq.h1
-rw-r--r--include/asm-ia64/intel_intrin.h254
-rw-r--r--include/asm-ia64/ptrace.h6
-rw-r--r--include/asm-ia64/signal.h13
-rw-r--r--include/asm-ia64/sn/hcl.h1
-rw-r--r--include/asm-ia64/sn/ioc3.h705
-rw-r--r--include/asm-ia64/sn/klclock.h61
-rw-r--r--include/asm-ia64/sn/nodepda.h2
-rw-r--r--include/asm-ia64/sn/pci/pciio.h34
-rw-r--r--include/asm-ia64/sn/sn2/intr.h3
-rw-r--r--include/asm-ia64/spinlock.h55
-rw-r--r--include/asm-ia64/uaccess.h87
-rw-r--r--include/asm-ia64/unistd.h1
-rw-r--r--include/linux/cpufreq.h2
-rw-r--r--include/linux/eventpoll.h7
-rw-r--r--include/linux/seq_file.h3
-rw-r--r--include/linux/serial_core.h10
-rw-r--r--include/linux/writeback.h4
-rw-r--r--include/rxrpc/call.h14
-rw-r--r--include/rxrpc/connection.h21
-rw-r--r--include/rxrpc/message.h8
-rw-r--r--include/rxrpc/packet.h47
-rw-r--r--include/rxrpc/peer.h5
-rw-r--r--include/rxrpc/rxrpc.h2
-rw-r--r--include/rxrpc/transport.h10
-rw-r--r--include/rxrpc/types.h4
-rw-r--r--kernel/sysctl.c2
-rw-r--r--net/core/dev.c6
-rw-r--r--net/rxrpc/Makefile12
-rw-r--r--net/rxrpc/call.c879
-rw-r--r--net/rxrpc/connection.c305
-rw-r--r--net/rxrpc/internal.h4
-rw-r--r--net/rxrpc/krxiod.c65
-rw-r--r--net/rxrpc/krxsecd.c66
-rw-r--r--net/rxrpc/krxtimod.c61
-rw-r--r--net/rxrpc/main.c77
-rw-r--r--net/rxrpc/peer.c131
-rw-r--r--net/rxrpc/proc.c136
-rw-r--r--net/rxrpc/sysctl.c19
-rw-r--r--net/rxrpc/transport.c291
177 files changed, 4872 insertions, 3816 deletions
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index be18ab2e9baf..fb28a5a000ff 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -251,7 +251,7 @@ void machine_restart(char * __unused)
* other OSs see a clean IRQ state.
*/
smp_send_stop();
-#elif CONFIG_X86_LOCAL_APIC
+#elif defined(CONFIG_X86_LOCAL_APIC)
if (cpu_has_apic) {
local_irq_disable();
disable_local_APIC();
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 9d4b08b893d1..a34c4788b99e 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -267,7 +267,7 @@ config IA64_MCA
unsure, answer Y.
config PM
- bool
+ bool "Power Management support"
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
default y
---help---
@@ -569,6 +569,7 @@ source "lib/Kconfig"
source "arch/ia64/hp/sim/Kconfig"
+source "arch/ia64/oprofile/Kconfig"
menu "Kernel hacking"
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 94d1034f8c3d..fbad6558252c 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -65,6 +65,7 @@ drivers-$(CONFIG_PCI) += arch/ia64/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
+drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
boot := arch/ia64/hp/sim/boot
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index c20455ccdb1b..59220cccf9b3 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -227,12 +227,7 @@ struct ioc {
static struct ioc *ioc_list;
static int reserve_sba_gart = 1;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define sba_sg_address(sg) (page_address((sg)->page) + (sg)->offset)
-#else
-#define sba_sg_address(sg) ((sg)->address ? (sg)->address : \
- page_address((sg)->page) + (sg)->offset)
-#endif
#ifdef FULL_VALID_PDIR
static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S
index 92c20ce3c404..43dcebc8fd6d 100644
--- a/arch/ia64/hp/sim/boot/boot_head.S
+++ b/arch/ia64/hp/sim/boot/boot_head.S
@@ -27,6 +27,14 @@ GLOBAL_ENTRY(_start)
br.call.sptk.many rp=start_bootloader
END(_start)
+/*
+ * Set a break point on this function so that symbols are available to set breakpoints in
+ * the kernel being debugged.
+ */
+GLOBAL_ENTRY(debug_break)
+ br.ret.sptk.many b0
+END(debug_break)
+
GLOBAL_ENTRY(ssc)
.regstk 5,0,0,0
mov r15=in4
diff --git a/arch/ia64/hp/sim/boot/bootloader.c b/arch/ia64/hp/sim/boot/bootloader.c
index f49cde5de1f9..51a7b7b4dd0e 100644
--- a/arch/ia64/hp/sim/boot/bootloader.c
+++ b/arch/ia64/hp/sim/boot/bootloader.c
@@ -37,15 +37,7 @@ struct disk_stat {
extern void jmp_to_kernel (unsigned long bp, unsigned long e_entry);
extern struct ia64_boot_param *sys_fw_init (const char *args, int arglen);
-
-/*
- * Set a break point on this function so that symbols are available to set breakpoints in
- * the kernel being debugged.
- */
-static void
-debug_break (void)
-{
-}
+extern void debug_break (void);
static void
cons_write (const char *buf)
diff --git a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h
index 407bfaea60d4..36f8d42e392a 100644
--- a/arch/ia64/ia32/elfcore32.h
+++ b/arch/ia64/ia32/elfcore32.h
@@ -8,6 +8,8 @@
#ifndef _ELFCORE32_H_
#define _ELFCORE32_H_
+#include <asm/intrinsics.h>
+
#define USE_ELF_CORE_DUMP 1
/* Override elfcore.h */
@@ -79,8 +81,7 @@ struct elf_prpsinfo
pr_reg[11] = regs->r1; \
pr_reg[12] = regs->cr_iip; \
pr_reg[13] = regs->r17 & 0xffff; \
- asm volatile ("mov %0=ar.eflag ;;" \
- : "=r"(pr_reg[14])); \
+ pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG); \
pr_reg[15] = regs->r12; \
pr_reg[16] = (regs->r17 >> 16) & 0xffff;
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index d5e1917e8715..6ee74e2ef0b9 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -603,11 +603,13 @@ acpi_boot_init (void)
printk(KERN_ERR PREFIX "Can't find FADT\n");
#ifdef CONFIG_SMP
- smp_boot_data.cpu_count = available_cpus;
if (available_cpus == 0) {
printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
+ printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
+ smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
available_cpus = 1; /* We've got at least one of these, no? */
}
+ smp_boot_data.cpu_count = available_cpus;
smp_build_cpu_map();
# ifdef CONFIG_NUMA
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 0338b214d2f0..8941b976474d 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -324,7 +324,7 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
check_md = q;
if (check_md->attribute & EFI_MEMORY_WB)
- trim_bottom(md, granule_addr);
+ trim_bottom(check_md, granule_addr);
if (check_md->phys_addr < granule_addr)
continue;
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 5d4c8d38785e..f9a462f588ef 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1448,7 +1448,7 @@ sys_call_table:
data8 sys_sched_setaffinity
data8 sys_sched_getaffinity
data8 sys_set_tid_address
- data8 sys_fadvise64
+ data8 sys_fadvise64_64
data8 sys_tgkill // 1235
data8 sys_exit_group
data8 sys_lookup_dcookie
@@ -1473,7 +1473,7 @@ sys_call_table:
data8 sys_clock_nanosleep
data8 sys_fstatfs64
data8 sys_statfs64
- data8 sys_fadvise64_64
+ data8 ia64_ni_syscall
data8 ia64_ni_syscall // 1260
data8 ia64_ni_syscall
data8 ia64_ni_syscall
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index f99167964293..dafa9bcfac4a 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -655,7 +655,7 @@ fsyscall_table:
data8 0 // sched_setaffinity
data8 0 // sched_getaffinity
data8 fsys_set_tid_address // set_tid_address
- data8 0 // fadvise64
+ data8 0 // fadvise64_64
data8 0 // tgkill // 1235
data8 0 // exit_group
data8 0 // lookup_dcookie
@@ -680,7 +680,7 @@ fsyscall_table:
data8 0 // clock_nanosleep
data8 0 // fstatfs64
data8 0 // statfs64
- data8 0 // fadvise64_64
+ data8 0
data8 0 // 1260
data8 0
data8 0
diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c
index ab79b199aadf..241a84cacba6 100644
--- a/arch/ia64/kernel/init_task.c
+++ b/arch/ia64/kernel/init_task.c
@@ -28,15 +28,13 @@ struct mm_struct init_mm = INIT_MM(init_mm);
*/
#define init_thread_info init_task_mem.s.thread_info
-static union {
+union {
struct {
struct task_struct task;
struct thread_info thread_info;
} s;
unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
-} init_task_mem asm ("init_task_mem") __attribute__((section(".data.init_task"))) = {{
+} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{
.task = INIT_TASK(init_task_mem.s.task),
.thread_info = INIT_THREAD_INFO(init_task_mem.s.task)
}};
-
-extern struct task_struct init_task __attribute__ ((alias("init_task_mem")));
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 53271196df2c..b7365a87f59a 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -58,23 +58,8 @@
#define PFM_CTX_ZOMBIE 4 /* owner of the context is closing it */
#define PFM_CTX_TERMINATED 5 /* the task the context was loaded onto is gone */
-#define CTX_LOADED(c) (c)->ctx_state = PFM_CTX_LOADED
-#define CTX_UNLOADED(c) (c)->ctx_state = PFM_CTX_UNLOADED
-#define CTX_ZOMBIE(c) (c)->ctx_state = PFM_CTX_ZOMBIE
-#define CTX_DESTROYED(c) (c)->ctx_state = PFM_CTX_DESTROYED
-#define CTX_MASKED(c) (c)->ctx_state = PFM_CTX_MASKED
-#define CTX_TERMINATED(c) (c)->ctx_state = PFM_CTX_TERMINATED
-
-#define CTX_IS_UNLOADED(c) ((c)->ctx_state == PFM_CTX_UNLOADED)
-#define CTX_IS_LOADED(c) ((c)->ctx_state == PFM_CTX_LOADED)
-#define CTX_IS_ZOMBIE(c) ((c)->ctx_state == PFM_CTX_ZOMBIE)
-#define CTX_IS_MASKED(c) ((c)->ctx_state == PFM_CTX_MASKED)
-#define CTX_IS_TERMINATED(c) ((c)->ctx_state == PFM_CTX_TERMINATED)
-#define CTX_IS_DEAD(c) ((c)->ctx_state == PFM_CTX_TERMINATED || (c)->ctx_state == PFM_CTX_ZOMBIE)
-
#define PFM_INVALID_ACTIVATION (~0UL)
-
/*
* depth of message queue
*/
@@ -649,6 +634,7 @@ DEFINE_PER_CPU(struct task_struct *, pmu_owner);
DEFINE_PER_CPU(pfm_context_t *, pmu_ctx);
DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+
/* forward declaration */
static struct file_operations pfm_file_ops;
@@ -659,7 +645,13 @@ static struct file_operations pfm_file_ops;
static void pfm_lazy_save_regs (struct task_struct *ta);
#endif
-#if defined(CONFIG_ITANIUM)
+/*
+ * the HP simulator must be first because
+ * CONFIG_IA64_HP_SIM is independent of CONFIG_MCKINLEY or CONFIG_ITANIUM
+ */
+#if defined(CONFIG_IA64_HP_SIM)
+#include "perfmon_hpsim.h"
+#elif defined(CONFIG_ITANIUM)
#include "perfmon_itanium.h"
#elif defined(CONFIG_MCKINLEY)
#include "perfmon_mckinley.h"
@@ -953,13 +945,15 @@ pfm_restore_monitoring(struct task_struct *task)
struct thread_struct *th = &task->thread;
unsigned long mask;
unsigned long psr, val;
- int i;
+ int i, is_system;
+
+ is_system = ctx->ctx_fl_system;
if (task != current) {
printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
return;
}
- if (CTX_IS_MASKED(ctx) == 0) {
+ if (ctx->ctx_state != PFM_CTX_MASKED) {
printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
task->pid, current->pid, ctx->ctx_state);
return;
@@ -975,7 +969,7 @@ pfm_restore_monitoring(struct task_struct *task)
*
* system-wide session are pinned and self-monitoring
*/
- if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+ if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
/* disable dcr pp */
ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP);
pfm_clear_psr_pp();
@@ -1022,7 +1016,7 @@ pfm_restore_monitoring(struct task_struct *task)
/*
* now restore PSR
*/
- if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+ if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
/* enable dcr pp */
ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP);
ia64_srlz_i();
@@ -1825,6 +1819,7 @@ pfm_close(struct inode *inode, struct file *filp)
void *smpl_buf_vaddr = NULL;
void *smpl_buf_addr = NULL;
int free_possible = 1;
+ int state, is_system;
{ u64 psr = pfm_get_psr();
BUG_ON((psr & IA64_PSR_I) == 0UL);
@@ -1850,6 +1845,11 @@ pfm_close(struct inode *inode, struct file *filp)
PROTECT_CTX(ctx, flags);
+ state = ctx->ctx_state;
+ is_system = ctx->ctx_fl_system;
+
+ task = PFM_CTX_TASK(ctx);
+
/*
* remove our file from the async queue, if we use it
*/
@@ -1859,11 +1859,10 @@ pfm_close(struct inode *inode, struct file *filp)
DPRINT(("[%d] after async_queue=%p\n", current->pid, ctx->ctx_async_queue));
}
- task = PFM_CTX_TASK(ctx);
- DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
+ DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
- if (CTX_IS_UNLOADED(ctx) || CTX_IS_TERMINATED(ctx)) {
+ if (state == PFM_CTX_UNLOADED || state == PFM_CTX_TERMINATED) {
goto doit;
}
@@ -1884,7 +1883,7 @@ pfm_close(struct inode *inode, struct file *filp)
*
* We need to release the resource on the ORIGINAL cpu.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
@@ -1900,9 +1899,10 @@ pfm_close(struct inode *inode, struct file *filp)
task->thread.pfm_context = NULL;
ctx->ctx_task = NULL;
- CTX_UNLOADED(ctx);
+ ctx->ctx_state = state = PFM_CTX_UNLOADED;
pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
+
} else
#endif /* CONFIG_SMP */
{
@@ -1914,19 +1914,20 @@ pfm_close(struct inode *inode, struct file *filp)
*/
pfm_context_unload(ctx, NULL, 0, regs);
- CTX_TERMINATED(ctx);
+ ctx->ctx_state = PFM_CTX_TERMINATED;
- DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
+ DPRINT(("[%d] ctx_state=%d\n", current->pid, state));
}
goto doit;
}
+
/*
* The task is currently blocked or will block after an overflow.
* we must force it to wakeup to get out of the
* MASKED state and transition to the unloaded state by itself
*/
- if (CTX_IS_MASKED(ctx) && CTX_OVFL_NOBLOCK(ctx) == 0) {
+ if (state == PFM_CTX_MASKED && CTX_OVFL_NOBLOCK(ctx) == 0) {
/*
* set a "partial" zombie state to be checked
@@ -1949,7 +1950,7 @@ pfm_close(struct inode *inode, struct file *filp)
*/
up(&ctx->ctx_restart_sem);
- DPRINT(("waking up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+ DPRINT(("waking up ctx_state=%d for [%d]\n", state, current->pid));
/*
* put ourself to sleep waiting for the other
@@ -1971,24 +1972,24 @@ pfm_close(struct inode *inode, struct file *filp)
*/
schedule();
- DPRINT(("woken up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
PROTECT_CTX(ctx, flags);
+
remove_wait_queue(&ctx->ctx_zombieq, &wait);
set_current_state(TASK_RUNNING);
/*
* context is terminated at this point
*/
- DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+ DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", state, current->pid));
}
else {
#ifdef CONFIG_SMP
/*
* switch context to zombie state
*/
- CTX_ZOMBIE(ctx);
+ ctx->ctx_state = PFM_CTX_ZOMBIE;
DPRINT(("zombie ctx for [%d]\n", task->pid));
/*
@@ -2002,6 +2003,10 @@ pfm_close(struct inode *inode, struct file *filp)
}
doit: /* cannot assume task is defined from now on */
+
+ /* reload state, may have changed during opening of critical section */
+ state = ctx->ctx_state;
+
/*
* the context is still attached to a task (possibly current)
* we cannot destroy it right now
@@ -2032,10 +2037,9 @@ doit: /* cannot assume task is defined from now on */
ctx->ctx_smpl_hdr = NULL;
}
-
DPRINT(("[%d] ctx_state=%d free_possible=%d vaddr=%p addr=%p size=%lu\n",
current->pid,
- ctx->ctx_state,
+ state,
free_possible,
smpl_buf_vaddr,
smpl_buf_addr,
@@ -2047,7 +2051,7 @@ doit: /* cannot assume task is defined from now on */
* UNLOADED and TERMINATED mean that the session has already been
* unreserved.
*/
- if (CTX_IS_ZOMBIE(ctx)) {
+ if (state == PFM_CTX_ZOMBIE) {
pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu);
}
@@ -2360,10 +2364,23 @@ error_kmem:
static int
pfm_bad_permissions(struct task_struct *task)
{
- /* stolen from bad_signal() */
- return (current->session != task->session)
- && (current->euid ^ task->suid) && (current->euid ^ task->uid)
- && (current->uid ^ task->suid) && (current->uid ^ task->uid);
+ /* inspired by ptrace_attach() */
+ DPRINT(("[%d] cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n",
+ current->pid,
+ current->uid,
+ current->gid,
+ task->euid,
+ task->suid,
+ task->uid,
+ task->egid,
+ task->sgid));
+
+ return ((current->uid != task->euid)
+ || (current->uid != task->suid)
+ || (current->uid != task->uid)
+ || (current->gid != task->egid)
+ || (current->gid != task->sgid)
+ || (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE);
}
static int
@@ -2655,7 +2672,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
/*
* context is unloaded
*/
- CTX_UNLOADED(ctx);
+ ctx->ctx_state = PFM_CTX_UNLOADED;
/*
* initialization of context's flags
@@ -2787,7 +2804,7 @@ pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int flag)
if (flag == PFM_PMD_NO_RESET) return;
- if (CTX_IS_MASKED(ctx)) {
+ if (ctx->ctx_state == PFM_CTX_MASKED) {
pfm_reset_regs_masked(ctx, ovfl_regs, flag);
return;
}
@@ -2836,27 +2853,30 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
unsigned long value;
unsigned long smpl_pmds, reset_pmds;
unsigned int cnum, reg_flags, flags;
- int i, can_access_pmu = 0, is_loaded;
- int is_monitor, is_counting;
+ int i, can_access_pmu = 0, is_loaded, is_system;
+ int is_monitor, is_counting, state;
int ret = -EINVAL;
#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
- if (CTX_IS_DEAD(ctx)) return -EINVAL;
+ state = ctx->ctx_state;
+ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
+ is_system = ctx->ctx_fl_system;
+
+ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
- is_loaded = CTX_IS_LOADED(ctx);
if (is_loaded) {
thread = &ctx->ctx_task->thread;
- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
/*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
+ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
}
for (i = 0; i < count; i++, req++) {
@@ -2893,7 +2913,6 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
goto error;
}
-
if (is_counting) {
pfm_monitor_t *p = (pfm_monitor_t *)&value;
/*
@@ -2975,7 +2994,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* make sure we do not try to reset on
* restart because we have established new values
*/
- if (CTX_IS_MASKED(ctx)) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+ if (state == PFM_CTX_MASKED) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
}
/*
* Needed in case the user does not initialize the equivalent
@@ -3007,7 +3026,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/*
* write thread state
*/
- if (ctx->ctx_fl_system == 0) thread->pmcs[cnum] = value;
+ if (is_system == 0) thread->pmcs[cnum] = value;
/*
* write hardware register if we can
@@ -3067,13 +3086,16 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
pfarg_reg_t *req = (pfarg_reg_t *)arg;
unsigned long value, hw_value;
unsigned int cnum;
- int i, can_access_pmu = 0;
- int is_counting, is_loaded;
+ int i, can_access_pmu = 0, state;
+ int is_counting, is_loaded, is_system;
int ret = -EINVAL;
- if (CTX_IS_DEAD(ctx)) return -EINVAL;
- is_loaded = CTX_IS_LOADED(ctx);
+ state = ctx->ctx_state;
+ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
+ is_system = ctx->ctx_fl_system;
+
+ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
/*
* on both UP and SMP, we can only write to the PMC when the task is
@@ -3081,16 +3103,16 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
if (is_loaded) {
thread = &ctx->ctx_task->thread;
- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
/*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
+ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
}
for (i = 0; i < count; i++, req++) {
@@ -3179,7 +3201,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* make sure we do not try to reset on
* restart because we have established new values
*/
- if (is_counting && CTX_IS_MASKED(ctx)) {
+ if (is_counting && state == PFM_CTX_MASKED) {
ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
}
@@ -3187,7 +3209,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/*
* write thread state
*/
- if (ctx->ctx_fl_system == 0) thread->pmds[cnum] = hw_value;
+ if (is_system == 0) thread->pmds[cnum] = hw_value;
/*
* write hardware register if we can
@@ -3265,35 +3287,40 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
unsigned long val = 0UL, lval ;
pfarg_reg_t *req = (pfarg_reg_t *)arg;
unsigned int cnum, reg_flags = 0;
- int i, is_loaded, can_access_pmu = 0;
+ int i, can_access_pmu = 0, state;
+ int is_loaded, is_system;
int ret = -EINVAL;
- if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
-
/*
* access is possible when loaded only for
* self-monitoring tasks or in UP mode
*/
- is_loaded = CTX_IS_LOADED(ctx);
+
+ state = ctx->ctx_state;
+ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
+ is_system = ctx->ctx_fl_system;
+
+ if (state == PFM_CTX_ZOMBIE) return -EINVAL;
if (is_loaded) {
thread = &ctx->ctx_task->thread;
/*
- * this can be true when not self-monitoring only in UP
- */
- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task? 1 : 0;
-
- if (can_access_pmu) ia64_srlz_d();
- /*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
+ /*
+ * this can be true when not self-monitoring only in UP
+ */
+ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
+
+ if (can_access_pmu) ia64_srlz_d();
}
+
DPRINT(("enter loaded=%d access_pmu=%d ctx_state=%d\n",
is_loaded,
can_access_pmu,
@@ -3334,7 +3361,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* if context is zombie, then task does not exist anymore.
* In this case, we use the full value saved in the context (pfm_flush_regs()).
*/
- val = CTX_IS_LOADED(ctx) ? thread->pmds[cnum] : 0UL;
+ val = state == PFM_CTX_LOADED ? thread->pmds[cnum] : 0UL;
}
if (PMD_IS_COUNTING(cnum)) {
@@ -3628,7 +3655,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
if (rst_ctrl.bits.mask_monitoring == 0) {
DPRINT(("resuming monitoring for [%d]\n", task->pid));
- if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(task);
+ if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
} else {
DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
@@ -3643,7 +3670,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/*
* back to LOADED state
*/
- CTX_LOADED(ctx);
+ ctx->ctx_state = PFM_CTX_LOADED;
return 0;
}
@@ -3706,30 +3733,34 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
dbreg_t dbreg;
unsigned int rnum;
int first_time;
- int ret = 0;
- int i, can_access_pmu = 0, is_loaded;
+ int ret = 0, state;
+ int i, can_access_pmu = 0;
+ int is_system, is_loaded;
if (pmu_conf.use_rr_dbregs == 0) return -EINVAL;
- if (CTX_IS_DEAD(ctx)) return -EINVAL;
+ state = ctx->ctx_state;
+ is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
+ is_system = ctx->ctx_fl_system;
+
+ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL;
- is_loaded = CTX_IS_LOADED(ctx);
/*
* on both UP and SMP, we can only write to the PMC when the task is
* the owner of the local PMU.
*/
if (is_loaded) {
thread = &ctx->ctx_task->thread;
- can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
/*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
+ can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0;
}
/*
@@ -3758,7 +3789,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
*/
LOCK_PFS();
- if (first_time && ctx->ctx_fl_system) {
+ if (first_time && is_system) {
if (pfm_sessions.pfs_ptrace_use_dbregs)
ret = -EBUSY;
else
@@ -3906,16 +3937,19 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
{
struct pt_regs *tregs;
struct task_struct *task = PFM_CTX_TASK(ctx);
+ int state, is_system;
+ state = ctx->ctx_state;
+ is_system = ctx->ctx_fl_system;
- if (CTX_IS_LOADED(ctx) == 0 && CTX_IS_MASKED(ctx) == 0) return -EINVAL;
+ if (state != PFM_CTX_LOADED && state != PFM_CTX_MASKED) return -EINVAL;
/*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
@@ -3925,7 +3959,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* and the user level state of the caller, which may not
* necessarily be the creator of the context.
*/
- if (ctx->ctx_fl_system) {
+ if (is_system) {
/*
* Update local PMU first
*
@@ -3985,15 +4019,19 @@ static int
pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
{
struct pt_regs *tregs;
+ int state, is_system;
+
+ state = ctx->ctx_state;
+ is_system = ctx->ctx_fl_system;
- if (CTX_IS_LOADED(ctx) == 0) return -EINVAL;
+ if (state != PFM_CTX_LOADED) return -EINVAL;
/*
* In system wide and when the context is loaded, access can only happen
* when the caller is running on the CPU being monitored by the session.
* It does not have to be the owner (ctx_task) of the context per se.
*/
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+ if (is_system && ctx->ctx_cpu != smp_processor_id()) {
DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
return -EBUSY;
}
@@ -4003,7 +4041,7 @@ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* and the user level state of the caller, which may not
* necessarily be the creator of the context.
*/
- if (ctx->ctx_fl_system) {
+ if (is_system) {
/*
* set user level psr.pp for the caller
@@ -4055,7 +4093,6 @@ pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
ia64_psr(tregs)->up = 1;
}
-
return 0;
}
@@ -4121,11 +4158,14 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
unsigned long *pmcs_source, *pmds_source;
int the_cpu;
int ret = 0;
+ int state, is_system;
+ state = ctx->ctx_state;
+ is_system = ctx->ctx_fl_system;
/*
* can only load from unloaded or terminated state
*/
- if (CTX_IS_UNLOADED(ctx) == 0 && CTX_IS_TERMINATED(ctx) == 0) {
+ if (state != PFM_CTX_UNLOADED && state != PFM_CTX_TERMINATED) {
DPRINT(("[%d] cannot load to [%d], invalid ctx_state=%d\n",
current->pid,
req->load_pid,
@@ -4151,7 +4191,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/*
* system wide is self monitoring only
*/
- if (ctx->ctx_fl_system && task != current) {
+ if (is_system && task != current) {
DPRINT(("system wide is self monitoring only current=%d load_pid=%d\n",
current->pid,
req->load_pid));
@@ -4191,7 +4231,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/*
* now reserve the session
*/
- ret = pfm_reserve_session(current, ctx->ctx_fl_system, the_cpu);
+ ret = pfm_reserve_session(current, is_system, the_cpu);
if (ret) goto error;
ret = -EBUSY;
@@ -4216,15 +4256,14 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
pfm_reset_msgq(ctx);
- CTX_LOADED(ctx);
+ ctx->ctx_state = PFM_CTX_LOADED;
/*
* link context to task
*/
ctx->ctx_task = task;
- if (ctx->ctx_fl_system) {
-
+ if (is_system) {
/*
* we load as stopped
*/
@@ -4250,7 +4289,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
if (task == current) {
- if (ctx->ctx_fl_system == 0) {
+ if (is_system == 0) {
/* allow user level control */
ia64_psr(regs)->sp = 0;
@@ -4318,14 +4357,14 @@ error:
/*
* release task, there is now a link with the context
*/
- if (ctx->ctx_fl_system == 0 && task != current) {
+ if (is_system == 0 && task != current) {
pfm_put_task(task);
if (ret == 0) {
ret = pfm_check_task_exist(ctx);
if (ret) {
- CTX_UNLOADED(ctx);
- ctx->ctx_task = NULL;
+ ctx->ctx_state = PFM_CTX_UNLOADED;
+ ctx->ctx_task = NULL;
}
}
}
@@ -4347,40 +4386,34 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
{
struct task_struct *task = PFM_CTX_TASK(ctx);
struct pt_regs *tregs;
+ int state, is_system;
DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+ state = ctx->ctx_state;
+ is_system = ctx->ctx_fl_system;
+
/*
* unload only when necessary
*/
- if (CTX_IS_TERMINATED(ctx) || CTX_IS_UNLOADED(ctx)) {
+ if (state == PFM_CTX_TERMINATED || state == PFM_CTX_UNLOADED) {
DPRINT(("[%d] ctx_state=%d, nothing to do\n", current->pid, ctx->ctx_state));
return 0;
}
/*
- * In system wide and when the context is loaded, access can only happen
- * when the caller is running on the CPU being monitored by the session.
- * It does not have to be the owner (ctx_task) of the context per se.
- */
- if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
- DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
- return -EBUSY;
- }
-
- /*
* clear psr and dcr bits
*/
pfm_stop(ctx, NULL, 0, regs);
- CTX_UNLOADED(ctx);
+ ctx->ctx_state = state = PFM_CTX_UNLOADED;
/*
* in system mode, we need to update the PMU directly
* and the user level state of the caller, which may not
* necessarily be the creator of the context.
*/
- if (ctx->ctx_fl_system) {
+ if (is_system) {
/*
* Update cpuinfo
@@ -4524,7 +4557,7 @@ pfm_exit_thread(struct task_struct *task)
if (ret) {
printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, ctx->ctx_state, ret);
}
- CTX_TERMINATED(ctx);
+ ctx->ctx_state = PFM_CTX_TERMINATED;
DPRINT(("ctx terminated by [%d]\n", task->pid));
pfm_end_notify_user(ctx);
@@ -4606,16 +4639,19 @@ static int
pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
{
struct task_struct *task;
+ int state;
+
+ state = ctx->ctx_state;
task = PFM_CTX_TASK(ctx);
if (task == NULL) {
- DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, ctx->ctx_state));
+ DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, state));
return 0;
}
DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
ctx->ctx_fd,
- ctx->ctx_state,
+ state,
task->pid,
task->state, PFM_CMD_STOPPED(cmd)));
@@ -4631,9 +4667,9 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
/*
* context is UNLOADED, MASKED, TERMINATED we are safe to go
*/
- if (CTX_IS_LOADED(ctx) == 0) return 0;
+ if (state != PFM_CTX_LOADED == 0) return 0;
- if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
+ if (state == PFM_CTX_ZOMBIE) return -EINVAL;
/*
* context is loaded, we must make sure the task is stopped
@@ -4653,6 +4689,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
pfm_wait_task_inactive(task);
PROTECT_CTX(ctx, flags);
+
return 0;
}
@@ -4830,12 +4867,12 @@ pfm_resume_after_ovfl(pfm_context_t *ctx, unsigned long ovfl_regs, struct pt_reg
}
if (rst_ctrl.bits.mask_monitoring == 0) {
DPRINT(("resuming monitoring\n"));
- if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(current);
+ if (ctx->ctx_state == PFM_CTX_MASKED) pfm_restore_monitoring(current);
} else {
DPRINT(("stopping monitoring\n"));
//pfm_stop_monitoring(current, regs);
}
- CTX_LOADED(ctx);
+ ctx->ctx_state = PFM_CTX_LOADED;
}
}
@@ -4869,7 +4906,7 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
/*
* switch to terminated state
*/
- CTX_TERMINATED(ctx);
+ ctx->ctx_state = PFM_CTX_TERMINATED;
DPRINT(("context <%d> terminated for [%d]\n", ctx->ctx_fd, current->pid));
@@ -4922,7 +4959,7 @@ pfm_handle_work(void)
/*
* must be done before we check non-blocking mode
*/
- if (ctx->ctx_fl_going_zombie || CTX_IS_ZOMBIE(ctx)) goto do_zombie;
+ if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie;
ovfl_regs = ctx->ctx_ovfl_regs[0];
@@ -4966,7 +5003,7 @@ nothing_to_do:
static int
pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg)
{
- if (CTX_IS_ZOMBIE(ctx)) {
+ if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
DPRINT(("ignoring overflow notification, owner is zombie\n"));
return 0;
}
@@ -5049,13 +5086,13 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
pfm_ovfl_arg_t ovfl_arg;
unsigned long mask;
unsigned long old_val;
- unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
+ unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL;
unsigned long tstamp;
pfm_ovfl_ctrl_t ovfl_ctrl;
unsigned int i, has_smpl;
int must_notify = 0;
- if (unlikely(CTX_IS_ZOMBIE(ctx))) goto stop_monitoring;
+ if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) goto stop_monitoring;
/*
* sanity test. Should never happen
@@ -5106,10 +5143,9 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i;
}
- DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx "
- "ovfl_notify=0x%lx\n",
- i, ctx->ctx_pmds[i].val, old_val,
- ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify));
+ DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx smpl_pmds=0x%lx\n",
+ i, ctx->ctx_pmds[i].val, old_val,
+ ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify, smpl_pmds));
}
/*
@@ -5128,7 +5164,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
*/
if (has_smpl) {
unsigned long start_cycles, end_cycles;
- unsigned long pmd_mask, smpl_pmds;
+ unsigned long pmd_mask;
int j, k, ret = 0;
int this_cpu = smp_processor_id();
@@ -5257,7 +5293,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
*/
if (ovfl_ctrl.bits.mask_monitoring) {
pfm_mask_monitoring(task);
- CTX_MASKED(ctx);
+ ctx->ctx_state = PFM_CTX_MASKED;
}
/*
@@ -5553,19 +5589,18 @@ pfm_do_syst_wide_update_task(struct task_struct *task, unsigned long info, int i
pfm_set_psr_pp();
ia64_srlz_i();
}
- { unsigned long val;
- val = ia64_get_pmc(4);
- if ((val & (1UL<<23)) == 0UL) printk("perfmon: PMU off: pmc4=0x%lx\n", val);
- }
}
void
pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
{
unsigned long start, end;
+
pfm_stats[smp_processor_id()].pfm_sysupdt_count++;
start = ia64_get_itc();
+
pfm_do_syst_wide_update_task(task, info, is_ctxswin);
+
end = ia64_get_itc();
pfm_stats[smp_processor_id()].pfm_sysupdt_cycles += end-start;
}
@@ -5591,7 +5626,7 @@ pfm_save_regs(struct task_struct *task)
*/
flags = pfm_protect_ctx_ctxsw(ctx);
- if (CTX_IS_ZOMBIE(ctx)) {
+ if (ctx->ctx_state == PFM_CTX_ZOMBIE) {
struct pt_regs *regs = ia64_task_regs(task);
pfm_clear_psr_up();
@@ -5840,7 +5875,7 @@ pfm_load_regs (struct task_struct *task)
BUG_ON(psr & IA64_PSR_I);
#endif
- if (unlikely(CTX_IS_ZOMBIE(ctx))) {
+ if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) {
struct pt_regs *regs = ia64_task_regs(task);
BUG_ON(ctx->ctx_smpl_hdr);
diff --git a/arch/ia64/kernel/perfmon_hpsim.h b/arch/ia64/kernel/perfmon_hpsim.h
new file mode 100644
index 000000000000..9c6fe7fc175f
--- /dev/null
+++ b/arch/ia64/kernel/perfmon_hpsim.h
@@ -0,0 +1,75 @@
+/*
+ * This file contains the HP SKI Simulator PMU register description tables
+ * and pmc checkers used by perfmon.c.
+ *
+ * Copyright (C) 2002-2003 Hewlett Packard Co
+ * Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * File mostly contributed by Ian Wienand <ianw@gelato.unsw.edu.au>
+ *
+ * This file is included as a dummy template so the kernel does not
+ * try to initalize registers the simulator can't handle.
+ *
+ * Note the simulator does not (currently) implement these registers, i.e.,
+ * they do not count anything. But you can read/write them.
+ */
+
+#define RDEP(x) (1UL<<(x))
+
+#ifndef CONFIG_IA64_HP_SIM
+#error "This file should only be included for the HP Simulator"
+#endif
+
+static pfm_reg_desc_t pfm_hpsim_pmc_desc[PMU_MAX_PMCS]={
+/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(10), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(11), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(12), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(13), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(14), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(15), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pfm_hpsim_pmd_desc[PMU_MAX_PMDS]={
+/* pmd0 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmd1 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmd2 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmd3 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+/* pmd8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(8),0UL, 0UL, 0UL}},
+/* pmd9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(9),0UL, 0UL, 0UL}},
+/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(13),0UL, 0UL, 0UL}},
+/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(14),0UL, 0UL, 0UL}},
+/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(15),0UL, 0UL, 0UL}},
+ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+/*
+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
+ */
+static pmu_config_t pmu_conf={
+ .pmu_name = "hpsim",
+ .pmu_family = 0x7, /* ski emulator reports as Itanium */
+ .enabled = 0,
+ .ovfl_val = (1UL << 32) - 1,
+ .num_ibrs = 0, /* does not use */
+ .num_dbrs = 0, /* does not use */
+ .pmd_desc = pfm_hpsim_pmd_desc,
+ .pmc_desc = pfm_hpsim_pmc_desc
+};
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 32bcf58681eb..554815286ab9 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -534,8 +534,8 @@ smp_prepare_cpus (unsigned int max_cpus)
printk(KERN_INFO "SMP mode deactivated.\n");
cpus_clear(cpu_online_map);
cpus_clear(phys_cpu_present_map);
- cpu_set(1, cpu_online_map);
- cpu_set(1, phys_cpu_present_map);
+ cpu_set(0, cpu_online_map);
+ cpu_set(0, phys_cpu_present_map);
return;
}
}
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 11a9cc6a2411..156401c955f5 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -17,6 +17,7 @@
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/efi.h>
+#include <linux/profile.h>
#include <linux/timex.h>
#include <asm/delay.h>
@@ -39,29 +40,6 @@ unsigned long last_cli_ip;
#endif
static void
-do_profile (unsigned long ip)
-{
- extern cpumask_t prof_cpu_mask;
-
- if (!prof_buffer)
- return;
-
- if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
- return;
-
- ip -= (unsigned long) _stext;
- ip >>= prof_shift;
- /*
- * Don't ignore out-of-bounds IP values silently, put them into the last
- * histogram slot, so if present, they will show up as a sharp peak.
- */
- if (ip > prof_len - 1)
- ip = prof_len - 1;
-
- atomic_inc((atomic_t *) &prof_buffer[ip]);
-}
-
-static void
itc_reset (void)
{
}
@@ -199,6 +177,52 @@ do_gettimeofday (struct timeval *tv)
tv->tv_usec = usec;
}
+/*
+ * The profiling function is SMP safe. (nothing can mess
+ * around with "current", and the profiling counters are
+ * updated with atomic operations). This is especially
+ * useful with a profiling multiplier != 1
+ */
+static inline void
+ia64_do_profile (struct pt_regs * regs)
+{
+ unsigned long ip, slot;
+ extern unsigned long prof_cpu_mask;
+
+ profile_hook(regs);
+
+ if (user_mode(regs))
+ return;
+
+ if (!prof_buffer)
+ return;
+
+ ip = instruction_pointer(regs);
+ /* Conserve space in histogram by encoding slot bits in address
+ * bits 2 and 3 rather than bits 0 and 1.
+ */
+ slot = ip & 3;
+ ip = (ip & ~3UL) + 4*slot;
+
+ /*
+ * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
+ * (default is all CPUs.)
+ */
+ if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
+ return;
+
+ ip -= (unsigned long) &_stext;
+ ip >>= prof_shift;
+ /*
+ * Don't ignore out-of-bounds IP values silently,
+ * put them into the last histogram slot, so if
+ * present, they will show up as a sharp peak.
+ */
+ if (ip > prof_len-1)
+ ip = prof_len-1;
+ atomic_inc((atomic_t *)&prof_buffer[ip]);
+}
+
static irqreturn_t
timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
@@ -210,14 +234,9 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
ia64_get_itc(), new_itm);
+ ia64_do_profile(regs);
+
while (1) {
- /*
- * Do kernel PC profiling here. We multiply the instruction number by
- * four so that we can use a prof_shift of 2 to get instruction-level
- * instead of just bundle-level accuracy.
- */
- if (!user_mode(regs))
- do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri);
#ifdef CONFIG_SMP
smp_do_timer(regs);
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
new file mode 100644
index 000000000000..bfac82f3e3c8
--- /dev/null
+++ b/arch/ia64/oprofile/Kconfig
@@ -0,0 +1,22 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile
new file mode 100644
index 000000000000..06e7c81ead2e
--- /dev/null
+++ b/arch/ia64/oprofile/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) init.o
diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c
new file mode 100644
index 000000000000..558561d6d112
--- /dev/null
+++ b/arch/ia64/oprofile/init.c
@@ -0,0 +1,25 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+extern void timer_init(struct oprofile_operations ** ops);
+
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
+{
+ return -ENODEV;
+}
+
+
+void oprofile_arch_exit(void)
+{
+}
diff --git a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags
index 97c72117f5d2..a9b64a538c5f 100755
--- a/arch/ia64/scripts/toolchain-flags
+++ b/arch/ia64/scripts/toolchain-flags
@@ -20,7 +20,7 @@ warning: your linker cannot handle cross-segment segment-relative relocations.
EOF
fi
-if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep -q 'attribute directive ignored'
+if ! $CC -c $dir/check-model.c -o $out 2>&1 | grep __model__ | grep -q attrib
then
CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
fi
diff --git a/arch/ia64/sn/io/drivers/ioconfig_bus.c b/arch/ia64/sn/io/drivers/ioconfig_bus.c
index 85c8cd0ed018..a361ba8c9357 100644
--- a/arch/ia64/sn/io/drivers/ioconfig_bus.c
+++ b/arch/ia64/sn/io/drivers/ioconfig_bus.c
@@ -24,7 +24,7 @@
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
-#include <asm//sn/sn_sal.h>
+#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
#include <asm/sn/ioconfig_bus.h>
@@ -157,7 +157,7 @@ build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
char *name;
char *temp;
char *next;
- char *current;
+ char *curr;
char *line;
struct ascii_moduleid *moduleid;
@@ -166,10 +166,10 @@ build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
name = kmalloc(125, GFP_KERNEL);
memset(name, 0, 125);
moduleid = table;
- current = file_contents;
- while (nextline(current, &next, line)){
+ curr = file_contents;
+ while (nextline(curr, &next, line)){
- DBG("current 0x%lx next 0x%lx\n", current, next);
+ DBG("curr 0x%lx next 0x%lx\n", curr, next);
temp = line;
/*
@@ -182,7 +182,7 @@ build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
break;
if (*temp == '\n') {
- current = next;
+ curr = next;
memset(line, 0, 256);
continue;
}
@@ -191,7 +191,7 @@ build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
* Skip comment lines
*/
if (*temp == '#') {
- current = next;
+ curr = next;
memset(line, 0, 256);
continue;
}
@@ -204,7 +204,7 @@ build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
DBG("Found %s\n", name);
moduleid++;
free_entry++;
- current = next;
+ curr = next;
memset(line, 0, 256);
}
diff --git a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
index 455b5884fee6..b8ce32192015 100644
--- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
+++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
@@ -544,7 +544,7 @@ sn_pci_fixup(int arg)
pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN,
(unsigned char *)&lines);
- irqpdaindr->current = device_dev;
+ irqpdaindr->curr = device_dev;
intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
irq = intr_handle->pi_irq;
diff --git a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c
index 5a26e7efb80a..209c5a0b2093 100644
--- a/arch/ia64/sn/io/machvec/pci_dma.c
+++ b/arch/ia64/sn/io/machvec/pci_dma.c
@@ -597,7 +597,7 @@ sn_dma_set_mask(struct device *dev, u64 dma_mask)
if (!sn_dma_supported(dev, dma_mask))
return 0;
- dev->dma_mask = dma_mask;
+ *dev->dma_mask = dma_mask;
return 1;
}
EXPORT_SYMBOL(sn_dma_set_mask);
diff --git a/arch/ia64/sn/io/sn2/ml_SN_intr.c b/arch/ia64/sn/io/sn2/ml_SN_intr.c
index 31da1ccb1bc5..e569b0f107fb 100644
--- a/arch/ia64/sn/io/sn2/ml_SN_intr.c
+++ b/arch/ia64/sn/io/sn2/ml_SN_intr.c
@@ -174,8 +174,8 @@ do_intr_reserve_level(cpuid_t cpu,
min_shared = 256;
for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
/* Share with the same device class */
- if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
- irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
+ if (irqpdaindr->curr->vendor == irqpdaindr->device_dev[i]->vendor &&
+ irqpdaindr->curr->device == irqpdaindr->device_dev[i]->device &&
irqpdaindr->share_count[i] < min_shared) {
min_shared = irqpdaindr->share_count[i];
bit = i;
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
index ce602a247971..84495257b961 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
index 77a9f9a3686d..a42f52051143 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
@@ -27,7 +27,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
index 0a9b7f98c631..ea5fada58a31 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
@@ -31,7 +31,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
index 91ee03e14b35..857ff8cfde13 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
index 3b9344a36f54..3f6a6cde69a9 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
index dd633b33cec4..1e0c7999ad9d 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
index 9063c1f1d8be..c5b2fc3e3452 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
index 2c9c7129daa5..631d5602660b 100644
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
@@ -27,7 +27,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/arch/ia64/sn/io/sn2/pic.c b/arch/ia64/sn/io/sn2/pic.c
index ee95e9b4848f..b805256e11fb 100644
--- a/arch/ia64/sn/io/sn2/pic.c
+++ b/arch/ia64/sn/io/sn2/pic.c
@@ -26,7 +26,6 @@
#include <asm/sn/pci/pci_defs.h>
#include <asm/sn/prio.h>
#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 5a4d6a931ccd..fa00e0152d1a 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -1016,7 +1016,13 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
void blk_plug_device(request_queue_t *q)
{
WARN_ON(!irqs_disabled());
- if (!blk_queue_plugged(q)) {
+
+ /*
+ * don't plug a stopped queue, it must be paired with blk_start_queue()
+ * which will restart the queueing
+ */
+ if (!blk_queue_plugged(q)
+ && !test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
spin_lock(&blk_plug_lock);
list_add_tail(&q->plug_list, &blk_plug_list);
mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 7ec62223e419..59a671bea216 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -491,7 +491,7 @@ static void __devexit agp_ati_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_ati_pci_table[] __initdata = {
+static struct pci_device_id agp_ati_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index f79d7b1f9028..0d7e66316624 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -215,7 +215,7 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_sis_pci_table[] __initdata = {
+static struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a89924fa3a50..1fa77885c111 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -350,7 +350,7 @@ static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_uninorth_pci_table[] __initdata = {
+static struct pci_device_id agp_uninorth_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 5d8768a90ed1..fb248b5585fd 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -432,7 +432,7 @@ static void __devexit agp_via_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_via_pci_table[] __initdata = {
+static struct pci_device_id agp_via_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 757b1687b4cb..4b9684f91606 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -149,7 +149,7 @@ static struct rng_operations rng_vendor_ops[] = {
* register a pci_driver, because someone else might one day
* want to register another driver on the same PCI id.
*/
-static struct pci_device_id rng_pci_tbl[] __initdata = {
+static struct pci_device_id rng_pci_tbl[] = {
{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
{ 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index 8be74993f420..6c3ba56186be 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -317,7 +317,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void
* want to register another driver on the same PCI id.
*/
-static struct pci_device_id ali_pci_tbl[] __initdata = {
+static struct pci_device_id ali_pci_tbl[] = {
{ PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,},
{ 0, },
};
diff --git a/drivers/char/watchdog/amd7xx_tco.c b/drivers/char/watchdog/amd7xx_tco.c
index 52c59122b698..5418e6134d9c 100644
--- a/drivers/char/watchdog/amd7xx_tco.c
+++ b/drivers/char/watchdog/amd7xx_tco.c
@@ -294,7 +294,7 @@ static struct miscdevice amdtco_miscdev =
.fops = &amdtco_fops
};
-static struct pci_device_id amdtco_pci_tbl[] __initdata = {
+static struct pci_device_id amdtco_pci_tbl[] = {
/* AMD 766 PCI_IDs here */
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }
diff --git a/drivers/char/watchdog/i810-tco.c b/drivers/char/watchdog/i810-tco.c
index 39b816e66912..782584ab039f 100644
--- a/drivers/char/watchdog/i810-tco.c
+++ b/drivers/char/watchdog/i810-tco.c
@@ -301,7 +301,7 @@ static int i810tco_ioctl (struct inode *inode, struct file *file,
* register a pci_driver, because someone else might one day
* want to register another driver on the same PCI id.
*/
-static struct pci_device_id i810tco_pci_tbl[] __initdata = {
+static struct pci_device_id i810tco_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
index 0c251121a740..b16a4b42e5cc 100644
--- a/drivers/ide/ide-default.c
+++ b/drivers/ide/ide-default.c
@@ -57,6 +57,14 @@ static int idedefault_attach (ide_drive_t *drive)
"driver with ide.c\n", drive->name);
return 1;
}
+
+ /* For the sake of the request layer, we must make sure we have a
+ * correct ready_stat value, that is 0 for ATAPI devices or we will
+ * fail any request like Power Management
+ */
+ if (drive->media != ide_disk)
+ drive->ready_stat = 0;
+
return 0;
}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 0d9fff1f883d..5295420010db 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -928,13 +928,10 @@ queue_next:
*
* We let requests forced at head of queue with ide-preempt
* though. I hope that doesn't happen too much, hopefully not
- * unless the subdriver triggers such a thing in it's own PM
+ * unless the subdriver triggers such a thing in its own PM
* state machine.
*/
if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
-#ifdef DEBUG_PM
- printk("%s: a request made it's way while we are power managing...\n", drive->name);
-#endif
/* We clear busy, there should be no pending ATA command at this point. */
hwgroup->busy = 0;
break;
@@ -1417,8 +1414,9 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
}
spin_lock_irqsave(&ide_lock, flags);
- if (action == ide_preempt || action == ide_head_wait) {
+ if (action == ide_preempt)
hwgroup->rq = NULL;
+ if (action == ide_preempt || action == ide_head_wait) {
where = ELEVATOR_INSERT_FRONT;
rq->flags |= REQ_PREEMPT;
}
diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
index c929795e5856..12f84f9e9c1b 100644
--- a/drivers/isdn/hardware/eicon/Kconfig
+++ b/drivers/isdn/hardware/eicon/Kconfig
@@ -12,7 +12,7 @@ config CAPI_EICON
config ISDN_DIVAS
tristate "Support Eicon DIVA Server cards"
- depends on CAPI_EICON && PROC_FS && PCI && m
+ depends on CAPI_EICON && PROC_FS && PCI
help
Say Y here if you have an Eicon Networks DIVA Server PCI ISDN card.
In order to use this card, additional firmware is necessary, which
@@ -24,12 +24,6 @@ config ISDN_DIVAS_BRIPCI
help
Enable support for DIVA Server BRI-PCI.
-config ISDN_DIVAS_4BRIPCI
- bool "DIVA Server 4BRI/PCI support"
- depends on ISDN_DIVAS
- help
- Enable support for DIVA Server 4BRI-PCI.
-
config ISDN_DIVAS_PRIPCI
bool "DIVA Server PRI/PCI support"
depends on ISDN_DIVAS
@@ -43,17 +37,17 @@ config ISDN_DIVAS_DIVACAPI
You need this to provide the CAPI interface
for DIVA Server cards.
-config ISDN_DIVAS_MAINT
- tristate "DIVA Maint driver support"
- depends on ISDN_DIVAS
- help
- Enable Divas Maintainance driver.
-
config ISDN_DIVAS_USERIDI
tristate "DIVA User-IDI interface support"
depends on ISDN_DIVAS
help
Enable support for user-mode IDI interface.
+config ISDN_DIVAS_MAINT
+ tristate "DIVA Maint driver support"
+ depends on ISDN_DIVAS && m
+ help
+ Enable Divas Maintainance driver.
+
endmenu
diff --git a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile
index ce1f5cf4b5a1..4fa7fdb7df0d 100644
--- a/drivers/isdn/hardware/eicon/Makefile
+++ b/drivers/isdn/hardware/eicon/Makefile
@@ -10,9 +10,8 @@ obj-$(CONFIG_ISDN_DIVAS_DIVACAPI) += divacapi.o
# Multipart objects.
divas-y := divasmain.o divasfunc.o di.o io.o istream.o \
- diva.o dlist.o divasproc.o diva_dma.o
-divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o
-divas-$(CONFIG_ISDN_DIVAS_4BRIPCI) += os_4bri.o s_4bri.o
+ diva.o divasproc.o diva_dma.o
+divas-$(CONFIG_ISDN_DIVAS_BRIPCI) += os_bri.o s_bri.o os_4bri.o s_4bri.o
divas-$(CONFIG_ISDN_DIVAS_PRIPCI) += os_pri.o s_pri.o
divacapi-y := capimain.o capifunc.o message.o capidtmf.o
@@ -21,4 +20,4 @@ divadidd-y := diva_didd.o diddfunc.o dadapter.o
diva_mnt-y := divamnt.o mntfunc.o debug.o maintidi.o
-diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
+diva_idi-y := divasi.o idifunc.o um_idi.o dqueue.o
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index 216c644c9350..e56e81c67e53 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -1,10 +1,10 @@
-/* $Id: capifunc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: capifunc.c,v 1.47 2003/09/09 06:52:29 schindler Exp $
*
* ISDN interface module for Eicon active cards DIVA.
* CAPI Interface common functions
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -25,10 +25,11 @@
DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
APPL *application = (APPL *) NULL;
byte max_appl = MAX_APPL;
+byte max_adapter = 0;
static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;
byte UnMapController(byte);
-char DRIVERRELEASE[32];
+char DRIVERRELEASE_CAPI[32];
extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);
extern void callback(ENTITY *);
@@ -45,7 +46,6 @@ static dword notify_handle;
static void DIRequest(ENTITY * e);
static DESCRIPTOR MAdapter;
static DESCRIPTOR DAdapter;
-byte max_adapter = 0;
static byte ControllerMap[MAX_DESCRIPTORS + 1];
@@ -59,16 +59,14 @@ extern void diva_os_set_controller_struct(struct capi_ctr *);
extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
-static void no_printf(unsigned char *, ...);
-
-DIVA_DI_PRINTF dprintf = no_printf;
-
/*
* debug
*/
+static void no_printf(unsigned char *, ...);
#include "debuglib.c"
void xlog(char *x, ...)
{
+#ifndef DIVA_NO_DEBUGLIB
va_list ap;
if (myDriverDebugHandle.dbgMask & DL_XLOG) {
va_start(ap, x);
@@ -81,6 +79,7 @@ void xlog(char *x, ...)
}
va_end(ap);
}
+#endif
}
/*
@@ -162,13 +161,14 @@ static int find_free_id(void)
p = cards;
while (p) {
if (p->Id == num)
- goto next_id;
+ break;
p = p->next;
}
+ if(!p) {
diva_os_leave_spin_lock(&ll_lock, &old_irql,
"find free id");
return (num);
- next_id:
+ }
}
diva_os_leave_spin_lock(&ll_lock, &old_irql, "find free id");
return (999);
@@ -315,10 +315,11 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
/* if DATA_B3_IND, copy data too */
if (command == _DATA_B3_I) {
- dword data = READ_DWORD(((byte *) & msg.info.data_b3_ind.Data));
+ dword data = READ_DWORD(&msg.info.data_b3_ind.Data);
memcpy(write + length, (void *) data, dlength);
}
+#ifndef DIVA_NO_DEBUGLIB
if (myDriverDebugHandle.dbgMask & DL_XLOG) {
switch (command) {
default:
@@ -332,8 +333,8 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
if (myDriverDebugHandle.dbgMask & DL_BLK) {
xlog("\x00\x02", &msg, 0x81, length);
for (i = 0; i < dlength; i += 256) {
- DBG_BLK((((char *) msg.info.data_b3_ind.
- Data) + i, ((dlength - i) < 256) ? (dlength - i) : 256))
+ DBG_BLK((((char *) READ_DWORD(&msg.info.data_b3_ind.Data)) + i,
+ ((dlength - i) < 256) ? (dlength - i) : 256))
if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
break; /* not more if not explicitely requested */
}
@@ -341,6 +342,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
break;
}
}
+#endif
/* find the card structure for this controller */
if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
@@ -719,7 +721,7 @@ static int diva_add_card(DESCRIPTOR * d)
}
/* profile information */
- ctrl->profile.nbchannel = card->d.channels;
+ WRITE_WORD(&ctrl->profile.nbchannel, card->d.channels);
ctrl->profile.goptions = a->profile.Global_Options;
ctrl->profile.support1 = a->profile.B1_Protocols;
ctrl->profile.support2 = a->profile.B2_Protocols;
@@ -745,17 +747,20 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
{
APPL *this;
word bnum, xnum;
- int i = 0, j = 0;
+ int i = 0;
+ unsigned char *p;
void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;
void **xbuffer_ptr, **xbuffer_internal;
diva_os_spin_lock_magic_t old_irql;
+ unsigned int mem_len;
+
if (diva_os_in_irq()) {
DBG_ERR(("CAPI_REGISTER - in irq context !"))
return;
}
- DBG_TRC(("application register"))
+ DBG_TRC(("application register Id=%d", appl))
if (appl > MAX_APPL) {
DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
@@ -775,97 +780,47 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
return; /* appl already registered */
}
- if (!try_module_get(ctrl->owner)) {
- printk(KERN_WARNING "%s: cannot reserve module\n", __FUNCTION__);
- return;
- }
-
/* alloc memory */
bnum = rp->level3cnt * rp->datablkcnt;
xnum = rp->level3cnt * MAX_DATA_B3;
- if (!(DataNCCI = diva_os_malloc(0, bnum * sizeof(word)))) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- module_put(ctrl->owner);
- return;
- }
- memset(DataNCCI, 0, bnum * sizeof(word));
-
- if (!(DataFlags = diva_os_malloc(0, bnum * sizeof(word)))) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- diva_os_free(0, DataNCCI);
- module_put(ctrl->owner);
- return;
- }
- memset(DataFlags, 0, bnum * sizeof(word));
-
- if (!(ReceiveBuffer = diva_os_malloc(0, bnum * rp->datablklen))) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- diva_os_free(0, DataNCCI);
- diva_os_free(0, DataFlags);
- module_put(ctrl->owner);
- return;
- }
- memset(ReceiveBuffer, 0, bnum * rp->datablklen);
+ mem_len = bnum * sizeof(word); /* DataNCCI */
+ mem_len += bnum * sizeof(word); /* DataFlags */
+ mem_len += bnum * rp->datablklen; /* ReceiveBuffer */
+ mem_len += xnum; /* xbuffer_used */
+ mem_len += xnum * sizeof(void *); /* xbuffer_ptr */
+ mem_len += xnum * sizeof(void *); /* xbuffer_internal */
+ mem_len += xnum * rp->datablklen; /* xbuffer_ptr[xnum] */
- if (!(xbuffer_used = (byte *) diva_os_malloc(0, xnum))) {
+ if (!(p = diva_os_malloc(0, mem_len))) {
DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- diva_os_free(0, DataNCCI);
- diva_os_free(0, DataFlags);
- diva_os_free(0, ReceiveBuffer);
- module_put(ctrl->owner);
return;
}
- memset(xbuffer_used, 0, xnum);
-
- if (!(xbuffer_ptr = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- diva_os_free(0, DataNCCI);
- diva_os_free(0, DataFlags);
- diva_os_free(0, ReceiveBuffer);
- diva_os_free(0, xbuffer_used);
- module_put(ctrl->owner);
- return;
- }
- memset(xbuffer_ptr, 0, xnum * sizeof(void *));
-
- if (!(xbuffer_internal = (void **) diva_os_malloc(0, xnum * sizeof(void *)))) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- diva_os_free(0, DataNCCI);
- diva_os_free(0, DataFlags);
- diva_os_free(0, ReceiveBuffer);
- diva_os_free(0, xbuffer_used);
- diva_os_free(0, xbuffer_ptr);
- module_put(ctrl->owner);
- return;
- }
- memset(xbuffer_internal, 0, xnum * sizeof(void *));
-
+ memset(p, 0, mem_len);
+
+ DataNCCI = (void *)p;
+ p += bnum * sizeof(word);
+ DataFlags = (void *)p;
+ p += bnum * sizeof(word);
+ ReceiveBuffer = (void *)p;
+ p += bnum * rp->datablklen;
+ xbuffer_used = (void *)p;
+ p += xnum;
+ xbuffer_ptr = (void **)p;
+ p += xnum * sizeof(void *);
+ xbuffer_internal = (void **)p;
+ p += xnum * sizeof(void *);
for (i = 0; i < xnum; i++) {
- xbuffer_ptr[i] = diva_os_malloc(0, rp->datablklen);
- if (!xbuffer_ptr[i]) {
- DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
- if (i) {
- for (j = 0; j < i; j++)
- if (xbuffer_ptr[j])
- diva_os_free(0, xbuffer_ptr [j]);
- }
- diva_os_free(0, DataNCCI);
- diva_os_free(0, DataFlags);
- diva_os_free(0, ReceiveBuffer);
- diva_os_free(0, xbuffer_used);
- diva_os_free(0, xbuffer_ptr);
- diva_os_free(0, xbuffer_internal);
- module_put(ctrl->owner);
- return;
- }
+ xbuffer_ptr[i] = (void *)p;
+ p += rp->datablklen;
}
DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
DBG_LOG((" MaxLogicalConnections = %d", rp->level3cnt))
DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt))
DBG_LOG((" MaxBDataLength = %d", rp->datablklen))
+ DBG_LOG((" Allocated Memory = %d", mem_len))
/* initialize application data */
diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");
@@ -875,9 +830,6 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
this->Id = appl;
- /* We do not need a list */
- /* InitializeListHead(&this->s_function); */
-
for (i = 0; i < max_adapter; i++) {
adapter[i].CIP_Mask[appl - 1] = 0;
}
@@ -911,41 +863,24 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
diva_os_spin_lock_magic_t old_irql;
APPL *this = &application[appl - 1];
- int i = 0;
+
+ DBG_TRC(("application %d(%d) cleanup", this->Id, appl))
if (diva_os_in_irq()) {
DBG_ERR(("CAPI_RELEASE - in irq context !"))
return;
}
- if (this->Id) {
- DBG_TRC(("application %d cleanup", this->Id))
- }
diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
if (this->Id) {
CapiRelease(this->Id);
if (this->DataNCCI)
diva_os_free(0, this->DataNCCI);
- if (this->DataFlags)
- diva_os_free(0, this->DataFlags);
- if (this->ReceiveBuffer)
- diva_os_free(0, this->ReceiveBuffer);
- if (this->xbuffer_ptr) {
- for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI); i++) {
- if (this->xbuffer_ptr[i])
- diva_os_free(0, this->xbuffer_ptr[i]);
- }
- diva_os_free(0, this->xbuffer_ptr);
- }
- if (this->xbuffer_internal)
- diva_os_free(0, this->xbuffer_internal);
- if (this->xbuffer_used)
- diva_os_free(0, this->xbuffer_used);
+ this->DataNCCI = NULL;
this->Id = 0;
}
diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");
- module_put(ctrl->owner);
}
/*
@@ -954,7 +889,7 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
static u16 diva_send_message(struct capi_ctr *ctrl,
diva_os_message_buffer_s * dmb)
{
- int i = 0, j = 0;
+ int i = 0;
word ret = 0;
diva_os_spin_lock_magic_t old_irql;
CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb);
@@ -971,6 +906,10 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
}
DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))
+ if (!this->Id) {
+ return CAPI_ILLAPPNR;
+ }
+
/* patch controller number */
msg->header.controller = ControllerMap[card->Id]
| (msg->header.controller & 0x80); /* preserve external controller bit */
@@ -983,13 +922,17 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
break;
case _DATA_B3_I | RESPONSE:
+#ifndef DIVA_NO_DEBUGLIB
if (myDriverDebugHandle.dbgMask & DL_BLK)
xlog("\x00\x02", msg, 0x80, clength);
+#endif
break;
case _DATA_B3_R:
+#ifndef DIVA_NO_DEBUGLIB
if (myDriverDebugHandle.dbgMask & DL_BLK)
xlog("\x00\x02", msg, 0x80, clength);
+#endif
if (clength == 24)
clength = 22; /* workaround for PPcom bug */
@@ -1016,8 +959,10 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength],
READ_WORD(&msg->info.data_b3_req.Data_Length));
+#ifndef DIVA_NO_DEBUGLIB
if ((myDriverDebugHandle.dbgMask & DL_BLK)
&& (myDriverDebugHandle.dbgMask & DL_XLOG)) {
+ int j;
for (j = 0; j <
READ_WORD(&msg->info.data_b3_req.Data_Length);
j += 256) {
@@ -1028,6 +973,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
break; /* not more if not explicitely requested */
}
}
+#endif
break;
}
@@ -1091,7 +1037,7 @@ static void didd_callback(void *context, DESCRIPTOR * adapter, int removal)
} else {
memcpy(&MAdapter, adapter, sizeof(MAdapter));
dprintf = (DIVA_DI_PRINTF) MAdapter.request;
- DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
}
} else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
if (removal) {
@@ -1119,7 +1065,7 @@ static int divacapi_connect_didd(void)
if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
dprintf = (DIVA_DI_PRINTF) MAdapter.request;
- DbgRegister("CAPI20", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
break;
}
}
@@ -1130,7 +1076,7 @@ static int divacapi_connect_didd(void)
req.didd_notify.e.Req = 0;
req.didd_notify.e.Rc =
IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
+ req.didd_notify.info.callback = (void *)didd_callback;
req.didd_notify.info.context = 0;
DAdapter.request((ENTITY *) & req);
if (req.didd_notify.e.Rc != 0xff) {
@@ -1260,4 +1206,7 @@ void DIVA_EXIT_FUNCTION finit_capifunc(void)
divacapi_remove_cards();
remove_main_structs();
+
+ diva_os_destroy_spin_lock(&api_lock, "capifunc");
+ diva_os_destroy_spin_lock(&ll_lock, "capifunc");
}
diff --git a/drivers/isdn/hardware/eicon/capifunc.h b/drivers/isdn/hardware/eicon/capifunc.h
index 4468b436c70d..133485841bee 100644
--- a/drivers/isdn/hardware/eicon/capifunc.h
+++ b/drivers/isdn/hardware/eicon/capifunc.h
@@ -1,10 +1,10 @@
-/* $Id: capifunc.h,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: capifunc.h,v 1.10 2003/08/25 10:06:37 schindler Exp $
*
* ISDN interface module for Eicon active cards DIVA.
* CAPI Interface common functions
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -21,7 +21,7 @@
#define M_COMPANY "Eicon Networks"
-extern char DRIVERRELEASE[];
+extern char DRIVERRELEASE_CAPI[];
typedef struct _diva_card {
int Id;
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 743fd398dc5a..4a1702523632 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -1,10 +1,10 @@
-/* $Id: capimain.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: capimain.c,v 1.24 2003/09/09 06:51:05 schindler Exp $
*
* ISDN interface module for Eicon active cards DIVA.
* CAPI Interface
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -15,10 +15,7 @@
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/smp_lock.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
#include <linux/skbuff.h>
-#include <linux/delay.h>
#include "os_capi.h"
@@ -29,7 +26,7 @@
#include "cp_vers.h"
#include "capifunc.h"
-static char *main_revision = "$Revision: 1.1.2.11 $";
+static char *main_revision = "$Revision: 1.24 $";
static char *DRIVERNAME =
"Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
static char *DRIVERLNAME = "divacapi";
@@ -57,47 +54,6 @@ static char *getrev(const char *revision)
}
/*
- * sleep for some milliseconds
- */
-void diva_os_sleep(dword mSec)
-{
- unsigned long timeout = HZ * mSec / 1000 + 1;
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(timeout);
-}
-
-/*
- * wait for some milliseconds
- */
-void diva_os_wait(dword mSec)
-{
- mdelay(mSec);
-}
-
-/*
- * alloc memory
- */
-void *diva_os_malloc(unsigned long flags, unsigned long size)
-{
- void *ret = NULL;
- if (size) {
- ret = (void *) vmalloc((unsigned int) size);
- }
- return (ret);
-}
-
-/*
- * free memory
- */
-void diva_os_free(unsigned long unused, void *ptr)
-{
- if (ptr) {
- vfree(ptr);
- }
-}
-
-/*
* alloc a message buffer
*/
diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size,
@@ -160,11 +116,11 @@ static int DIVA_INIT_FUNCTION divacapi_init(void)
char tmprev[32];
int ret = 0;
- sprintf(DRIVERRELEASE, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
+ sprintf(DRIVERRELEASE_CAPI, "%d.%d%s", DRRELMAJOR, DRRELMINOR,
DRRELEXTRA);
printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
+ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_CAPI);
strcpy(tmprev, main_revision);
printk("%s Build: %s(%s)\n", getrev(tmprev),
diva_capi_common_code_build, DIVA_BUILD);
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
index 19b353eb4ef7..dcfae9e9ad7b 100644
--- a/drivers/isdn/hardware/eicon/dadapter.c
+++ b/drivers/isdn/hardware/eicon/dadapter.c
@@ -49,8 +49,21 @@ dword Adapters = 0; /* Number of adapters */
Shadow IDI_DIMAINT
and 'shadow' debug stuff
-------------------------------------------------------------------------- */
-static void no_printf (unsigned char * format, ...) { }
-DIVA_DI_PRINTF dprintf = no_printf;
+static void no_printf (unsigned char * format, ...)
+{
+#ifdef EBUG
+ va_list ap;
+ va_start (ap, format);
+ debug((format, ap));
+ va_end (ap);
+#endif
+}
+
+/* -------------------------------------------------------------------------
+ Portable debug Library
+ ------------------------------------------------------------------------- */
+#include "debuglib.c"
+
static DESCRIPTOR MAdapter = {IDI_DIMAINT, /* Adapter Type */
0x00, /* Channels */
0x0000, /* Features */
@@ -86,6 +99,7 @@ void diva_didd_load_time_init (void) {
Should be called as last step, if driver does unload
-------------------------------------------------------------------------- */
void diva_didd_load_time_finit (void) {
+ diva_os_destroy_spin_lock (&didd_spin, "didd");
}
/* --------------------------------------------------------------------------
Called in order to register new adapter in adapter array
@@ -349,7 +363,4 @@ void IDI_CALL_LINK_T DIVA_DIDD_Read (void IDI_CALL_ENTITY_T * buffer,
int length) {
diva_didd_read_adapter_array (buffer, length);
}
-/* -------------------------------------------------------------------------
- Portable debug Library
- ------------------------------------------------------------------------- */
-#include "debuglib.c"
+
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 0eac01779d59..907364c9cb9b 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -2,7 +2,6 @@
#include "pc.h"
#include "di_defs.h"
#include "debug_if.h"
-#include "linux/kernel.h"
#include "divasync.h"
#include "kst_ifc.h"
#include "maintidi.h"
@@ -96,9 +95,9 @@ static void queueInit (MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {
static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {
/* Allocate 'size' bytes at tail of queue which will be filled later
- * directly whith callers own message header info and/or message.
+ * directly with callers own message header info and/or message.
* An 'alloced' message is marked incomplete by oring the 'Size' field
- * whith MSG_INCOMPLETE.
+ * with MSG_INCOMPLETE.
* This must be reset via queueCompleteMsg() after the message is filled.
* As long as a message is marked incomplete queuePeekMsg() will return
* a 'queue empty' condition when it reaches such a message. */
@@ -160,7 +159,7 @@ static void queueFreeMsg (MSG_QUEUE *Q) {
}
static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {
- /* Show the first valid message in queue BUT DONT free the message.
+ /* Show the first valid message in queue BUT DON'T free the message.
* After looking on the message contents it can be freed queueFreeMsg()
* or simply remain in message queue. */
@@ -195,7 +194,7 @@ static dword start_usec;
length: length of the message queue
do_init: perfor queue reset
- return: zero on sucess, -1 on error
+ return: zero on success, -1 on error
*/
int diva_maint_init (byte* base, unsigned long length, int do_init) {
if (dbg_queue || (!base) || (length < (4096*4))) {
@@ -296,7 +295,7 @@ dword diva_dbg_q_length (void) {
/*
INTERFACE:
- Lock messafe queue and return the pointer to the first
+ Lock message queue and return the pointer to the first
entry.
*/
diva_dbg_entry_head_t* diva_maint_get_message (word* size,
@@ -725,12 +724,12 @@ int diva_get_driver_info (dword id, byte* data, int data_length) {
if (clients[id].hDbg) {
*p++ = 1;
- *p++ = (byte)clients[id].sec; /* save secounds */
+ *p++ = (byte)clients[id].sec; /* save seconds */
*p++ = (byte)(clients[id].sec >> 8);
*p++ = (byte)(clients[id].sec >> 16);
*p++ = (byte)(clients[id].sec >> 24);
- *p++ = (byte)(clients[id].usec/1000); /* save msecounds */
+ *p++ = (byte)(clients[id].usec/1000); /* save mseconds */
*p++ = (byte)((clients[id].usec/1000) >> 8);
*p++ = (byte)((clients[id].usec/1000) >> 16);
*p++ = (byte)((clients[id].usec/1000) >> 24);
@@ -1079,7 +1078,7 @@ void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) {
}
/* ----------------------------------------------------------------
- Low level interface for management interace client
+ Low level interface for management interface client
---------------------------------------------------------------- */
/*
Return handle to client structure
@@ -1462,7 +1461,7 @@ static void diva_maint_state_change_notify (void* user_context,
case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
/*
- Incoming Statistices
+ Incoming Statistics
*/
if (channel->pInterfaceStat->inc.Calls) {
diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
@@ -1498,7 +1497,7 @@ static void diva_maint_state_change_notify (void* user_context,
}
/*
- Outgoing Statistices
+ Outgoing Statistics
*/
if (channel->pInterfaceStat->outg.Calls) {
diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
diff --git a/drivers/isdn/hardware/eicon/debuglib.c b/drivers/isdn/hardware/eicon/debuglib.c
index 0690f539ece2..a19b7ffe9ace 100644
--- a/drivers/isdn/hardware/eicon/debuglib.c
+++ b/drivers/isdn/hardware/eicon/debuglib.c
@@ -23,8 +23,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
+
#include "debuglib.h"
+
+#ifdef DIVA_NO_DEBUGLIB
+static DIVA_DI_PRINTF dprintf;
+#else /* DIVA_NO_DEBUGLIB */
+
_DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION };
+DIVA_DI_PRINTF dprintf = no_printf;
/*****************************************************************************/
#define DBG_FUNC(name) \
void \
@@ -146,3 +153,4 @@ void xdi_dbg_xlog (char* x, ...) {
va_end(ap);
}
/*****************************************************************************/
+#endif /* DIVA_NO_DEBUGLIB */
diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h
index bf77b55b2420..e1dfce06483d 100644
--- a/drivers/isdn/hardware/eicon/debuglib.h
+++ b/drivers/isdn/hardware/eicon/debuglib.h
@@ -101,6 +101,34 @@
* with _KERNEL_DBG_PRINT_
*/
#define DL_TO_KERNEL 0x40000000
+
+#ifdef DIVA_NO_DEBUGLIB
+#define myDbgPrint_LOG(x,...) do { } while(0);
+#define myDbgPrint_FTL(x,...) do { } while(0);
+#define myDbgPrint_ERR(x,...) do { } while(0);
+#define myDbgPrint_TRC(x,...) do { } while(0);
+#define myDbgPrint_MXLOG(x,...) do { } while(0);
+#define myDbgPrint_EVL(x,...) do { } while(0);
+#define myDbgPrint_REG(x,...) do { } while(0);
+#define myDbgPrint_MEM(x,...) do { } while(0);
+#define myDbgPrint_SPL(x,...) do { } while(0);
+#define myDbgPrint_IRP(x,...) do { } while(0);
+#define myDbgPrint_TIM(x,...) do { } while(0);
+#define myDbgPrint_BLK(x,...) do { } while(0);
+#define myDbgPrint_TAPI(x,...) do { } while(0);
+#define myDbgPrint_NDIS(x,...) do { } while(0);
+#define myDbgPrint_CONN(x,...) do { } while(0);
+#define myDbgPrint_STAT(x,...) do { } while(0);
+#define myDbgPrint_SEND(x,...) do { } while(0);
+#define myDbgPrint_RECV(x,...) do { } while(0);
+#define myDbgPrint_PRV0(x,...) do { } while(0);
+#define myDbgPrint_PRV1(x,...) do { } while(0);
+#define myDbgPrint_PRV2(x,...) do { } while(0);
+#define myDbgPrint_PRV3(x,...) do { } while(0);
+#define DBG_TEST(func,args) do { } while(0);
+#define DBG_EVL_ID(args) do { } while(0);
+
+#else /* DIVA_NO_DEBUGLIB */
/*
* define low level macros for formatted & raw debugging
*/
@@ -156,6 +184,9 @@ DBG_DECL(PRV3)
{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL ) \
{ myDbgPrint_EVL args ; \
} }
+
+#endif /* DIVA_NO_DEBUGLIB */
+
#define DBG_LOG(args) DBG_TEST(LOG, args)
#define DBG_FTL(args) DBG_TEST(FTL, args)
#define DBG_ERR(args) DBG_TEST(ERR, args)
@@ -182,9 +213,16 @@ DBG_DECL(PRV3)
/*
* prototypes for debug register/deregister functions in "debuglib.c"
*/
+#ifdef DIVA_NO_DEBUGLIB
+#define DbgRegister(name,tag, mask) do { } while(0)
+#define DbgDeregister() do { } while(0)
+#define DbgSetLevel(mask) do { } while(0)
+#else
+extern DIVA_DI_PRINTF dprintf;
extern int DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) ;
extern void DbgDeregister (void) ;
extern void DbgSetLevel (unsigned long dbgMask) ;
+#endif
/*
* driver internal structure for debug handling;
* in client drivers this structure is maintained in "debuglib.c",
@@ -274,9 +312,11 @@ typedef struct
} CardTrace;
} u1;
} _DbgExtendedInfo_;
+#ifndef DIVA_NO_DEBUGLIB
/* -------------------------------------------------------------
Function used for xlog-style debug
------------------------------------------------------------- */
#define XDI_USE_XLOG 1
void xdi_dbg_xlog (char* x, ...);
+#endif /* DIVA_NO_DEBUGLIB */
#endif /* __DEBUGLIB_H__ */
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index 9ce6aa956d7f..8e1791d3b194 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -112,16 +112,14 @@ void pr_out(ADAPTER * a)
#ifdef USE_EXTENDED_DEBUGS
if ( !this )
{
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
- xdi_xlog_sec++, (int)io->ANum))
+ xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
e_no = look_req(a) ;
ReadyCount-- ;
continue ;
}
{
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DBG_TRC((">A%d Id=0x%x Req=0x%x", io->ANum, this->Id, this->Req))
+ DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
}
#else
dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
@@ -563,8 +561,7 @@ byte isdn_rc(ADAPTER * a,
int cancel_rc;
#ifdef USE_EXTENDED_DEBUGS
{
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DBG_TRC(("<A%d Id=0x%x Rc=0x%x", io->ANum, Id, Rc))
+ DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
}
#else
dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
@@ -767,8 +764,7 @@ byte isdn_ind(ADAPTER * a,
byte* cma = 0;
#ifdef USE_EXTENDED_DEBUGS
{
- ISDN_ADAPTER *io = (ISDN_ADAPTER *)a->io ;
- DBG_TRC(("<A%d Id=0x%x Ind=0x%x", io->ANum, Id, Ind))
+ DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
}
#else
dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
@@ -956,10 +952,10 @@ static void xdi_xlog_rc_event (byte Adapter,
byte Id, byte Ch, byte Rc, byte cb, byte type) {
#if defined(XDI_USE_XLOG)
word LogInfo[4];
- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
- LogInfo[1] = (word)Id | (word)(Ch << 8);
- LogInfo[2] = (word)Rc | (word)(type << 8);
- LogInfo[3] = cb;
+ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+ WRITE_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
+ WRITE_WORD(&LogInfo[3], cb);
xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
#endif
}
@@ -980,9 +976,9 @@ static void xdi_xlog_request (byte Adapter, byte Id,
byte Ch, byte Req, byte type) {
#if defined(XDI_USE_XLOG)
word LogInfo[3];
- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
- LogInfo[1] = (word)Id | (word)(Ch << 8);
- LogInfo[2] = (word)Req | (word)(type << 8);
+ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+ WRITE_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
#endif
}
@@ -1024,10 +1020,10 @@ static void xdi_xlog_ind (byte Adapter,
byte type) {
#if defined(XDI_USE_XLOG)
word LogInfo[4];
- LogInfo[0] = (word)Adapter | (word)(xdi_xlog_sec++ << 8);
- LogInfo[1] = (word)Id | (word)(Ch << 8);
- LogInfo[2] = (word)Ind | (word)(type << 8);
- LogInfo[3] = (word)rnr | (word)(rnr_valid << 8);
+ WRITE_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+ WRITE_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+ WRITE_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
+ WRITE_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
#endif
}
diff --git a/drivers/isdn/hardware/eicon/diddfunc.c b/drivers/isdn/hardware/eicon/diddfunc.c
index 94e4001c4b35..69abacc7c85b 100644
--- a/drivers/isdn/hardware/eicon/diddfunc.c
+++ b/drivers/isdn/hardware/eicon/diddfunc.c
@@ -1,11 +1,11 @@
-/* $Id: diddfunc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: diddfunc.c,v 1.14 2003/08/25 10:06:37 schindler Exp $
*
* DIDD Interface module for Eicon active cards.
*
* Functions are in dadapter.c
*
- * Copyright 2002 by Armin Schindler (mac@melware.de)
- * Copyright 2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -23,7 +23,7 @@
extern void DIVA_DIDD_Read(void *, int);
-extern char *DRIVERRELEASE;
+extern char *DRIVERRELEASE_DIDD;
static dword notify_handle;
static DESCRIPTOR _DAdapter;
@@ -40,7 +40,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter,
if (removal) {
DbgDeregister();
} else {
- DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
}
}
return (NULL);
@@ -65,14 +65,14 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
req.didd_notify.e.Req = 0;
req.didd_notify.e.Rc =
IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
+ req.didd_notify.info.callback = (void *)didd_callback;
req.didd_notify.info.context = 0;
_DAdapter.request((ENTITY *) & req);
if (req.didd_notify.e.Rc != 0xff)
return (0);
notify_handle = req.didd_notify.info.handle;
} else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
- DbgRegister("DIDD", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("DIDD", DRIVERRELEASE_DIDD, DBG_DEFAULT);
}
}
return (dadapter);
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
index c96f0a3b5530..6c5b1bd81a3a 100644
--- a/drivers/isdn/hardware/eicon/diva.c
+++ b/drivers/isdn/hardware/eicon/diva.c
@@ -1,4 +1,4 @@
-/* $Id: diva.c,v 1.1.2.5 2001/02/14 21:10:19 armin Exp $ */
+/* $Id: diva.c,v 1.17 2003/09/09 06:52:01 schindler Exp $ */
#define CARDTYPE_H_WANT_DATA 1
#define CARDTYPE_H_WANT_IDI_DATA 0
@@ -7,7 +7,6 @@
#include "platform.h"
#include "debuglib.h"
-#include "diva_pci.h"
#include "cardtype.h"
#include "dlist.h"
#include "pc.h"
@@ -15,19 +14,17 @@
#include "di.h"
#include "io.h"
#include "pc_maint.h"
-
#include "xdi_msg.h"
#include "xdi_adapter.h"
+#include "diva_pci.h"
#include "diva.h"
#ifdef CONFIG_ISDN_DIVAS_PRIPCI
#include "os_pri.h"
#endif
-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
-#include "os_4bri.h"
-#endif
#ifdef CONFIG_ISDN_DIVAS_BRIPCI
#include "os_bri.h"
+#include "os_4bri.h"
#endif
PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
@@ -78,6 +75,11 @@ DivaIdiReqFunc(31)
struct pt_regs;
/*
+ * include queue functions
+ */
+#include "dlist.c"
+
+/*
** LOCALS
*/
diva_entity_queue_t adapter_queue;
@@ -109,7 +111,7 @@ static diva_supported_cards_info_t divas_supported_cards[] = {
*/
{CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
#endif
-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
+#ifdef CONFIG_ISDN_DIVAS_BRIPCI
/*
4BRI Rev 1 Cards
*/
@@ -126,8 +128,6 @@ static diva_supported_cards_info_t divas_supported_cards[] = {
{CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
{CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
{CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
-#endif
-#ifdef CONFIG_ISDN_DIVAS_BRIPCI
/*
BRI
*/
@@ -193,6 +193,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
pdiva->controller = i + 1;
pdiva->xdi_adapter.ANum = pdiva->controller;
IoAdapters[i] = &pdiva->xdi_adapter;
+ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
create_adapter_proc(pdiva); /* add adapter to proc file system */
DBG_LOG(("add %s:%d",
@@ -200,6 +201,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
[CardOrdinal].Name,
pdiva->controller))
+ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
pa = pdiva;
for (j = 1; j < nr; j++) { /* slave adapters, if any */
pa = (diva_os_xdi_adapter_t *) diva_q_get_next(&pa->link);
@@ -207,8 +209,11 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
pa->controller = i + 1 + j;
pa->xdi_adapter.ANum = pa->controller;
IoAdapters[i + j] = &pa->xdi_adapter;
+ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
DBG_LOG(("add slave adapter (%d)",
- pa->controller)) create_adapter_proc(pa); /* add adapter to proc file system */
+ pa->controller))
+ create_adapter_proc(pa); /* add adapter to proc file system */
+ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
} else {
DBG_ERR(("slave adapter problem"))
break;
@@ -463,7 +468,8 @@ diva_xdi_write(void *adapter, void *os_handle, const void *src,
}
} else {
DBG_ERR(("A: A(%d) write error (%d)", a->controller,
- length))}
+ length))
+ }
diva_os_free(0, data);
@@ -564,7 +570,6 @@ static void diva_init_request_array(void)
Requests[31] = DivaIdiRequest31;
}
-/* card: 1-based card number */
void diva_xdi_display_adapter_features(int card)
{
dword features;
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 16e629d69e80..0afd015e0468 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -1,11 +1,11 @@
-/* $Id: diva_didd.c,v 1.1.2.6 2001/05/01 15:48:05 armin Exp $
+/* $Id: diva_didd.c,v 1.13 2003/08/27 10:11:21 schindler Exp $
*
* DIDD Interface module for Eicon active cards.
*
* Functions are in dadapter.c
*
- * Copyright 2002 by Armin Schindler (mac@melware.de)
- * Copyright 2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -23,14 +23,13 @@
#include "divasync.h"
#include "did_vers.h"
-static char *main_revision = "$Revision: 1.1.2.6 $";
+static char *main_revision = "$Revision: 1.13 $";
static char *DRIVERNAME =
"Eicon DIVA - DIDD table (http://www.melware.net)";
static char *DRIVERLNAME = "divadidd";
-char *DRIVERRELEASE = "2.0";
+char *DRIVERRELEASE_DIDD = "2.0";
-static char *dir_in_proc_net = "isdn";
static char *main_proc_dir = "eicon";
MODULE_DESCRIPTION("DIDD table driver for diva drivers");
@@ -48,12 +47,11 @@ extern void diddfunc_finit(void);
extern void DIVA_DIDD_Read(void *, int);
-static struct proc_dir_entry *proc_net_isdn;
static struct proc_dir_entry *proc_didd;
-struct proc_dir_entry *proc_net_isdn_eicon = NULL;
+struct proc_dir_entry *proc_net_eicon = NULL;
EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
-EXPORT_SYMBOL_NOVERS(proc_net_isdn_eicon);
+EXPORT_SYMBOL_NOVERS(proc_net_eicon);
static char *getrev(const char *revision)
{
@@ -78,7 +76,7 @@ proc_read(char *page, char **start, off_t off, int count, int *eof,
strcpy(tmprev, main_revision);
len += sprintf(page + len, "%s\n", DRIVERNAME);
len += sprintf(page + len, "name : %s\n", DRIVERLNAME);
- len += sprintf(page + len, "release : %s\n", DRIVERRELEASE);
+ len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_DIDD);
len += sprintf(page + len, "build : %s(%s)\n",
diva_didd_common_code_build, DIVA_BUILD);
len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
@@ -93,26 +91,12 @@ proc_read(char *page, char **start, off_t off, int count, int *eof,
static int DIVA_INIT_FUNCTION create_proc(void)
{
- struct proc_dir_entry *pe;
+ proc_net_eicon = create_proc_entry(main_proc_dir, S_IFDIR, proc_net);
- for (pe = proc_net->subdir; pe; pe = pe->next) {
- if (!memcmp(dir_in_proc_net, pe->name, pe->namelen)) {
- proc_net_isdn = pe;
- break;
- }
- }
- if (!proc_net_isdn) {
- proc_net_isdn =
- create_proc_entry(dir_in_proc_net, S_IFDIR, proc_net);
- }
- proc_net_isdn_eicon =
- create_proc_entry(main_proc_dir, S_IFDIR, proc_net_isdn);
-
- if (proc_net_isdn_eicon) {
- if (
- (proc_didd =
+ if (proc_net_eicon) {
+ if ((proc_didd =
create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO,
- proc_net_isdn_eicon))) {
+ proc_net_eicon))) {
proc_didd->read_proc = proc_read;
}
return (1);
@@ -120,14 +104,10 @@ static int DIVA_INIT_FUNCTION create_proc(void)
return (0);
}
-static void remove_proc(void)
+static void DIVA_EXIT_FUNCTION remove_proc(void)
{
- remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
- remove_proc_entry(main_proc_dir, proc_net_isdn);
-
- if ((proc_net_isdn) && (!proc_net_isdn->subdir)) {
- remove_proc_entry(dir_in_proc_net, proc_net);
- }
+ remove_proc_entry(DRIVERLNAME, proc_net_eicon);
+ remove_proc_entry(main_proc_dir, proc_net);
}
static int DIVA_INIT_FUNCTION divadidd_init(void)
@@ -136,7 +116,7 @@ static int DIVA_INIT_FUNCTION divadidd_init(void)
int ret = 0;
printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
+ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIDD);
strcpy(tmprev, main_revision);
printk("%s Build:%s(%s)\n", getrev(tmprev),
diva_didd_common_code_build, DIVA_BUILD);
@@ -151,7 +131,9 @@ static int DIVA_INIT_FUNCTION divadidd_init(void)
if (!diddfunc_init()) {
printk(KERN_ERR "%s: failed to connect to DIDD.\n",
DRIVERLNAME);
+#ifdef MODULE
remove_proc();
+#endif
ret = -EIO;
goto out;
}
diff --git a/drivers/isdn/hardware/eicon/diva_pci.h b/drivers/isdn/hardware/eicon/diva_pci.h
index 237902dc4f6e..b09e23e3f24a 100644
--- a/drivers/isdn/hardware/eicon/diva_pci.h
+++ b/drivers/isdn/hardware/eicon/diva_pci.h
@@ -1,9 +1,12 @@
-/* $Id: diva_pci.h,v 1.1.2.2 2001/02/12 20:23:46 armin Exp $ */
+/* $Id: diva_pci.h,v 1.6 2003/01/04 15:29:45 schindler Exp $ */
#ifndef __DIVA_PCI_INTERFACE_H__
#define __DIVA_PCI_INTERFACE_H__
-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length);
+void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a,
+ int id,
+ unsigned long bar,
+ unsigned long area_length);
void divasa_unmap_pci_bar(void *bar);
unsigned long divasa_get_pci_irq(unsigned char bus,
unsigned char func, void *pci_dev_handle);
diff --git a/drivers/isdn/hardware/eicon/divacapi.h b/drivers/isdn/hardware/eicon/divacapi.h
index 69811d2839d6..9f5b68037a26 100644
--- a/drivers/isdn/hardware/eicon/divacapi.h
+++ b/drivers/isdn/hardware/eicon/divacapi.h
@@ -643,7 +643,7 @@ struct async_s {
unsigned parity:2;
unsigned spare: 2;
unsigned stp: 1;
- unsigned ch_len:2; // 3th octett in CAI
+ unsigned ch_len:2; /* 3th octett in CAI */
};
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index 2901f5d19b35..836f7535146d 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -1,10 +1,10 @@
-/* $Id: divamnt.c,v 1.1.2.4 2001/05/01 15:48:05 armin Exp $
+/* $Id: divamnt.c,v 1.27 2003/09/09 06:46:29 schindler Exp $
*
* Driver for Eicon DIVA Server ISDN cards.
* Maint module
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -19,7 +19,6 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
-#include <linux/vmalloc.h>
#include <linux/devfs_fs_kernel.h>
#include "platform.h"
@@ -28,16 +27,14 @@
#include "di_defs.h"
#include "debug_if.h"
-static char *main_revision = "$Revision: 1.1.2.4 $";
+static char *main_revision = "$Revision: 1.27 $";
-static int major = 241;
+static int major;
MODULE_DESCRIPTION("Maint driver for Eicon DIVA Server cards");
MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
MODULE_SUPPORTED_DEVICE("DIVA card driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(major, "i");
-MODULE_PARM_DESC(major, "Major number for /dev/DivasMAINT");
int buffer_length = 128;
MODULE_PARM(buffer_length, "i");
@@ -47,7 +44,8 @@ MODULE_PARM(diva_dbg_mem, "l");
static char *DRIVERNAME =
"Eicon DIVA - MAINT module (http://www.melware.net)";
static char *DRIVERLNAME = "diva_mnt";
-char *DRIVERRELEASE = "2.0";
+static char *DEVNAME = "DivasMAINT";
+char *DRIVERRELEASE_MNT = "2.0";
static wait_queue_head_t msgwaitq;
static DECLARE_MUTEX(opened_sem);
@@ -77,18 +75,8 @@ static char *getrev(const char *revision)
}
/*
- * memory alloc
+ * buffer alloc
*/
-void *diva_os_malloc(unsigned long flags, unsigned long size)
-{
- return (vmalloc(size));
-}
-void diva_os_free(unsigned long flags, void *ptr)
-{
- if (ptr) {
- vfree(ptr);
- }
-}
void *diva_os_malloc_tbuffer(unsigned long flags, unsigned long size)
{
return (kmalloc(size, GFP_KERNEL));
@@ -101,17 +89,6 @@ void diva_os_free_tbuffer(unsigned long flags, void *ptr)
}
/*
- * sleep msec
- */
-void diva_os_sleep(dword mSec)
-{
- unsigned long timeout = HZ * mSec / 1000 + 1;
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(timeout);
-}
-
-/*
* kernel/user space copy functions
*/
int diva_os_copy_to_user(void *os_handle, void *dst, const void *src,
@@ -158,7 +135,7 @@ void diva_os_get_time(dword * sec, dword * usec)
* /proc entries
*/
-extern struct proc_dir_entry *proc_net_isdn_eicon;
+extern struct proc_dir_entry *proc_net_eicon;
static struct proc_dir_entry *maint_proc_entry = NULL;
/*
@@ -363,7 +340,7 @@ static int DIVA_INIT_FUNCTION create_maint_proc(void)
{
maint_proc_entry =
create_proc_entry("maint", S_IFREG | S_IRUGO | S_IWUSR,
- proc_net_isdn_eicon);
+ proc_net_eicon);
if (!maint_proc_entry)
return (0);
@@ -376,7 +353,7 @@ static int DIVA_INIT_FUNCTION create_maint_proc(void)
static void remove_maint_proc(void)
{
if (maint_proc_entry) {
- remove_proc_entry("maint", proc_net_isdn_eicon);
+ remove_proc_entry("maint", proc_net_eicon);
maint_proc_entry = NULL;
}
}
@@ -408,20 +385,20 @@ static struct file_operations divas_maint_fops = {
static void divas_maint_unregister_chrdev(void)
{
- devfs_remove("DivasMAINT");
- unregister_chrdev(major, "DivasMAINT");
+ devfs_remove(DEVNAME);
+ unregister_chrdev(major, DEVNAME);
}
static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void)
{
- if (register_chrdev(major, "DivasMAINT", &divas_maint_fops))
+ if ((major = register_chrdev(0, DEVNAME, &divas_maint_fops)) < 0)
{
printk(KERN_ERR "%s: failed to create /dev entry.\n",
DRIVERLNAME);
return (0);
}
+ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasMAINT");
return (1);
}
@@ -446,10 +423,9 @@ static int DIVA_INIT_FUNCTION maint_init(void)
init_waitqueue_head(&msgwaitq);
printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
+ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_MNT);
strcpy(tmprev, main_revision);
- printk("%s Build: %s Major: %d\n", getrev(tmprev), DIVA_BUILD,
- major);
+ printk("%s Build: %s \n", getrev(tmprev), DIVA_BUILD);
if (!divas_maint_register_chrdev()) {
ret = -EIO;
@@ -472,9 +448,9 @@ static int DIVA_INIT_FUNCTION maint_init(void)
goto out;
}
- printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s \n",
- DRIVERLNAME, buffer, buffer_length,
- (diva_dbg_mem == 0) ? "internal" : "external");
+ printk(KERN_INFO "%s: trace buffer = %p - %d kBytes, %s (Major: %d)\n",
+ DRIVERLNAME, buffer, (buffer_length / 1024),
+ (diva_dbg_mem == 0) ? "internal" : "external", major);
out:
return (ret);
diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c
index 4fe56e14efee..4d7a0a5abefa 100644
--- a/drivers/isdn/hardware/eicon/divasfunc.c
+++ b/drivers/isdn/hardware/eicon/divasfunc.c
@@ -1,9 +1,9 @@
-/* $Id: divasfunc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: divasfunc.c,v 1.22 2003/09/09 06:46:29 schindler Exp $
*
* Low level driver for Eicon DIVA Server ISDN cards.
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -21,6 +21,8 @@
#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
+static int debugmask;
+
extern void DIVA_DIDD_Read(void *, int);
extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
@@ -28,7 +30,7 @@ extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
#define MAX_DESCRIPTORS 32
extern void diva_run_trap_script(PISDN_ADAPTER IoAdapter, dword ANum);
-extern char *DRIVERRELEASE;
+extern char *DRIVERRELEASE_DIVAS;
static dword notify_handle;
static DESCRIPTOR DAdapter;
@@ -42,8 +44,6 @@ static void no_printf(unsigned char *x, ...)
/* dummy debug function */
}
-DIVA_DI_PRINTF dprintf = no_printf;
-
#include "debuglib.c"
/*
@@ -117,10 +117,11 @@ void diva_xdi_didd_remove_adapter(int card)
*/
static void start_dbg(void)
{
- DbgRegister("DIVAS", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s]-%s-%s)",
DIVA_BUILD, diva_xdi_common_code_build, __DATE__,
- __TIME__))}
+ __TIME__))
+}
/*
* stop debug
@@ -174,7 +175,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
req.didd_notify.e.Req = 0;
req.didd_notify.e.Rc =
IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
+ req.didd_notify.info.callback = (void *)didd_callback;
req.didd_notify.info.context = 0;
DAdapter.request((ENTITY *) & req);
if (req.didd_notify.e.Rc != 0xff) {
@@ -214,13 +215,19 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void)
/*
* init
*/
-int DIVA_INIT_FUNCTION divasfunc_init(void)
+int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
{
+ char *version;
+
+ debugmask = dbgmask;
+
if (!connect_didd()) {
DBG_ERR(("divasfunc: failed to connect to DIDD."))
return (0);
}
+ version = diva_xdi_common_code_build;
+
divasa_xdi_driver_entry();
return (1);
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 6572ab938b27..1a0640d824d0 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -1,10 +1,10 @@
-/* $Id: divasi.c,v 1.1.2.7 2001/05/01 15:48:05 armin Exp $
+/* $Id: divasi.c,v 1.25 2003/09/09 06:46:29 schindler Exp $
*
* Driver for Eicon DIVA Server ISDN cards.
* User Mode IDI Interface
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -19,7 +19,6 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
-#include <linux/vmalloc.h>
#include <linux/devfs_fs_kernel.h>
#include "platform.h"
@@ -28,27 +27,27 @@
#include "um_xdi.h"
#include "um_idi.h"
-static char *main_revision = "$Revision: 1.1.2.7 $";
+static char *main_revision = "$Revision: 1.25 $";
-static int major = 242;
+static int major;
MODULE_DESCRIPTION("User IDI Interface for Eicon ISDN cards");
MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
MODULE_SUPPORTED_DEVICE("DIVA card driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(major, "i");
-MODULE_PARM_DESC(major, "Major number for /dev/DivasIDI");
typedef struct _diva_um_idi_os_context {
wait_queue_head_t read_wait;
wait_queue_head_t close_wait;
struct timer_list diva_timer_id;
int aborted;
+ int adapter_nr;
} diva_um_idi_os_context_t;
static char *DRIVERNAME = "Eicon DIVA - User IDI (http://www.melware.net)";
static char *DRIVERLNAME = "diva_idi";
-char *DRIVERRELEASE = "2.0";
+static char *DEVNAME = "DivasIDI";
+char *DRIVERRELEASE_IDI = "2.0";
extern int idifunc_init(void);
extern void idifunc_finit(void);
@@ -83,32 +82,9 @@ static int remove_entity(void *entity);
static void diva_um_timer_function(unsigned long data);
/*
- * malloc
- */
-void *diva_os_malloc(unsigned long flags, unsigned long size)
-{
- void *ret = NULL;
-
- if (size) {
- ret = (void *) vmalloc((unsigned int) size);
- }
- return (ret);
-}
-
-/*
- * free
- */
-void diva_os_free(unsigned long unused, void *ptr)
-{
- if (ptr) {
- vfree(ptr);
- }
-}
-
-/*
* proc entry
*/
-extern struct proc_dir_entry *proc_net_isdn_eicon;
+extern struct proc_dir_entry *proc_net_eicon;
static struct proc_dir_entry *um_idi_proc_entry = NULL;
static int
@@ -120,10 +96,11 @@ um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof,
len += sprintf(page + len, "%s\n", DRIVERNAME);
len += sprintf(page + len, "name : %s\n", DRIVERLNAME);
- len += sprintf(page + len, "release : %s\n", DRIVERRELEASE);
+ len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_IDI);
strcpy(tmprev, main_revision);
len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
len += sprintf(page + len, "build : %s\n", DIVA_BUILD);
+ len += sprintf(page + len, "major : %d\n", major);
if (off + count >= len)
*eof = 1;
@@ -137,7 +114,7 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
{
um_idi_proc_entry = create_proc_entry(DRIVERLNAME,
S_IFREG | S_IRUGO | S_IWUSR,
- proc_net_isdn_eicon);
+ proc_net_eicon);
if (!um_idi_proc_entry)
return (0);
@@ -150,7 +127,7 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
static void remove_um_idi_proc(void)
{
if (um_idi_proc_entry) {
- remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
+ remove_proc_entry(DRIVERLNAME, proc_net_eicon);
um_idi_proc_entry = NULL;
}
}
@@ -167,20 +144,20 @@ static struct file_operations divas_idi_fops = {
static void divas_idi_unregister_chrdev(void)
{
- devfs_remove("DivasIDI");
- unregister_chrdev(major, "DivasIDI");
+ devfs_remove(DEVNAME);
+ unregister_chrdev(major, DEVNAME);
}
static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void)
{
- if (register_chrdev(major, "DivasIDI", &divas_idi_fops))
+ if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0)
{
printk(KERN_ERR "%s: failed to create /dev entry.\n",
DRIVERLNAME);
return (0);
}
+ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "DivasIDI");
return (1);
}
@@ -193,10 +170,9 @@ static int DIVA_INIT_FUNCTION divasi_init(void)
int ret = 0;
printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
+ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_IDI);
strcpy(tmprev, main_revision);
- printk("%s Build: %s Major: %d\n", getrev(tmprev), DIVA_BUILD,
- major);
+ printk("%s Build: %s\n", getrev(tmprev), DIVA_BUILD);
if (!divas_idi_register_chrdev()) {
ret = -EIO;
@@ -219,6 +195,7 @@ static int DIVA_INIT_FUNCTION divasi_init(void)
ret = -EIO;
goto out;
}
+ printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
out:
return (ret);
@@ -330,6 +307,7 @@ static int um_idi_open_adapter(struct file *file, int adapter_nr)
p_os->diva_timer_id.function = (void *) diva_um_timer_function;
p_os->diva_timer_id.data = (unsigned long) p_os;
p_os->aborted = 0;
+ p_os->adapter_nr = adapter_nr;
return (1);
}
@@ -432,7 +410,8 @@ static int um_idi_open(struct inode *inode, struct file *file)
static int um_idi_release(struct inode *inode, struct file *file)
{
- unsigned int adapter_nr = iminor(inode);
+ diva_um_idi_os_context_t *p_os;
+ unsigned int adapter_nr;
int ret = 0;
if (!(file->private_data)) {
@@ -440,6 +419,14 @@ static int um_idi_release(struct inode *inode, struct file *file)
goto out;
}
+ if (!(p_os =
+ (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ adapter_nr = p_os->adapter_nr;
+
if ((ret = remove_entity(file->private_data))) {
goto out;
}
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 75fd1545bd21..bcd7221eef93 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -1,9 +1,9 @@
-/* $Id: divasmain.c,v 1.1.2.8 2001/05/01 15:48:05 armin Exp $
+/* $Id: divasmain.c,v 1.39 2003/09/09 07:42:05 schindler Exp $
*
* Low level driver for Eicon DIVA Server ISDN cards.
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -16,14 +16,12 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/unistd.h>
-#include <linux/vmalloc.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
@@ -37,38 +35,44 @@
#include "di_defs.h"
#include "divasync.h"
#include "diva.h"
-#include "diva_pci.h"
#include "di.h"
#include "io.h"
#include "xdi_msg.h"
#include "xdi_adapter.h"
#include "xdi_vers.h"
#include "diva_dma.h"
+#include "diva_pci.h"
-static char *main_revision = "$Revision: 1.1.2.8 $";
+static char *main_revision = "$Revision: 1.39 $";
int errno = 0;
-static int major = 240;
+static int major;
+
+static int dbgmask;
MODULE_DESCRIPTION("Kernel driver for Eicon DIVA Server cards");
MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
MODULE_LICENSE("GPL");
-MODULE_PARM(major, "i");
-MODULE_PARM_DESC(major, "Major number for /dev/Divas");
+
+MODULE_PARM(dbgmask, "i");
+MODULE_PARM_DESC(dbgmask, "initial debug mask");
static char *DRIVERNAME =
"Eicon DIVA Server driver (http://www.melware.net)";
static char *DRIVERLNAME = "divas";
-char *DRIVERRELEASE = "2.0";
+static char *DEVNAME = "Divas";
+char *DRIVERRELEASE_DIVAS = "2.0";
extern irqreturn_t diva_os_irq_wrapper(int irq, void *context,
struct pt_regs *regs);
extern int create_divas_proc(void);
extern void remove_divas_proc(void);
extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
-extern int divasfunc_init(void);
+extern int divasfunc_init(int dbgmask);
extern void divasfunc_exit(void);
+static devfs_handle_t devfs_handle;
+
typedef struct _diva_os_thread_dpc {
struct tasklet_struct divas_task;
struct work_struct trap_script_task;
@@ -119,7 +123,7 @@ typedef struct _diva_os_thread_dpc {
/*
This table should be sorted by PCI device ID
*/
-static struct pci_device_id divas_pci_tbl[] = {
+static struct pci_device_id divas_pci_tbl[] __devinitdata = {
/* Diva Server BRI-2M PCI 0xE010 */
{PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_MAESTRA_PCI},
@@ -185,19 +189,6 @@ static char *getrev(const char *revision)
return rev;
}
-void diva_os_sleep(dword mSec)
-{
- unsigned long timeout = HZ * mSec / 1000 + 1;
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(timeout);
-}
-
-void diva_os_wait(dword mSec)
-{
- mdelay(mSec);
-}
-
void diva_log_info(unsigned char *format, ...)
{
va_list args;
@@ -215,29 +206,8 @@ void divas_get_version(char *p)
char tmprev[32];
strcpy(tmprev, main_revision);
- sprintf(p, "%s: %s(%s) %s(%s)\n", DRIVERLNAME, DRIVERRELEASE,
- getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD);
-}
-
-/*********************************************************
- ** malloc / free
- *********************************************************/
-
-void *diva_os_malloc(unsigned long flags, unsigned long size)
-{
- void *ret = NULL;
-
- if (size) {
- ret = (void *) vmalloc((unsigned int) size);
- }
- return (ret);
-}
-
-void diva_os_free(unsigned long unused, void *ptr)
-{
- if (ptr) {
- vfree(ptr);
- }
+ sprintf(p, "%s: %s(%s) %s(%s) major=%d\n", DRIVERLNAME, DRIVERRELEASE_DIVAS,
+ getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD, major);
}
/* --------------------------------------------------------------------------
@@ -282,6 +252,7 @@ void diva_run_trap_script(PISDN_ADAPTER IoAdapter, dword ANum)
(diva_os_thread_dpc_t *) psoft_isr->object;
if (context && !context->card_failed) {
+ printk(KERN_ERR "%s: adapter %d trapped !\n", DRIVERLNAME, ANum + 1);
context->card_failed = ANum + 1;
schedule_work(&context->trap_script_task);
}
@@ -505,8 +476,8 @@ void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap)
*********************************************************/
int
-diva_os_register_io_port(int on, unsigned long port, unsigned long length,
- const char *name)
+diva_os_register_io_port(void *adapter, int on, unsigned long port,
+ unsigned long length, const char *name, int id)
{
if (on) {
if (!request_region(port, length, name)) {
@@ -519,7 +490,7 @@ diva_os_register_io_port(int on, unsigned long port, unsigned long length,
return (0);
}
-void *divasa_remap_pci_bar(unsigned long bar, unsigned long area_length)
+void *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, int id, unsigned long bar, unsigned long area_length)
{
void *ret;
@@ -772,20 +743,20 @@ static struct file_operations divas_fops = {
static void divas_unregister_chrdev(void)
{
- devfs_remove("Divas");
- unregister_chrdev(major, "Divas");
+ devfs_remove(DEVNAME);
+ unregister_chrdev(major, DEVNAME);
}
static int DIVA_INIT_FUNCTION divas_register_chrdev(void)
{
- if (register_chrdev(major, "Divas", &divas_fops))
+ if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0)
{
printk(KERN_ERR "%s: failed to create /dev entry.\n",
DRIVERLNAME);
return (0);
}
+ devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
- devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, "Divas");
return (1);
}
@@ -877,23 +848,20 @@ static int DIVA_INIT_FUNCTION divas_init(void)
int ret = 0;
printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE);
+ printk(KERN_INFO "%s: Rel:%s Rev:", DRIVERLNAME, DRIVERRELEASE_DIVAS);
strcpy(tmprev, main_revision);
- printk("%s Build: %s(%s) Major: %d\n", getrev(tmprev),
- diva_xdi_common_code_build, DIVA_BUILD, major);
+ printk("%s Build: %s(%s)\n", getrev(tmprev),
+ diva_xdi_common_code_build, DIVA_BUILD);
printk(KERN_INFO "%s: support for: ", DRIVERLNAME);
#ifdef CONFIG_ISDN_DIVAS_BRIPCI
printk("BRI/PCI ");
#endif
-#ifdef CONFIG_ISDN_DIVAS_4BRIPCI
- printk("4BRI/PCI ");
-#endif
#ifdef CONFIG_ISDN_DIVAS_PRIPCI
printk("PRI/PCI ");
#endif
- printk("\n");
+ printk("adapters\n");
- if (!divasfunc_init()) {
+ if (!divasfunc_init(dbgmask)) {
printk(KERN_ERR "%s: failed to connect to DIDD.\n",
DRIVERLNAME);
ret = -EIO;
@@ -901,15 +869,19 @@ static int DIVA_INIT_FUNCTION divas_init(void)
}
if (!divas_register_chrdev()) {
+#ifdef MODULE
divasfunc_exit();
+#endif
ret = -EIO;
goto out;
}
if (!create_divas_proc()) {
+#ifdef MODULE
remove_divas_proc();
divas_unregister_chrdev();
divasfunc_exit();
+#endif
printk(KERN_ERR "%s: failed to create proc entry.\n",
DRIVERLNAME);
ret = -EIO;
@@ -917,13 +889,16 @@ static int DIVA_INIT_FUNCTION divas_init(void)
}
if ((ret = pci_module_init(&diva_pci_driver))) {
+#ifdef MODULE
remove_divas_proc();
divas_unregister_chrdev();
divasfunc_exit();
+#endif
printk(KERN_ERR "%s: failed to init pci driver.\n",
DRIVERLNAME);
goto out;
}
+ printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
out:
return (ret);
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index d23c1470ae1e..5c98d6acb41a 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -1,10 +1,10 @@
-/* $Id: divasproc.c,v 1.1.2.4 2001/02/16 08:40:36 armin Exp $
+/* $Id: divasproc.c,v 1.18 2003/09/09 06:46:29 schindler Exp $
*
* Low level driver for Eicon DIVA Server ISDN cards.
* /proc functions
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
-#include <linux/interrupt.h>
#include "platform.h"
#include "debuglib.h"
@@ -23,7 +22,6 @@
#undef ID_MASK
#undef N_DATA
#include "pc.h"
-#include "diva_pci.h"
#include "di_defs.h"
#include "divasync.h"
#include "di.h"
@@ -31,6 +29,7 @@
#include "xdi_msg.h"
#include "xdi_adapter.h"
#include "diva.h"
+#include "diva_pci.h"
extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
@@ -52,7 +51,7 @@ static char *d_l1_down_proc_name = "dynamic_l1_down";
** "divas" entry
*/
-extern struct proc_dir_entry *proc_net_isdn_eicon;
+extern struct proc_dir_entry *proc_net_eicon;
static struct proc_dir_entry *divas_proc_entry = NULL;
static ssize_t
@@ -131,7 +130,7 @@ int create_divas_proc(void)
{
divas_proc_entry = create_proc_entry(divas_proc_name,
S_IFREG | S_IRUGO,
- proc_net_isdn_eicon);
+ proc_net_eicon);
if (!divas_proc_entry)
return (0);
@@ -144,7 +143,7 @@ int create_divas_proc(void)
void remove_divas_proc(void)
{
if (divas_proc_entry) {
- remove_proc_entry(divas_proc_name, proc_net_isdn_eicon);
+ remove_proc_entry(divas_proc_name, proc_net_eicon);
divas_proc_entry = NULL;
}
}
@@ -333,7 +332,8 @@ info_read(char *page, char **start, off_t off, int count, int *eof,
}
}
if ((!a->xdi_adapter.port) &&
- ((!a->xdi_adapter.ram) || (!a->xdi_adapter.reset)
+ ((!a->xdi_adapter.ram) ||
+ (!a->xdi_adapter.reset)
|| (!a->xdi_adapter.cfg))) {
if (!IoAdapter->irq_info.irq_nr) {
p = "slave";
@@ -369,20 +369,14 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a)
struct proc_dir_entry *de, *pe;
char tmp[16];
- if (in_interrupt()) {
- printk(KERN_ERR
- "divasproc: create_proc in_interrupt, not creating\n");
- return (1);
- }
-
sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
- if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_isdn_eicon)))
+ if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_eicon)))
return (0);
a->proc_adapter_dir = (void *) de;
if (!(pe =
- create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR,
- de))) return (0);
+ create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de)))
+ return (0);
a->proc_info = (void *) pe;
pe->write_proc = info_write;
pe->read_proc = info_read;
@@ -429,7 +423,7 @@ void remove_adapter_proc(diva_os_xdi_adapter_t * a)
(struct proc_dir_entry *) a->proc_adapter_dir);
}
sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
- remove_proc_entry(tmp, proc_net_isdn_eicon);
+ remove_proc_entry(tmp, proc_net_eicon);
DBG_TRC(("proc entry %s%d removed", adapter_dir_name,
a->controller));
}
diff --git a/drivers/isdn/hardware/eicon/dlist.c b/drivers/isdn/hardware/eicon/dlist.c
index b71b5f58eca2..cc0e99c03428 100644
--- a/drivers/isdn/hardware/eicon/dlist.c
+++ b/drivers/isdn/hardware/eicon/dlist.c
@@ -1,4 +1,4 @@
-/* $Id: dlist.c,v 1.1.2.2 2001/02/11 14:40:41 armin Exp $ */
+/* $Id: dlist.c,v 1.6 2003/08/25 16:03:35 schindler Exp $ */
#include "platform.h"
#include "dlist.h"
@@ -7,7 +7,7 @@
** Initialize linked list
*/
-void diva_q_init(diva_entity_queue_t * q)
+static void diva_q_init(diva_entity_queue_t * q)
{
memset(q, 0x00, sizeof(*q));
}
@@ -15,7 +15,7 @@ void diva_q_init(diva_entity_queue_t * q)
/*
** Remove element from linked list
*/
-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
+static void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
{
if (!what->prev) {
if ((q->head = what->next)) {
@@ -36,7 +36,7 @@ void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what)
/*
** Add element to the tail of linked list
*/
-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
+static void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
{
what->next = 0;
if (!q->head) {
@@ -49,7 +49,7 @@ void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what)
}
}
-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
+static diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
const void *what, diva_q_cmp_fn_t cmp_fn)
{
diva_entity_link_t *diva_current = q->head;
@@ -64,35 +64,13 @@ diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
return (diva_current);
}
-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
+static diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q)
{
return (q->head);
}
-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q)
-{
- return (q->tail);
-}
-
-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
+static diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what)
{
return ((what) ? what->next : 0);
}
-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what)
-{
- return ((what) ? what->prev : 0);
-}
-
-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q)
-{
- int i = 0;
- const diva_entity_link_t *diva_current = q->head;
-
- while (diva_current) {
- i++;
- diva_current = diva_current->next;
- }
-
- return (i);
-}
diff --git a/drivers/isdn/hardware/eicon/dlist.h b/drivers/isdn/hardware/eicon/dlist.h
index a8644f330296..47bbe45891da 100644
--- a/drivers/isdn/hardware/eicon/dlist.h
+++ b/drivers/isdn/hardware/eicon/dlist.h
@@ -1,4 +1,4 @@
-/* $Id: dlist.h,v 1.1.2.2 2001/02/08 12:25:43 armin Exp $ */
+/* $Id: dlist.h,v 1.5 2003/08/25 16:03:35 schindler Exp $ */
#ifndef __DIVA_LINK_H__
#define __DIVA_LINK_H__
@@ -17,16 +17,4 @@ typedef struct _diva_entity_queue {
typedef int (*diva_q_cmp_fn_t) (const void *what,
const diva_entity_link_t *);
-void diva_q_remove(diva_entity_queue_t * q, diva_entity_link_t * what);
-void diva_q_add_tail(diva_entity_queue_t * q, diva_entity_link_t * what);
-diva_entity_link_t *diva_q_find(const diva_entity_queue_t * q,
- const void *what, diva_q_cmp_fn_t cmp_fn);
-
-diva_entity_link_t *diva_q_get_head(diva_entity_queue_t * q);
-diva_entity_link_t *diva_q_get_tail(diva_entity_queue_t * q);
-diva_entity_link_t *diva_q_get_next(diva_entity_link_t * what);
-diva_entity_link_t *diva_q_get_prev(diva_entity_link_t * what);
-int diva_q_get_nr_of_entries(const diva_entity_queue_t * q);
-void diva_q_init(diva_entity_queue_t * q);
-
#endif
diff --git a/drivers/isdn/hardware/eicon/idifunc.c b/drivers/isdn/hardware/eicon/idifunc.c
index b51c7358fbbb..5adcbddfb4ae 100644
--- a/drivers/isdn/hardware/eicon/idifunc.c
+++ b/drivers/isdn/hardware/eicon/idifunc.c
@@ -1,10 +1,10 @@
-/* $Id: idifunc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: idifunc.c,v 1.13 2003/08/25 14:49:53 schindler Exp $
*
* Driver for Eicon DIVA Server ISDN cards.
* User Mode IDI Interface
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -19,7 +19,7 @@
#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
-extern char *DRIVERRELEASE;
+extern char *DRIVERRELEASE_IDI;
extern void DIVA_DIDD_Read(void *, int);
extern int diva_user_mode_idi_create_adapter(const DESCRIPTOR *, int);
@@ -36,8 +36,6 @@ static void no_printf(unsigned char *x, ...)
/* dummy debug function */
}
-DIVA_DI_PRINTF dprintf = no_printf;
-
#include "debuglib.c"
/*
@@ -202,7 +200,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter,
} else {
memcpy(&MAdapter, adapter, sizeof(MAdapter));
dprintf = (DIVA_DI_PRINTF) MAdapter.request;
- DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
}
} else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */
if (removal) {
@@ -233,7 +231,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
req.didd_notify.e.Req = 0;
req.didd_notify.e.Rc =
IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
+ req.didd_notify.info.callback = (void *)didd_callback;
req.didd_notify.info.context = 0;
DAdapter.request((ENTITY *) & req);
if (req.didd_notify.e.Rc != 0xff) {
@@ -244,7 +242,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
} else if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */
memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
dprintf = (DIVA_DI_PRINTF) MAdapter.request;
- DbgRegister("User IDI", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("User IDI", DRIVERRELEASE_IDI, DBG_DEFAULT);
} else if ((DIDD_Table[x].type > 0)
&& (DIDD_Table[x].type < 16)) { /* IDI Adapter found */
um_new_card(&DIDD_Table[x]);
diff --git a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c
index d604ab5f0a36..6f94ee9328ee 100644
--- a/drivers/isdn/hardware/eicon/io.c
+++ b/drivers/isdn/hardware/eicon/io.c
@@ -72,10 +72,10 @@ IDI_CALL Requests[MAX_ADAPTER] =
*/
static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ+1] = {
(DIVA_XDI_EXTENDED_FEATURES_VALID |
- DIVA_XDI_EXTENDED_FEATURE_CMA |
DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR |
DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS |
#if defined(DIVA_IDI_RX_DMA)
+ DIVA_XDI_EXTENDED_FEATURE_CMA |
DIVA_XDI_EXTENDED_FEATURE_RX_DMA |
#endif
DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
@@ -156,7 +156,8 @@ void
dump_trap_frame (PISDN_ADAPTER IoAdapter, byte *exceptionFrame)
{
MP_XCPTC *xcept = (MP_XCPTC *)exceptionFrame ;
- dword *regs = &xcept->regs[0] ;
+ dword *regs;
+ regs = &xcept->regs[0] ;
DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
&IoAdapter->Name[0]))
DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
@@ -567,26 +568,38 @@ Trapped:
/*------------------------------------------------------------------*/
byte mem_in (ADAPTER *a, void *addr)
{
- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- return (*Base) ;
+ byte val;
+ volatile byte* Base;
+
+ Base = (volatile byte *)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ val = *(Base + (unsigned long)addr);
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ return (val);
}
word mem_inw (ADAPTER *a, void *addr)
{
- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- return (READ_WORD(Base)) ;
+ word val;
+ volatile byte* Base;
+
+ Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ val = READ_WORD((Base + (unsigned long)addr));
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+ return (val);
}
void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords)
{
- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
while (dwords--) {
- *data++ = READ_DWORD(Base);
- Base++;
+ *data++ = READ_DWORD((Base + (unsigned long)addr));
+ addr+=4;
}
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_in_buffer (ADAPTER *a, void *addr, void *buffer, word length)
{
- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- memcpy (buffer, Base, length) ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ memcpy (buffer, (void *)(Base + (unsigned long)addr), length);
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
{
@@ -598,99 +611,130 @@ void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
}
void mem_out (ADAPTER *a, void *addr, byte data)
{
- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- *Base = data ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ *(Base + (unsigned long)addr) = data ;
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_outw (ADAPTER *a, void *addr, word data)
{
- word* Base = (word*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- WRITE_WORD(Base, data);
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ WRITE_WORD((Base + (unsigned long)addr), data);
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords)
{
- volatile dword* Base = (dword*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
while (dwords--) {
- WRITE_DWORD(Base, *data);
- Base++;
+ WRITE_DWORD((Base + (unsigned long)addr), *data);
+ addr+=4;
data++;
}
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_out_buffer (ADAPTER *a, void *addr, void *buffer, word length)
{
- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- memcpy (Base, buffer, length) ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ memcpy ((void *)(Base + (unsigned long)addr), buffer, length) ;
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
void mem_inc (ADAPTER *a, void *addr)
{
- byte* Base = (byte*)&((PISDN_ADAPTER)a->io)->ram[(unsigned long)addr] ;
- byte x = *Base ;
- *Base = x + 1 ;
+ volatile byte* Base = (volatile byte*)DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+ byte x = *(Base + (unsigned long)addr);
+ *(Base + (unsigned long)addr) = x + 1 ;
+ DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
}
/*------------------------------------------------------------------*/
/* ram access functions for io-mapped cards */
/*------------------------------------------------------------------*/
byte io_in(ADAPTER * a, void * adr)
{
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- return inpp(((PISDN_ADAPTER)a->io)->port);
+ byte val;
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port + 4, (word)(unsigned long)adr);
+ val = inpp(Port);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ return(val);
}
word io_inw(ADAPTER * a, void * adr)
{
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- return inppw(((PISDN_ADAPTER)a->io)->port);
+ word val;
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port + 4, (word)(unsigned long)adr);
+ val = inppw(Port);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ return(val);
}
void io_in_buffer(ADAPTER * a, void * adr, void * buffer, word len)
{
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
byte* P = (byte*)buffer;
if ((long)adr & 1) {
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- *P = inpp(((PISDN_ADAPTER)a->io)->port);
+ outppw(Port+4, (word)(unsigned long)adr);
+ *P = inpp(Port);
P++;
adr = ((byte *) adr) + 1;
len--;
- if (!len) return;
+ if (!len) {
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ return;
}
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- inppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
+ }
+ outppw(Port+4, (word)(unsigned long)adr);
+ inppw_buffer (Port, P, len+1);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e)
{
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)RBuffer);
- ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(((PISDN_ADAPTER)a->io)->port);
- inppw_buffer (((PISDN_ADAPTER)a->io)->port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port+4, (word)(unsigned long)RBuffer);
+ ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
+ inppw_buffer (Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
void io_out(ADAPTER * a, void * adr, byte data)
{
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- outpp(((PISDN_ADAPTER)a->io)->port, data);
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port+4, (word)(unsigned long)adr);
+ outpp(Port, data);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
void io_outw(ADAPTER * a, void * adr, word data)
{
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- outppw(((PISDN_ADAPTER)a->io)->port, data);
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port+4, (word)(unsigned long)adr);
+ outppw(Port, data);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
void io_out_buffer(ADAPTER * a, void * adr, void * buffer, word len)
{
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
byte* P = (byte*)buffer;
if ((long)adr & 1) {
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- outpp(((PISDN_ADAPTER)a->io)->port, *P);
+ outppw(Port+4, (word)(unsigned long)adr);
+ outpp(Port, *P);
P++;
adr = ((byte *) adr) + 1;
len--;
- if (!len) return;
+ if (!len) {
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+ return;
+ }
}
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- outppw_buffer (((PISDN_ADAPTER)a->io)->port, P, len+1);
+ outppw(Port+4, (word)(unsigned long)adr);
+ outppw_buffer (Port, P, len+1);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
void io_inc(ADAPTER * a, void * adr)
{
byte x;
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- x = inpp(((PISDN_ADAPTER)a->io)->port);
- outppw(((PISDN_ADAPTER)a->io)->port+4, (word)(unsigned long)adr);
- outpp(((PISDN_ADAPTER)a->io)->port, x+1);
+ byte *Port = (byte*)DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+ outppw(Port+4, (word)(unsigned long)adr);
+ x = inpp(Port);
+ outppw(Port+4, (word)(unsigned long)adr);
+ outpp(Port, x+1);
+ DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
}
/*------------------------------------------------------------------*/
/* OS specific functions related to queuing of entities */
diff --git a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h
index 532b3b4e87da..3e54039839a0 100644
--- a/drivers/isdn/hardware/eicon/io.h
+++ b/drivers/isdn/hardware/eicon/io.h
@@ -40,14 +40,6 @@ typedef struct {
PISDN_ADAPTER QuadroAdapter[4] ;
} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY ;
/* --------------------------------------------------------------------------
- Special OS memory support structures
- -------------------------------------------------------------------------- */
-#define MAX_MAPPED_ENTRIES 8
-typedef struct {
- void * Address;
- dword Length;
-} ADAPTER_MEMORY ;
-/* --------------------------------------------------------------------------
Configuration of XDI clients carried by XDI
-------------------------------------------------------------------------- */
#define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON 0x01
@@ -71,7 +63,6 @@ struct _ISDN_ADAPTER {
/*
remember mapped memory areas
*/
- ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES] ;
CARD_PROPERTIES Properties ;
dword cardType ;
dword protocol_id ; /* configured protocol identifier */
@@ -97,6 +88,8 @@ struct _ISDN_ADAPTER {
dword MemoryBase ;
dword MemorySize ;
byte *Address ;
+ byte *Config ;
+ byte *Control ;
byte *reset ;
byte *port ;
byte *ram ;
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 88b254b0ed5d..2f2dfe384e3f 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -3590,7 +3590,7 @@ byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
{
if (plci->channels)
{
- for (ncci = 1; ncci < MAX_NCCI+1; i++)
+ for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
{
if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
{
@@ -6612,7 +6612,7 @@ void nl_ind(PLCI * plci)
||(*data == DSP_UDATA_INDICATION_CTS_ON)) )
{
word conn_opt, ncpi_opt = 0x00;
-// HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data);
+/* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
if (*data == DSP_UDATA_INDICATION_DCD_ON)
plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
@@ -7813,15 +7813,15 @@ word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_faciliti
}
}
- if(READ_WORD(bp_parms[0].info)==2 || // V.110 async
- READ_WORD(bp_parms[0].info)==3 ) // V.110 sync
+ if(READ_WORD(bp_parms[0].info)==2 || /* V.110 async */
+ READ_WORD(bp_parms[0].info)==3 ) /* V.110 sync */
{
if(bp_parms[3].length){
dbug(1,dprintf("V.110,%d",READ_WORD(&bp_parms[3].info[1])));
- switch(READ_WORD(&bp_parms[3].info[1])){ // Rate
+ switch(READ_WORD(&bp_parms[3].info[1])){ /* Rate */
case 0:
case 56000:
- if(READ_WORD(bp_parms[0].info)==3){ //V.110 sync 56k
+ if(READ_WORD(bp_parms[0].info)==3){ /* V.110 sync 56k */
dbug(1,dprintf("56k sync HSCX"));
cai[1] = 8;
cai[2] = 0;
@@ -7859,7 +7859,7 @@ word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_faciliti
return _B1_PARM_NOT_SUPPORTED;
}
cai[3] = 0;
- if (cai[1] == 13) // v.110 async
+ if (cai[1] == 13) /* v.110 async */
{
if (bp_parms[3].length >= 8)
{
@@ -7906,7 +7906,7 @@ word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_faciliti
}
WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
-//HexDump ("CAI", sizeof(cai), &cai[0]);
+/* HexDump ("CAI", sizeof(cai), &cai[0]); */
add_p(plci, CAI, cai);
return 0;
@@ -8681,7 +8681,7 @@ static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms)
DLC_MODEMPROT_DISABLE_COMPRESSION;
}
dlc[0] = (byte)(i - 1);
-//HexDump ("DLC", sizeof(dlc), &dlc[0]);
+/* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
add_p(plci, DLC, dlc);
return (0);
}
@@ -8739,7 +8739,7 @@ void send_req(PLCI * plci)
{
ENTITY * e;
word l;
-// word i;
+/* word i; */
if(!plci) return;
if(plci->adapter->adapter_disabled) return;
@@ -8856,7 +8856,7 @@ void send_data(PLCI * plci)
}
else if (plci->send_disc == ncci)
{
- //dprintf("N_DISC");
+ /* dprintf("N_DISC"); */
plci->NData[0].PLength = 0;
plci->NL.ReqCh = a->ncci_ch[ncci];
plci->NL.Req = plci->nl_req = N_DISC;
@@ -9059,15 +9059,15 @@ static byte AddInfo(byte **add_i,
for(k=0;k<=flen;k++,j++)
{
facility[j]=fty_i[i][k];
-// dbug(1,dprintf("%x ",facility[j]));
+/* dbug(1,dprintf("%x ",facility[j])); */
}
}
facility[0] = len;
add_i[3] = facility;
}
-// dbug(1,dprintf("FacArrLen=%d ",len));
+/* dbug(1,dprintf("FacArrLen=%d ",len)); */
len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0];
- len += 4; // calculate length of all
+ len += 4; /* calculate length of all */
return(len);
}
@@ -9083,8 +9083,8 @@ void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER * a)
channel = chi[chi[0]]&0x3;
dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel));
voice_chi[2] = (channel) ? channel : 1;
- add_p(plci,FTY,"\x02\x01\x07"); // B On, default on 1
- add_p(plci,ESC,voice_chi); // Channel
+ add_p(plci,FTY,"\x02\x01\x07"); /* B On, default on 1 */
+ add_p(plci,ESC,voice_chi); /* Channel */
sig_req(plci,TEL_CTRL,0);
send_req(plci);
if(a->AdvSignalPLCI)
@@ -9096,7 +9096,7 @@ void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER * a)
void VoiceChannelOff(PLCI *plci)
{
dbug(1,dprintf("ExtDevOFF"));
- add_p(plci,FTY,"\x02\x01\x08"); // B Off
+ add_p(plci,FTY,"\x02\x01\x08"); /* B Off */
sig_req(plci,TEL_CTRL,0);
send_req(plci);
if(plci->adapter->AdvSignalPLCI)
diff --git a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c
index 2c74d96dca6d..232510c426cf 100644
--- a/drivers/isdn/hardware/eicon/mntfunc.c
+++ b/drivers/isdn/hardware/eicon/mntfunc.c
@@ -1,10 +1,10 @@
-/* $Id: mntfunc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
+/* $Id: mntfunc.c,v 1.15 2003/08/25 14:49:53 schindler Exp $
*
* Driver for Eicon DIVA Server ISDN cards.
* Maint module
*
- * Copyright 2000,2001 by Armin Schindler (mac@melware.de)
- * Copyright 2000,2001 Cytronics & Melware (info@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -17,7 +17,7 @@
#include "di_defs.h"
#include "debug_if.h"
-extern char *DRIVERRELEASE;
+extern char *DRIVERRELEASE_MNT;
#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
@@ -45,8 +45,6 @@ static void no_printf(unsigned char *x, ...)
/* dummy debug function */
}
-DIVA_DI_PRINTF dprintf = no_printf;
-
#include "debuglib.c"
/*
@@ -73,7 +71,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter,
} else {
memcpy(&MAdapter, adapter, sizeof(MAdapter));
dprintf = (DIVA_DI_PRINTF) MAdapter.request;
- DbgRegister("MAINT", DRIVERRELEASE, DBG_DEFAULT);
+ DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT);
}
} else if ((adapter->type > 0) && (adapter->type < 16)) {
if (removal) {
@@ -104,7 +102,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
req.didd_notify.e.Req = 0;
req.didd_notify.e.Rc =
IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
+ req.didd_notify.info.callback = (void *)didd_callback;
req.didd_notify.info.context = 0;
DAdapter.request((ENTITY *) & req);
if (req.didd_notify.e.Rc != 0xff)
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index a458e3be07cd..f8dcf577199c 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -1,4 +1,4 @@
-/* $Id: os_4bri.c,v 1.1.2.3 2001/02/14 21:10:19 armin Exp $ */
+/* $Id: os_4bri.c,v 1.25 2003/06/21 17:08:44 schindler Exp $ */
#include "platform.h"
#include "debuglib.h"
@@ -99,6 +99,40 @@ static int _4bri_is_rev_2_bri_card(int card_ordinal)
return (0);
}
+static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
+{
+ dword offset = a->resources.pci.qoffset;
+ dword c_offset = offset * a->xdi_adapter.ControllerNumber;
+
+ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
+ a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
+ a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
+
+ /*
+ Set up hardware related pointers
+ */
+ a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */
+ a->xdi_adapter.Address += c_offset;
+
+ a->xdi_adapter.Control = a->resources.pci.addr[2]; /* BAR2 SDRAM */
+
+ a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */
+ a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
+
+ a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
+ /*
+ ctlReg contains the register address for the MIPS CPU reset control
+ */
+ a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */
+ /*
+ prom contains the register address for FPGA and EEPROM programming
+ */
+ a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
+}
+
/*
** BAR0 - MEM - 0x100 - CONFIG MEM
** BAR1 - I/O - 0x100 - UNUSED
@@ -110,11 +144,11 @@ static int _4bri_is_rev_2_bri_card(int card_ordinal)
int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
{
int bar, i;
+ byte *p;
PADAPTER_LIST_ENTRY quadro_list;
diva_os_xdi_adapter_t *diva_current;
diva_os_xdi_adapter_t *adapter_list[4];
PISDN_ADAPTER Slave;
- dword offset;
unsigned long bar_length[sizeof(_4bri_bar_length) /
sizeof(_4bri_bar_length[0])];
int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
@@ -142,7 +176,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
have to map any BAR before we can access it
*/
if (!_4bri_get_serial_number(a)) {
- DBG_ERR(("A: 4BRI can't ger Serial Number"))
+ DBG_ERR(("A: 4BRI can't get Serial Number"))
diva_4bri_cleanup_adapter(a);
return (-1);
}
@@ -190,7 +224,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
for (bar = 0; bar < 4; bar++) {
if (bar != 1) { /* ignore I/O */
a->resources.pci.addr[bar] =
- divasa_remap_pci_bar(a->resources.pci.bar[bar],
+ divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
bar_length[bar]);
if (!a->resources.pci.addr[bar]) {
DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
@@ -205,14 +239,15 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
*/
sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
- if (diva_os_register_io_port(1, a->resources.pci.bar[1],
- bar_length[1], &a->port_name[0])) {
+ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
+ bar_length[1], &a->port_name[0], 1)) {
DBG_ERR(("A: 4BRI: can't register bar[1]"))
diva_4bri_cleanup_adapter(a);
return (-1);
}
- a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
+ a->resources.pci.addr[1] =
+ (void *) (unsigned long) a->resources.pci.bar[1];
/*
Set cleanup pointer for base adapter only, so slave adapter
@@ -265,8 +300,8 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
(PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
if (!(a->slave_list = quadro_list)) {
for (i = 0; i < (tasks - 1); i++) {
- diva_os_free(0, a->slave_adapters[bar]);
- a->slave_adapters[bar] = 0;
+ diva_os_free(0, a->slave_adapters[i]);
+ a->slave_adapters[i] = 0;
}
diva_4bri_cleanup_adapter(a);
return (-1);
@@ -359,60 +394,39 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
prepare_qBri_functions(&a->xdi_adapter);
}
+ for (i = 0; i < tasks; i++) {
+ diva_current = adapter_list[i];
+ if (i)
+ memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
+ diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
+ }
+
/*
Set up hardware related pointers
*/
a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0]; /* BAR0 CONFIG */
a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1 */
- a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */
- a->xdi_adapter.ctlReg =
- (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
-
- a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
- a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */
- /*
- ctlReg contains the register address for the MIPS CPU reset control
- */
- a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */
- /*
- prom contains the register address for FPGA and EEPROM programming
- */
- a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
- /*
- reset contains the base address for the PLX 9054 register set
- */
- a->xdi_adapter.reset[PLX9054_INTCSR] = 0x00; /* disable PCI interrupts */
+ a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
- /*
- Replicate addresses to all instances, set shared memory
- address for all instances
- */
for (i = 0; i < tasks; i++) {
+ diva_current = adapter_list[i];
+ diva_4bri_set_addresses(diva_current);
Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
- offset =
- Slave->ControllerNumber *
- (a->xdi_adapter.MemorySize >> factor);
- Slave->Address = &a->xdi_adapter.Address[offset];
- Slave->ram = &a->xdi_adapter.ram[offset];
- Slave->reset = a->xdi_adapter.reset;
- Slave->ctlReg = a->xdi_adapter.ctlReg;
- Slave->prom = a->xdi_adapter.prom;
- Slave->reset = a->xdi_adapter.reset;
+ Slave->MultiMaster = &a->xdi_adapter;
Slave->sdram_bar = a->xdi_adapter.sdram_bar;
- }
- for (i = 0; i < tasks; i++) {
- Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
- Slave->ram +=
- ((a->xdi_adapter.MemorySize >> factor) -
- MQ_SHARED_RAM_SIZE);
- }
- for (i = 1; i < tasks; i++) {
- Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
- Slave->serialNo =
- ((dword) (Slave->ControllerNumber << 24)) | a->
- xdi_adapter.serialNo;
+ if (i) {
+ Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
+ a->xdi_adapter.serialNo;
Slave->cardType = a->xdi_adapter.cardType;
}
+ }
+
+ /*
+ reset contains the base address for the PLX 9054 register set
+ */
+ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
+ p[PLX9054_INTCSR] = 0x00; /* disable PCI interrupts */
+ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
/*
Set IRQ handler
@@ -484,8 +498,7 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
if (bar != 1) {
if (a->resources.pci.bar[bar]
&& a->resources.pci.addr[bar]) {
- divasa_unmap_pci_bar(a->resources.pci.
- addr[bar]);
+ divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
a->resources.pci.bar[bar] = 0;
a->resources.pci.addr[bar] = 0;
}
@@ -496,12 +509,12 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
Unregister I/O
*/
if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
- diva_os_register_io_port(0, a->resources.pci.bar[1],
+ diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
_4bri_is_rev_2_card(a->
CardOrdinal) ?
_4bri_v2_bar_length[1] :
_4bri_bar_length[1],
- &a->port_name[0]);
+ &a->port_name[0], 1);
a->resources.pci.bar[1] = 0;
a->resources.pci.addr[1] = 0;
}
@@ -776,23 +789,18 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
a->xdi_mbox.
data_length);
if (a->xdi_mbox.data) {
- byte *src =
- a->xdi_adapter.Address;
- byte *dst =
- a->xdi_mbox.data;
- dword len =
- a->xdi_mbox.
- data_length;
-
- src +=
- cmd->command_data.
- read_sdram.offset;
+ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
+ byte *src = p;
+ byte *dst = a->xdi_mbox.data;
+ dword len = a->xdi_mbox.data_length;
+
+ src += cmd->command_data.read_sdram.offset;
while (len--) {
*dst++ = *src++;
}
- a->xdi_mbox.status =
- DIVA_XDI_MBOX_BUSY;
+ DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
+ a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
ret = 0;
}
}
@@ -903,10 +911,12 @@ diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
dword address,
const byte * data, dword length, dword limit)
{
- byte *mem = IoAdapter->Address;
+ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ byte *mem = p;
if (((address + length) >= limit) || !mem) {
- DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
+ DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
IoAdapter->ANum, address + length))
return (-1);
}
@@ -916,6 +926,7 @@ diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
*mem++ = *data++;
}
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
return (0);
}
@@ -926,16 +937,18 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
volatile word *signature;
int started = 0;
int i;
+ byte *p;
/*
start adapter
*/
start_qBri_hardware(IoAdapter);
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
/*
wait for signature in shared memory (max. 3 seconds)
*/
- signature = (volatile word *) (&IoAdapter->ram[0x1E]);
+ signature = (volatile word *) (&p[0x1E]);
for (i = 0; i < 300; ++i) {
diva_os_wait(10);
@@ -958,10 +971,12 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
IoAdapter->Properties.Name,
READ_WORD(&signature[0])))
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
(*(IoAdapter->trapFnc)) (IoAdapter);
IoAdapter->stop(IoAdapter);
return (-1);
}
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
for (i = 0; i < IoAdapter->tasks; i++) {
IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
@@ -997,13 +1012,16 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
#ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
int i;
ADAPTER *a = &IoAdapter->a;
+ byte *p;
IoAdapter->IrqCount = 0;
if (IoAdapter->ControllerNumber > 0)
return (-1);
- IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
/*
interrupt test
*/
@@ -1015,20 +1033,23 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
return ((IoAdapter->IrqCount > 0) ? 0 : -1);
#else
dword volatile *qBriIrq;
+ byte *p;
/*
Reset on-board interrupt register
*/
IoAdapter->IrqCount = 0;
- qBriIrq =
- (dword volatile *) (&IoAdapter->
- ctlReg[_4bri_is_rev_2_card
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriIrq = (dword volatile *) (&p[_4bri_is_rev_2_card
(IoAdapter->
cardType) ? (MQ2_BREG_IRQ_TEST)
: (MQ_BREG_IRQ_TEST)]);
WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
- IoAdapter->reset[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ p[PLX9054_INTCSR] = PLX9054_INT_ENABLE;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
diva_os_wait(100);
diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c
index 586f9df5c569..0ca31608ec15 100644
--- a/drivers/isdn/hardware/eicon/os_bri.c
+++ b/drivers/isdn/hardware/eicon/os_bri.c
@@ -1,4 +1,4 @@
-/* $Id: os_bri.c,v 1.1.2.2 2001/02/12 20:23:46 armin Exp $ */
+/* $Id: os_bri.c,v 1.18 2003/06/21 17:10:29 schindler Exp $ */
#include "platform.h"
#include "debuglib.h"
@@ -46,6 +46,27 @@ static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
dword start_address, dword features);
static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);
+static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
+{
+ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
+ a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
+ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
+ a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
+
+ a->xdi_adapter.ram = a->resources.pci.addr[0];
+ a->xdi_adapter.cfg = a->resources.pci.addr[1];
+ a->xdi_adapter.Address = a->resources.pci.addr[2];
+
+ a->xdi_adapter.reset = a->xdi_adapter.cfg;
+ a->xdi_adapter.port = a->xdi_adapter.Address;
+
+ a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
+
+ a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
+}
+
/*
** BAR0 - MEM Addr - 0x80 - NOT USED
** BAR1 - I/O Addr - 0x80
@@ -58,6 +79,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
word cmd = 0, cmd_org;
byte Bus, Slot;
void *hdev;
+ byte *p;
/*
Set properties
@@ -123,7 +145,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
Map and register resources
*/
if (!(a->resources.pci.addr[0] =
- divasa_remap_pci_bar(a->resources.pci.bar[0],
+ divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
bri_bar_length[0]))) {
DBG_ERR(("A: BRI, can't map BAR[0]"))
diva_bri_cleanup_adapter(a);
@@ -133,8 +155,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
sprintf(&a->port_name[0], "BRI %02x:%02x",
a->resources.pci.bus, a->resources.pci.func);
- if (diva_os_register_io_port(1, a->resources.pci.bar[1],
- bri_bar_length[1], &a->port_name[0])) {
+ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
+ bri_bar_length[1], &a->port_name[0], 1)) {
DBG_ERR(("A: BRI, can't register BAR[1]"))
diva_bri_cleanup_adapter(a);
return (-1);
@@ -142,8 +164,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
a->resources.pci.length[1] = bri_bar_length[1];
- if (diva_os_register_io_port(1, a->resources.pci.bar[2],
- bar2_length, &a->port_name[0])) {
+ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
+ bar2_length, &a->port_name[0], 2)) {
DBG_ERR(("A: BRI, can't register BAR[2]"))
diva_bri_cleanup_adapter(a);
return (-1);
@@ -152,6 +174,11 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
a->resources.pci.length[2] = bar2_length;
/*
+ Set all memory areas
+ */
+ diva_bri_set_addresses(a);
+
+ /*
Get Serial Number
*/
a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
@@ -210,15 +237,9 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
a->interface.cmd_proc = diva_bri_cmd_card_proc;
- a->xdi_adapter.cfg = a->resources.pci.addr[1];
- a->xdi_adapter.Address = a->resources.pci.addr[2];
-
- a->xdi_adapter.reset = a->xdi_adapter.cfg;
- a->xdi_adapter.port = a->xdi_adapter.Address;
-
- a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
- a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
- outpp(a->xdi_adapter.reset, 0x41);
+ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
+ outpp(p, 0x41);
+ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
prepare_maestra_functions(&a->xdi_adapter);
@@ -268,11 +289,11 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
for (i = 1; i < 3; i++) {
if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
- diva_os_register_io_port(0,
+ diva_os_register_io_port(a, 0,
a->resources.pci.bar[i],
a->resources.pci.
length[i],
- &a->port_name[0]);
+ &a->port_name[0], i);
a->resources.pci.addr[i] = 0;
a->resources.pci.bar[i] = 0;
}
@@ -314,18 +335,20 @@ static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a)
byte *confIO;
word serHi, serLo, *confMem;
- confIO = (byte *) a->resources.pci.addr[1];
+ confIO = (byte *) DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
serNo = ((dword) serHi << 16) | (dword) serLo;
+ DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
- confMem = (word *) a->resources.pci.addr[0];
+ confMem = (word *) DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
serNo = (((dword) serHi) << 16) | ((dword) serLo);
+ DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
}
DBG_LOG(("Serial Number=%ld", serNo))
@@ -342,9 +365,9 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
int i;
for (i = 1; i < 3; i++) {
- diva_os_register_io_port(0, a->resources.pci.bar[i],
+ diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
a->resources.pci.length[i],
- &a->port_name[0]);
+ &a->port_name[0], i);
a->resources.pci.addr[i] = 0;
}
@@ -352,9 +375,9 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
(long) a->xdi_adapter.serialNo);
for (i = 1; i < 3; i++) {
- if (diva_os_register_io_port(1, a->resources.pci.bar[i],
+ if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
a->resources.pci.length[i],
- &a->port_name[0])) {
+ &a->port_name[0], i)) {
DBG_ERR(("A: failed to reregister BAR[%d]", i))
return (-1);
}
@@ -493,6 +516,7 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
{
byte *addrHi, *addrLo, *ioaddr;
dword i;
+ byte *Port;
if (!IoAdapter->port) {
return (-1);
@@ -501,13 +525,13 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
IoAdapter->ANum)) return (-1);
}
- addrHi =
- IoAdapter->port +
- ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = IoAdapter->port + ADDR;
- ioaddr = IoAdapter->port + DATA;
(*(IoAdapter->rstFnc)) (IoAdapter);
diva_os_wait(100);
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port +
+ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+ addrLo = Port + ADDR;
+ ioaddr = Port + DATA;
/*
recover
*/
@@ -540,6 +564,8 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
outppw(addrLo, (word) 0);
outppw(ioaddr, (word) 0);
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+
/*
Forget all outstanding entities
*/
@@ -578,16 +604,17 @@ diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
dword address, const byte * data, dword length)
{
byte *addrHi, *addrLo, *ioaddr;
+ byte *Port;
if (!IoAdapter->port) {
return (-1);
}
- addrHi =
- IoAdapter->port +
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port +
((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = IoAdapter->port + ADDR;
- ioaddr = IoAdapter->port + DATA;
+ addrLo = Port + ADDR;
+ ioaddr = Port + DATA;
while (length--) {
outpp(addrHi, (word) (address >> 16));
@@ -596,6 +623,7 @@ diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
address++;
}
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
return (0);
}
@@ -603,6 +631,7 @@ static int
diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
dword start_address, dword features)
{
+ byte *Port;
dword i, test;
byte *addrHi, *addrLo, *ioaddr;
int started = 0;
@@ -621,11 +650,11 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
- addrHi =
- IoAdapter->port +
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port +
((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = IoAdapter->port + ADDR;
- ioaddr = IoAdapter->port + DATA;
+ addrLo = Port + ADDR;
+ ioaddr = Port + DATA;
outpp(addrHi,
(byte) (
@@ -633,12 +662,20 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
BRI_SHARED_RAM_SIZE) >> 16));
outppw(addrLo, 0x1e);
outppw(ioaddr, 0x00);
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
/*
start the protocol code
*/
- outpp(IoAdapter->ctlReg, 0x08);
+ Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ outpp(Port, 0x08);
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port +
+ ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+ addrLo = Port + ADDR;
+ ioaddr = Port + DATA;
/*
wait for signature (max. 3 seconds)
*/
@@ -659,6 +696,7 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
break;
}
}
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
if (!started) {
DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
@@ -677,7 +715,9 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
a->ReadyInt = 1;
if (IoAdapter->reset) {
- outpp(IoAdapter->reset, 0x41);
+ Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ outpp(Port, 0x41);
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
}
a->ram_out(a, &PR_RAM->ReadyInt, 1);
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
index 1f746bfe7d72..cab364b74f33 100644
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ b/drivers/isdn/hardware/eicon/os_pri.c
@@ -1,4 +1,4 @@
-/* $Id: os_pri.c,v 1.1.2.3 2001/02/14 21:10:19 armin Exp $ */
+/* $Id: os_pri.c,v 1.29 2003/08/25 13:41:27 schindler Exp $ */
#include "platform.h"
#include "debuglib.h"
@@ -57,6 +57,34 @@ static int pri_is_rev_2_card(int card_ordinal)
return (0);
}
+static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
+{
+ a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
+ a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
+ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
+ a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
+ a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
+ a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
+
+ a->xdi_adapter.Address = a->resources.pci.addr[0];
+ a->xdi_adapter.Control = a->resources.pci.addr[2];
+ a->xdi_adapter.Config = a->resources.pci.addr[4];
+
+ a->xdi_adapter.ram = a->resources.pci.addr[0];
+ a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
+
+ a->xdi_adapter.reset = a->resources.pci.addr[2];
+ a->xdi_adapter.reset += MP_RESET;
+
+ a->xdi_adapter.cfg = a->resources.pci.addr[4];
+ a->xdi_adapter.cfg += MP_IRQ_RESET;
+
+ a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
+
+ a->xdi_adapter.prom = a->resources.pci.addr[3];
+}
+
/*
** BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
** BAR1 - DEVICES, 0x1000
@@ -117,7 +145,7 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
*/
for (bar = 0; bar < 5; bar++) {
a->resources.pci.addr[bar] =
- divasa_remap_pci_bar(a->resources.pci.bar[bar],
+ divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
bar_length[bar]);
if (!a->resources.pci.addr[bar]) {
DBG_ERR(("A: A(%d), can't map bar[%d]",
@@ -128,6 +156,11 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
}
/*
+ Set all memory areas
+ */
+ diva_pri_set_addresses(a);
+
+ /*
Get Serial Number of this adapter
*/
if (pri_get_serial_number(a)) {
@@ -194,23 +227,6 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
prepare_pri_functions(&a->xdi_adapter);
}
- /*
- Set all memory areas
- */
- a->xdi_adapter.Address = a->resources.pci.addr[0];
- a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
- a->xdi_adapter.ram = a->resources.pci.addr[0];
- a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
-
- a->xdi_adapter.reset = a->resources.pci.addr[2];
- a->xdi_adapter.reset += MP_RESET;
-
- a->xdi_adapter.prom =
- (byte *) (unsigned long) a->resources.pci.bar[3];
-
- a->xdi_adapter.cfg = a->resources.pci.addr[4];
- a->xdi_adapter.cfg += MP_IRQ_RESET;
-
a->dsp_mask = diva_pri_detect_dsps(a);
/*
@@ -317,7 +333,7 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
{
dword i;
- struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
+ struct mp_load *boot;
if (!IoAdapter->Address || !IoAdapter->reset) {
return (-1);
@@ -328,12 +344,20 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
return (-1);
}
+ boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
WRITE_DWORD(&boot->err, 0);
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+
IoAdapter->rstFnc(IoAdapter);
+
diva_os_wait(10);
+
+ boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
i = READ_DWORD(&boot->live);
+
diva_os_wait(10);
if (i == READ_DWORD(&boot->live)) {
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
IoAdapter->ANum, IoAdapter->serialNo))
return (-1);
@@ -342,8 +366,10 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
IoAdapter->ANum, IoAdapter->serialNo,
READ_DWORD(&boot->err)))
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
return (-1);
}
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
/*
Forget all outstanding entities
@@ -383,9 +409,11 @@ diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
dword address,
const byte * data, dword length, dword limit)
{
- byte *mem = IoAdapter->Address;
+ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+ byte *mem = p;
if (((address + length) >= limit) || !mem) {
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
IoAdapter->ANum, address + length))
return (-1);
@@ -396,6 +424,7 @@ diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
*mem++ = *data++;
}
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
return (0);
}
@@ -405,15 +434,18 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
{
dword i;
int started = 0;
- struct mp_load *boot = (struct mp_load *) IoAdapter->Address;
+ byte *p;
+ struct mp_load *boot = (struct mp_load *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
ADAPTER *a = &IoAdapter->a;
if (IoAdapter->Initialized) {
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
IoAdapter->ANum))
return (-1);
}
if (!boot) {
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
IoAdapter->serialNo))
return (-1);
@@ -437,17 +469,22 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
}
if (!started) {
- dword TrapId = READ_DWORD(&IoAdapter->Address[0x80]);
- dword debug = READ_DWORD(&IoAdapter->Address[0x1c]);
+ byte *p = (byte *)boot;
+ dword TrapId;
+ dword debug;
+ TrapId = READ_DWORD(&p[0x80]);
+ debug = READ_DWORD(&p[0x1c]);
DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
IoAdapter->ANum, READ_DWORD(&boot->signature),
TrapId, debug))
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
if (IoAdapter->trapFnc) {
(*(IoAdapter->trapFnc)) (IoAdapter);
}
IoAdapter->stop(IoAdapter);
return (-1);
}
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
IoAdapter->Initialized = TRUE;
@@ -455,8 +492,9 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
Check Interrupt
*/
IoAdapter->IrqCount = 0;
- WRITE_DWORD(((dword volatile *) IoAdapter->cfg),
- (dword) ~ 0x03E00000);
+ p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+ WRITE_DWORD(((dword volatile *) p), (dword) ~ 0x03E00000);
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
a->ReadyInt = 1;
a->ram_out(a, &PR_RAM->ReadyInt, 1);
@@ -658,7 +696,8 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
diva_os_malloc(0, a->xdi_mbox.data_length);
if (a->xdi_mbox.data) {
dword *data = (dword *) a->xdi_mbox.data;
- if (!a->xdi_adapter.ram || !a->xdi_adapter.reset ||
+ if (!a->xdi_adapter.ram ||
+ !a->xdi_adapter.reset ||
!a->xdi_adapter.cfg) {
*data = 3;
} else if (a->xdi_adapter.trapped) {
@@ -691,23 +730,18 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
a->xdi_mbox.
data_length);
if (a->xdi_mbox.data) {
- byte *src =
- a->xdi_adapter.Address;
- byte *dst =
- a->xdi_mbox.data;
- dword len =
- a->xdi_mbox.
- data_length;
-
- src +=
- cmd->command_data.
- read_sdram.offset;
+ byte *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
+ byte *src = p;
+ byte *dst = a->xdi_mbox.data;
+ dword len = a->xdi_mbox.data_length;
+
+ src += cmd->command_data.read_sdram.offset;
while (len--) {
*dst++ = *src++;
}
- a->xdi_mbox.status =
- DIVA_XDI_MBOX_BUSY;
+ a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
+ DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
ret = 0;
}
}
@@ -731,27 +765,33 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
byte data[64];
int i;
dword len = sizeof(data);
- volatile byte *config = (byte *) a->resources.pci.addr[4];
- volatile byte *flash = (byte *) a->resources.pci.addr[3];
+ volatile byte *config;
+ volatile byte *flash;
/*
* First set some GT6401x config registers before accessing the BOOT-ROM
*/
+ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
if (!(config[0xc3c] & 0x08)) {
config[0xc3c] |= 0x08; /* Base Address enable register */
}
config[LOW_BOOTCS_DREG] = 0x00;
config[HI_BOOTCS_DREG] = 0xFF;
+ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
/*
* Read only the last 64 bytes of manufacturing data
*/
memset(data, '\0', len);
+ flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
for (i = 0; i < len; i++) {
data[i] = flash[0x8000 - len + i];
}
+ DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
+ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
config[LOW_BOOTCS_DREG] = 0xFC; /* Disable FLASH EPROM access */
config[HI_BOOTCS_DREG] = 0xFF;
+ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
if (memcmp(&data[48], "DIVAserverPR", 12)) {
#if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */
@@ -791,22 +831,26 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
/*
Try to read Flash again
*/
- config = (byte *) a->resources.pci.addr[4];
- flash = (byte *) a->resources.pci.addr[3];
len = sizeof(data);
+ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
if (!(config[0xc3c] & 0x08)) {
config[0xc3c] |= 0x08; /* Base Address enable register */
}
config[LOW_BOOTCS_DREG] = 0x00;
config[HI_BOOTCS_DREG] = 0xFF;
+ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
memset(data, '\0', len);
+ flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
for (i = 0; i < len; i++) {
data[i] = flash[0x8000 - len + i];
}
+ DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
+ config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
config[LOW_BOOTCS_DREG] = 0xFC;
config[HI_BOOTCS_DREG] = 0xFF;
+ DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
if (memcmp(&data[48], "DIVAserverPR", 12)) {
DBG_ERR(("A: failed to read serial number"))
@@ -907,7 +951,8 @@ dsp_check_presence(volatile byte * addr, volatile byte * data, int dsp)
*/
static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
{
- byte *base = a->resources.pci.addr[2];
+ byte *base;
+ byte *p;
dword ret = 0;
dword row_offset[7] = {
0x00000000,
@@ -921,14 +966,17 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
byte *dsp_addr_port, *dsp_data_port, row_state;
int dsp_row = 0, dsp_index, dsp_num;
- if (!base || !a->xdi_adapter.reset) {
+ if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
return (0);
}
- *(volatile byte *) (a->xdi_adapter.reset) =
- _MP_RISC_RESET | _MP_DSP_RESET;
+ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
+ *(volatile byte *) p = _MP_RISC_RESET | _MP_DSP_RESET;
+ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
diva_os_wait(5);
+ base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
+
for (dsp_num = 0; dsp_num < 30; dsp_num++) {
dsp_row = dsp_num / 7 + 1;
dsp_index = dsp_num % 7;
@@ -947,9 +995,11 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
ret |= (1 << dsp_num);
}
}
+ DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
- *(volatile byte *) (a->xdi_adapter.reset) =
- _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
+ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
+ *(volatile byte *) p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
+ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
diva_os_wait(5);
/*
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index bfb939de6c88..4f9bc1d34275 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -1,9 +1,9 @@
-/* $Id: platform.h,v 1.1.2.6 2001/05/01 15:48:05 armin Exp $
+/* $Id: platform.h,v 1.31 2003/09/08 15:15:22 schindler Exp $
*
* platform.h
*
*
- * Copyright 2000-2002 by Armin Schindler (mac@melware.de)
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
* Copyright 2000 Eicon Networks
*
* This software may be used and distributed according to the terms
@@ -23,20 +23,27 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/skbuff.h>
+#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
+#include <linux/delay.h>
#include <asm/types.h>
#include <asm/io.h>
#include "cardtype.h"
+/* activate debuglib for modules only */
+#ifndef MODULE
+#define DIVA_NO_DEBUGLIB
+#endif
+
#define DIVA_INIT_FUNCTION __init
#define DIVA_EXIT_FUNCTION __exit
#define DIVA_USER_MODE_CARD_CONFIG 1
-#define XDI_USE_XLOG 1
#define USE_EXTENDED_DEBUGS 1
#define MAX_ADAPTER 32
@@ -46,11 +53,6 @@
#define MEMORY_SPACE_TYPE 0
#define PORT_SPACE_TYPE 1
-#include "debuglib.h"
-
-#define dtrc(p) DBG_PRV0(p)
-#define dbug(a,p) DBG_PRV1(p)
-
#include <linux/string.h>
@@ -106,6 +108,36 @@
#define _cdecl
#endif
+#define MEM_TYPE_RAM 0
+#define MEM_TYPE_PORT 1
+#define MEM_TYPE_PROM 2
+#define MEM_TYPE_CTLREG 3
+#define MEM_TYPE_RESET 4
+#define MEM_TYPE_CFG 5
+#define MEM_TYPE_ADDRESS 6
+#define MEM_TYPE_CONFIG 7
+#define MEM_TYPE_CONTROL 8
+
+#define DIVA_OS_MEM_ATTACH_RAM(a) ((a)->ram)
+#define DIVA_OS_MEM_ATTACH_PORT(a) ((a)->port)
+#define DIVA_OS_MEM_ATTACH_PROM(a) ((a)->prom)
+#define DIVA_OS_MEM_ATTACH_CTLREG(a) ((a)->ctlReg)
+#define DIVA_OS_MEM_ATTACH_RESET(a) ((a)->reset)
+#define DIVA_OS_MEM_ATTACH_CFG(a) ((a)->cfg)
+#define DIVA_OS_MEM_ATTACH_ADDRESS(a) ((a)->Address)
+#define DIVA_OS_MEM_ATTACH_CONFIG(a) ((a)->Config)
+#define DIVA_OS_MEM_ATTACH_CONTROL(a) ((a)->Control)
+
+#define DIVA_OS_MEM_DETACH_RAM(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_CTLREG(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_RESET(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_CFG(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_ADDRESS(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while(0)
+#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while(0)
+
#if !defined(DIM)
#define DIM(array) (sizeof (array)/sizeof ((array)[0]))
#endif
@@ -124,7 +156,11 @@ typedef struct _ISDN_ADAPTER ISDN_ADAPTER;
typedef struct _ISDN_ADAPTER* PISDN_ADAPTER;
typedef void (* DIVA_DI_PRINTF) (unsigned char *, ...);
-extern DIVA_DI_PRINTF dprintf;
+#include "debuglib.h"
+
+#define dtrc(p) DBG_PRV0(p)
+#define dbug(a,p) DBG_PRV1(p)
+
typedef struct e_info_s E_INFO ;
@@ -146,8 +182,21 @@ void diva_xdi_didd_remove_adapter (int card);
/*
** memory allocation
*/
-void* diva_os_malloc (unsigned long flags, unsigned long size);
-void diva_os_free (unsigned long flags, void* ptr);
+static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size)
+{
+ void *ret = NULL;
+
+ if (size) {
+ ret = (void *) vmalloc((unsigned int) size);
+ }
+ return (ret);
+}
+static __inline__ void diva_os_free (unsigned long flags, void* ptr)
+{
+ if (ptr) {
+ vfree(ptr);
+ }
+}
/*
** use skbuffs for message buffer
@@ -161,8 +210,17 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb);
/*
** mSeconds waiting
*/
-void diva_os_sleep(dword mSec);
-void diva_os_wait(dword mSec);
+static __inline__ void diva_os_sleep(dword mSec)
+{
+ unsigned long timeout = HZ * mSec / 1000 + 1;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(timeout);
+}
+static __inline__ void diva_os_wait(dword mSec)
+{
+ mdelay(mSec);
+}
/*
** PCI Configuration space access
@@ -173,8 +231,8 @@ void PCIread (byte bus, byte func, int offset, void* data, int length, void* pci
/*
** I/O Port utilities
*/
-int diva_os_register_io_port (int register, unsigned long port, unsigned long length, const char* name);
-
+int diva_os_register_io_port (void *adapter, int register, unsigned long port,
+ unsigned long length, const char* name, int id);
/*
** I/O port access abstraction
*/
@@ -199,14 +257,6 @@ void diva_os_remove_irq (void* context, byte irq);
#define diva_os_in_irq() in_irq()
/*
-** module locking
-*/
-/*
-#define DIVA_LOCK_MODULE MOD_INC_USE_COUNT
-#define DIVA_UNLOCK_MODULE MOD_DEC_USE_COUNT
-*/
-
-/*
** Spin Lock framework
*/
typedef long diva_os_spin_lock_magic_t;
diff --git a/drivers/isdn/hardware/eicon/s_4bri.c b/drivers/isdn/hardware/eicon/s_4bri.c
index 62d089d4b739..b869651daeed 100644
--- a/drivers/isdn/hardware/eicon/s_4bri.c
+++ b/drivers/isdn/hardware/eicon/s_4bri.c
@@ -55,8 +55,8 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
* check for trapped MIPS 46xx CPU, dump exception frame
*/
+ base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
- base = IoAdapter->ram - offset - ((IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE) ;
TrapID = READ_DWORD(&base[0x80]) ;
@@ -75,8 +75,10 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
if ( (regs[0] >= offset)
&& (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) )
{
- if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
+ if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
+ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
return ;
+ }
size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ;
if ( size > MAX_XLOG_SIZE )
@@ -89,7 +91,7 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
diva_os_free (0, Xlog) ;
IoAdapter->trapped = 2 ;
}
-
+ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
}
/* --------------------------------------------------------------------------
@@ -97,10 +99,10 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
-------------------------------------------------------------------------- */
static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
word volatile *qBriReset ;
- dword volatile *qBriCntrl ;
+ byte volatile *qBriCntrl ;
+ byte volatile *p ;
- qBriReset = (word volatile *)IoAdapter->prom ;
- qBriCntrl = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
+ qBriReset = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ;
diva_os_wait (1) ;
WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ;
@@ -109,34 +111,40 @@ static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
diva_os_wait (1) ;
WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ;
diva_os_wait (1);
+ DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
- WRITE_DWORD(qBriCntrl, 0) ;
+ qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
+ WRITE_DWORD(p, 0) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
- DBG_TRC(("resetted board @ cntrl addr 0x%08lx", qBriCntrl))
-
+ DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
}
/* --------------------------------------------------------------------------
Start Card CPU
-------------------------------------------------------------------------- */
void start_qBri_hardware (PISDN_ADAPTER IoAdapter) {
- dword volatile *qBriReset ;
+ byte volatile *qBriReset ;
+ byte volatile *p ;
- qBriReset = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]);
+ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ;
diva_os_wait (2) ;
WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ;
diva_os_wait (10) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
-
}
/* --------------------------------------------------------------------------
Stop Card CPU
-------------------------------------------------------------------------- */
static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+ byte volatile *p ;
dword volatile *qBriReset ;
dword volatile *qBriIrq ;
dword volatile *qBriIsacDspReset ;
@@ -147,16 +155,24 @@ static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
if ( IoAdapter->ControllerNumber > 0 )
return ;
- qBriReset = (dword volatile *)(&IoAdapter->ctlReg[reset_offset]) ;
- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[irq_offset]) ;
- qBriIsacDspReset = (dword volatile *)(&IoAdapter->ctlReg[hw_offset]);
+ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriReset = (dword volatile *)&p[reset_offset];
+ qBriIsacDspReset = (dword volatile *)&p[hw_offset];
/*
* clear interrupt line (reset Local Interrupt Test Register)
*/
WRITE_DWORD(qBriReset, 0) ;
WRITE_DWORD(qBriIsacDspReset, 0) ;
- IoAdapter->reset[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+
+ p = (byte volatile *)DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ p[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+
+ p = (byte volatile *)DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriIrq = (dword volatile *)&p[irq_offset];
WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
@@ -260,7 +276,7 @@ int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
int bit ;
byte *File ;
dword code, FileLength ;
- word volatile *addr = (word volatile *)IoAdapter->prom ;
+ word volatile *addr = (word volatile *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
word val, baseval = FPGA_CS | FPGA_PROG ;
@@ -291,8 +307,10 @@ int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit",
&FileLength, &code) ;
}
- if ( !File )
+ if ( !File ) {
+ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
return (0) ;
+ }
/*
* prepare download, pulse PROGRAM pin down.
*/
@@ -306,6 +324,7 @@ int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
{
DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
xdiFreeFile (File) ;
+ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
return (0) ;
}
/*
@@ -329,6 +348,8 @@ int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
diva_os_wait (100) ;
val = READ_WORD(addr) ;
+ DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
+
if ( !(val & FPGA_BUSY) )
{
DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
@@ -343,12 +364,10 @@ int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
Download protocol code to the adapter
-------------------------------------------------------------------------- */
-#define DOWNLOAD_ADDR(IoAdapter) (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
-
-
static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdapter) {
PISDN_ADAPTER HighIoAdapter;
+ byte *p;
dword FileLength ;
dword *sharedRam, *File;
dword Addr, ProtOffset, SharedRamOffset, i;
@@ -436,7 +455,8 @@ static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdap
return (0) ;
}
IoAdapter->downloadAddr = 0 ;
- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ sharedRam = (dword *)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
memcpy (sharedRam, File, FileLength) ;
DBG_TRC(("Download addr 0x%08x len %ld - virtual 0x%08x",
@@ -449,10 +469,12 @@ static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdap
DBG_FTL(("File=0x%x, sharedRam=0x%x", File, sharedRam))
DBG_BLK(( (char *)File, 256))
DBG_BLK(( (char *)sharedRam, 256))
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
xdiFreeFile (File) ;
return (0) ;
}
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
xdiFreeFile (File) ;
return (1) ;
@@ -466,6 +488,7 @@ static long qBri_download_buffer (OsFileHandle *fp, long length, void **addr) {
PISDN_ADAPTER IoAdapter;
word i ;
dword *sharedRam ;
+ byte *p;
i = 0 ;
@@ -485,12 +508,14 @@ static long qBri_download_buffer (OsFileHandle *fp, long length, void **addr) {
IoAdapter->downloadAddr + length))
return (-1) ;
}
- sharedRam = (dword*)(&BaseIoAdapter->ram[IoAdapter->downloadAddr &
- (IoAdapter->MemorySize - 1)]) ;
-
+ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
+ sharedRam = (dword*)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
- if ( fp->sysFileRead (fp, sharedRam, length) != length )
+ if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
return (-1) ;
+ }
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
IoAdapter->downloadAddr += length ;
IoAdapter->downloadAddr = (IoAdapter->downloadAddr + 3) & (~3) ;
@@ -509,6 +534,7 @@ static dword qBri_telindus_load (PISDN_ADAPTER BaseIoAdapter) {
word download_count, i ;
dword *sharedRam ;
dword FileLength ;
+ byte *p;
if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) ) {
DBG_FTL(("qBri_telindus_load: %s not found!", DSP_TELINDUS_FILE))
@@ -553,8 +579,8 @@ static dword qBri_telindus_load (PISDN_ADAPTER BaseIoAdapter) {
* store # of download files extracted from the archive and download table
*/
HighIoAdapter->downloadAddr = HighIoAdapter->DspCodeBaseAddr ;
- sharedRam = (dword *)(&BaseIoAdapter->ram[HighIoAdapter->downloadAddr &
- (IoAdapter->MemorySize - 1)]) ;
+ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
+ sharedRam = (dword *)&p[HighIoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
@@ -563,6 +589,7 @@ static dword qBri_telindus_load (PISDN_ADAPTER BaseIoAdapter) {
if ( memcmp (&sharedRam[1], &download_table, download_count) ) {
DBG_FTL(("%s: Dsp Memory test failed!", IoAdapter->Properties.Name))
}
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
return (FileLength) ;
}
@@ -588,6 +615,7 @@ static byte* qBri_sdp_load (PISDN_ADAPTER BaseIoAdapter,
dword phys_start_addr;
dword end_addr;
byte* sharedRam = 0;
+ byte *p;
if (task) {
if (!(fp = OsOpenFile (task))) {
@@ -657,18 +685,22 @@ static byte* qBri_sdp_load (PISDN_ADAPTER BaseIoAdapter,
}
fp->sysFileSeek (fp, 0, OS_SEEK_SET);
- sharedRam = &BaseIoAdapter->ram[phys_start_addr];
+ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
+ sharedRam = &p[phys_start_addr];
if ((dword)fp->sysFileRead (fp, sharedRam, FileLength) != FileLength) {
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
OsCloseFile (fp) ;
DBG_ERR(("Can't read image [%s]", task))
return (0);
}
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
OsCloseFile (fp) ;
}
+ p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
if (!link_addr) {
- link_addr = &BaseIoAdapter->ram[OFFS_DSP_CODE_BASE_ADDR];
+ link_addr = &p[OFFS_DSP_CODE_BASE_ADDR];
}
DBG_TRC(("Write task [%s] link %08lx at %08lx",
@@ -681,6 +713,8 @@ static byte* qBri_sdp_load (PISDN_ADAPTER BaseIoAdapter,
link_addr[2] = (byte)((start_addr >> 16) & 0xff);
link_addr[3] = (byte)((start_addr >> 24) & 0xff);
+ DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
+
return (task ? &sharedRam[DIVA_MIPS_TASK_IMAGE_LINK_OFFS] : 0);
}
@@ -691,6 +725,7 @@ static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
dword i, offset, controller ;
word *signature ;
int factor = (IoAdapter->tasks == 1) ? 1 : 2;
+ byte *p;
PISDN_ADAPTER Slave ;
@@ -751,7 +786,8 @@ static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
Slave->reset = IoAdapter->reset ;
Slave->ctlReg = IoAdapter->ctlReg ;
Slave->prom = IoAdapter->prom ;
- Slave->reset = IoAdapter->reset ;
+ Slave->Config = IoAdapter->Config ;
+ Slave->Control = IoAdapter->Control ;
if ( !qBri_protocol_load (IoAdapter, Slave) )
return (0) ;
@@ -782,9 +818,11 @@ static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
{
Slave = IoAdapter->QuadroList->QuadroAdapter[i] ;
Slave->ram += (IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE ;
+ p = DIVA_OS_MEM_ATTACH_RAM(Slave);
DBG_TRC(("Configure instance %d shared memory @ 0x%08lx",
- Slave->ControllerNumber, Slave->ram))
- memset (Slave->ram, '\0', 256) ;
+ Slave->ControllerNumber, p))
+ memset (p, '\0', 256) ;
+ DIVA_OS_MEM_DETACH_RAM(Slave, p);
diva_configure_protocol (Slave);
}
@@ -792,7 +830,8 @@ static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
* start adapter
*/
start_qBri_hardware (IoAdapter) ;
- signature = (word *)(&IoAdapter->ram[0x1E]) ;
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ signature = (word *)(&p[0x1E]) ;
/*
* wait for signature in shared memory (max. 3 seconds)
*/
@@ -802,12 +841,14 @@ static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
if ( signature[0] == 0x4447 )
{
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
DBG_TRC(("Protocol startup time %d.%02d seconds",
(i / 100), (i % 100) ))
return (1) ;
}
}
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
IoAdapter->Properties.Name, signature[0] >> 16))
qBri_cpu_trapped (IoAdapter) ;
@@ -829,16 +870,23 @@ static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
word i ;
int serviced = 0 ;
+ byte *p;
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
- if ( !(IoAdapter->reset[PLX9054_INTCSR] & 0x80) )
+ if ( !(p[PLX9054_INTCSR] & 0x80) ) {
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
return (0) ;
+ }
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
/*
* clear interrupt line (reset Local Interrupt Test Register)
*/
- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
for ( i = 0 ; i < IoAdapter->tasks; ++i )
{
@@ -861,15 +909,21 @@ static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
-------------------------------------------------------------------------- */
static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
dword volatile *qBriIrq ;
+ byte *p;
if ( IoAdapter->ControllerNumber > 0 )
return ;
- qBriIrq = (dword volatile *)(&IoAdapter->ctlReg[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
/*
* clear interrupt line (reset Local Interrupt Test Register)
*/
- IoAdapter->reset[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ p[PLX9054_INTCSR] = 0x00 ; /* disable PCI interrupts */
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ qBriIrq = (dword volatile *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]);
WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
}
/* --------------------------------------------------------------------------
diff --git a/drivers/isdn/hardware/eicon/s_bri.c b/drivers/isdn/hardware/eicon/s_bri.c
index bbfba867544d..24df86bf4143 100644
--- a/drivers/isdn/hardware/eicon/s_bri.c
+++ b/drivers/isdn/hardware/eicon/s_bri.c
@@ -45,15 +45,16 @@ static void bri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
word *Xlog ;
dword regs[4], i, size ;
Xdesc xlogDesc ;
+ byte *Port;
/*
* first read pointers and trap frame
*/
if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
return ;
- addrHi = IoAdapter->port
- + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
- addrLo = IoAdapter->port + ADDR ;
- ioaddr = IoAdapter->port + DATA ;
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+ addrLo = Port + ADDR ;
+ ioaddr = Port + DATA ;
outpp (addrHi, 0) ;
outppw (addrLo, 0) ;
for ( i = 0 ; i < 0x100 ; Xlog[i++] = inppw(ioaddr) ) ;
@@ -95,21 +96,28 @@ static void bri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
outpp (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
BRI_SHARED_RAM_SIZE)) >> 16)) ;
outppw (addrLo, 0x00) ;
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
}
/* ---------------------------------------------------------------------
Reset hardware
--------------------------------------------------------------------- */
static void reset_bri_hardware (PISDN_ADAPTER IoAdapter) {
- outpp (IoAdapter->ctlReg, 0x00) ;
+ byte *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ outpp (p, 0x00) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
}
/* ---------------------------------------------------------------------
Halt system
--------------------------------------------------------------------- */
static void stop_bri_hardware (PISDN_ADAPTER IoAdapter) {
- if (IoAdapter->reset) {
- outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ if (p) {
+ outpp (p, 0x00) ; /* disable interrupts ! */
}
- outpp (IoAdapter->ctlReg, 0x00) ; /* clear int, halt cpu */
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ outpp (p, 0x00) ; /* clear int, halt cpu */
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
}
#if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
/* ---------------------------------------------------------------------
@@ -121,6 +129,7 @@ static dword bri_protocol_load (PISDN_ADAPTER IoAdapter) {
byte* addrHi, *addrLo, *ioaddr ;
char *FileName = &IoAdapter->Protocol[0] ;
dword Addr, i ;
+ byte *Port;
/* -------------------------------------------------------------------
Try to load protocol code. 'File' points to memory location
that does contain entire protocol code
@@ -173,10 +182,10 @@ static dword bri_protocol_load (PISDN_ADAPTER IoAdapter) {
DBG_FTL(("Protocol code '%s' too big (%ld)", FileName, FileLength))
return (0) ;
}
- addrHi = IoAdapter->port
- + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
- addrLo = IoAdapter->port + ADDR ;
- ioaddr = IoAdapter->port + DATA ;
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
+ addrLo = Port + ADDR ;
+ ioaddr = Port + DATA ;
/*
* set start address for download (use autoincrement mode !)
*/
@@ -204,12 +213,14 @@ static dword bri_protocol_load (PISDN_ADAPTER IoAdapter) {
test = inppw (ioaddr) ;
if ( test != File[i/2] )
{
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
DBG_FTL(("%s: Memory test failed! (%d - 0x%04X/0x%04X)",
IoAdapter->Properties.Name, i, test, File[i/2]))
xdiFreeFile (File);
return (0) ;
}
}
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
xdiFreeFile (File);
return (FileLength) ;
}
@@ -290,6 +301,7 @@ static dword bri_telindus_load (PISDN_ADAPTER IoAdapter, char *DspTelindusFile)
t_dsp_portable_desc download_table[DSP_MAX_DOWNLOAD_COUNT] ;
word download_count ;
dword FileLength ;
+ byte *Port;
if (!pinfo) {
DBG_ERR (("A: out of memory s_bri at %d", __LINE__))
return (0);
@@ -299,11 +311,11 @@ static dword bri_telindus_load (PISDN_ADAPTER IoAdapter, char *DspTelindusFile)
return (0) ;
}
FileLength = fp->sysFileSize ;
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
pinfo->IoAdapter = IoAdapter ;
- pinfo->AddrLo = IoAdapter->port + ADDR ;
- pinfo->AddrHi = IoAdapter->port +\
- (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
- pinfo->Data = (word*)(IoAdapter->port + DATA) ;
+ pinfo->AddrLo = Port + ADDR ;
+ pinfo->AddrHi = Port + (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
+ pinfo->Data = (word*)(Port + DATA) ;
pinfo->DownloadPos = (IoAdapter->DspCodeBaseAddr +\
sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
fp->sysLoadDesc = (void *)pinfo;
@@ -317,6 +329,7 @@ static dword bri_telindus_load (PISDN_ADAPTER IoAdapter, char *DspTelindusFile)
&download_count, NULL, &download_table[0]) ;
if ( error )
{
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
DBG_FTL(("download file error: %s", error))
OsCloseFile (fp) ;
diva_os_free (0, pinfo);
@@ -335,23 +348,25 @@ static dword bri_telindus_load (PISDN_ADAPTER IoAdapter, char *DspTelindusFile)
* copy download table to board
*/
outppw_buffer (pinfo->Data, &download_table[0], sizeof(download_table)) ;
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
diva_os_free (0, pinfo);
return (FileLength) ;
}
/******************************************************************************/
static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
dword i ;
- byte* addrHi, *addrLo, *ioaddr ;
+ byte* addrHi, *addrLo, *ioaddr, *p ;
dword test ;
+ byte *Port;
if ( IoAdapter->Properties.Card != CARD_MAE )
{
return (FALSE) ;
}
- addrHi = IoAdapter->port \
- + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = IoAdapter->port + ADDR ;
- ioaddr = IoAdapter->port + DATA ;
reset_bri_hardware (IoAdapter) ;
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+ addrLo = Port + ADDR ;
+ ioaddr = Port + DATA ;
diva_os_wait (100);
/*
* recover
@@ -366,6 +381,7 @@ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
outppw (addrLo, 0) ;
for ( i = 0 ; i < 0x8000 ; outppw (ioaddr, 0), ++i ) ;
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
diva_os_wait (100) ;
/*
* download protocol and dsp files
@@ -396,6 +412,11 @@ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
return (FALSE) ;
break ;
}
+
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+ addrLo = Port + ADDR ;
+ ioaddr = Port + DATA ;
/*
* clear signature
*/
@@ -408,13 +429,20 @@ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
* copy parameters
*/
diva_configure_protocol (IoAdapter);
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
/*
* start the protocol code
*/
- outpp (IoAdapter->ctlReg, 0x08) ;
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ outpp (p, 0x08) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
/*
* wait for signature (max. 3 seconds)
*/
+ Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+ addrHi = Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+ addrLo = Port + ADDR ;
+ ioaddr = Port + DATA ;
for ( i = 0 ; i < 300 ; ++i )
{
diva_os_wait (10) ;
@@ -424,11 +452,13 @@ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
test = (dword)inppw (ioaddr) ;
if ( test == 0x4447 )
{
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
DBG_TRC(("Protocol startup time %d.%02d seconds",
(i / 100), (i % 100) ))
return (TRUE) ;
}
}
+ DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
IoAdapter->Properties.Name, test))
bri_cpu_trapped (IoAdapter) ;
@@ -441,12 +471,18 @@ static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
#endif /* } */
/******************************************************************************/
static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
- if ( !(inpp (IoAdapter->ctlReg) & 0x01) )
+ byte *p;
+
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ if ( !(inpp (p) & 0x01) ) {
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
return (0) ;
+ }
/*
clear interrupt line
*/
- outpp (IoAdapter->ctlReg, 0x08) ;
+ outpp (p, 0x08) ;
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
IoAdapter->IrqCount++ ;
if ( IoAdapter->Initialized ) {
diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
@@ -457,11 +493,16 @@ static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
Disable IRQ in the card hardware
-------------------------------------------------------------------------- */
static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter) {
- if ( IoAdapter->reset )
+ byte *p;
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ if ( p )
{
- outpp (IoAdapter->reset, 0x00) ; /* disable interrupts ! */
+ outpp (p, 0x00) ; /* disable interrupts ! */
}
- outpp (IoAdapter->ctlReg, 0x00) ; /* clear int, halt cpu */
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+ outpp (p, 0x00) ; /* clear int, halt cpu */
+ DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
}
/* -------------------------------------------------------------------------
Fill card entry points
diff --git a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c
index 2cfa06e6bb26..e1f13e05e5ad 100644
--- a/drivers/isdn/hardware/eicon/s_pri.c
+++ b/drivers/isdn/hardware/eicon/s_pri.c
@@ -54,7 +54,7 @@ static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
/*
* check for trapped MIPS 46xx CPU, dump exception frame
*/
- base = IoAdapter->ram - MP_SHARED_RAM_OFFSET ;
+ base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
TrapID = READ_DWORD(&base[0x80]) ;
if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
{
@@ -68,8 +68,10 @@ static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
regs[0] &= IoAdapter->MemorySize - 1 ;
if ( (regs[0] < IoAdapter->MemorySize - 1) )
{
- if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
+ if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
return ;
+ }
size = IoAdapter->MemorySize - regs[0] ;
if ( size > MAX_XLOG_SIZE )
size = MAX_XLOG_SIZE ;
@@ -81,24 +83,29 @@ static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
diva_os_free (0, Xlog) ;
IoAdapter->trapped = 2 ;
}
+ DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
}
/* -------------------------------------------------------------------------
Hardware reset of PRI card
------------------------------------------------------------------------- */
static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) {
- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
+ byte *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
diva_os_wait (50) ;
- *IoAdapter->reset = 0x00 ;
+ *p = 0x00 ;
diva_os_wait (50) ;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
}
/* -------------------------------------------------------------------------
Stop Card Hardware
------------------------------------------------------------------------- */
static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
dword i;
- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
+ byte *p;
+ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
cfgReg[3] = 0x00000000 ;
cfgReg[1] = 0x00000000 ;
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ;
i = 0 ;
while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) )
@@ -107,21 +114,25 @@ static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
i++ ;
}
DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
+ cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000)));
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
diva_os_wait (1) ;
- *IoAdapter->reset = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ *p = _MP_RISC_RESET | _MP_LED1 | _MP_LED2 ;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
}
#if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
/* -------------------------------------------------------------------------
Load protocol code to the PRI Card
------------------------------------------------------------------------- */
-#define DOWNLOAD_ADDR(IoAdapter) \
- (&IoAdapter->ram[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)])
+#define DOWNLOAD_ADDR(IoAdapter) (IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1))
static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
dword FileLength ;
dword *File ;
dword *sharedRam ;
dword Addr ;
+ byte *p;
if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
return (0) ;
}
@@ -172,14 +183,17 @@ static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
return (0) ;
}
IoAdapter->downloadAddr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
memcpy (sharedRam, File, FileLength) ;
if ( memcmp (sharedRam, File, FileLength) )
{
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
xdiFreeFile (File);
return (0) ;
}
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
xdiFreeFile (File);
return (1) ;
}
@@ -228,8 +242,8 @@ dsp_check_presence (volatile byte* addr, volatile byte* data, int dsp)
static dword
diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
{
- /* byte* base = a->resources.pci.addr[2]; */
- byte* base = IoAdapter->reset - MP_RESET ;
+ byte* base;
+ byte* p;
dword ret = 0, DspCount = 0 ;
dword row_offset[] = {
0x00000000,
@@ -242,14 +256,18 @@ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
byte *dsp_addr_port, *dsp_data_port, row_state;
int dsp_row = 0, dsp_index, dsp_num;
IoAdapter->InitialDspInfo &= 0xffff ;
- /* if (!base || !a->xdi_adapter.reset) */
- if (!base || !IoAdapter->reset)
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ if (!p)
{
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
return (0);
}
- /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_DSP_RESET; */
- *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_DSP_RESET;
+ *(volatile byte*)(p) = _MP_RISC_RESET | _MP_DSP_RESET;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
diva_os_wait (5) ;
+
+ base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
+
for (dsp_num = 0; dsp_num < 30; dsp_num++) {
dsp_row = dsp_num / 7 + 1;
dsp_index = dsp_num % 7;
@@ -264,8 +282,10 @@ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
DspCount++ ;
}
}
- /* *(volatile byte*)(a->xdi_adapter.reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2; */
- *(volatile byte*)(IoAdapter->reset) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
+ DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
+
+ p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+ *(volatile byte*)(p) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
diva_os_wait (50) ;
/*
Verify modules
@@ -301,7 +321,8 @@ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
((ret >> (3*7)) & 0x7F) ? "Y" : "N"))
DBG_LOG(("+-----------------------+"))
DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, ~ret & 0x3fffffff))
- *(volatile byte*)(IoAdapter->reset) = 0 ;
+ *(volatile byte*)(p) = 0 ;
+ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
diva_os_wait (50) ;
IoAdapter->InitialDspInfo |= DspCount << 16 ;
return (ret);
@@ -312,6 +333,7 @@ diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
dword *sharedRam ;
+ byte *p;
*addr = (void *)IoAdapter->downloadAddr ;
if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
@@ -321,11 +343,15 @@ static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
IoAdapter->downloadAddr + length))
return (-1) ;
}
- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
- if ( fp->sysFileRead (fp, sharedRam, length) != length )
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
+ if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
return (-1) ;
+ }
IoAdapter->downloadAddr += length ;
IoAdapter->downloadAddr = (IoAdapter->downloadAddr + 3) & (~3) ;
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
return (0) ;
}
/* -------------------------------------------------------------------------
@@ -338,6 +364,7 @@ static dword pri_telindus_load (PISDN_ADAPTER IoAdapter) {
word download_count ;
dword *sharedRam ;
dword FileLength ;
+ byte *p;
if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) )
return (0) ;
IoAdapter->downloadAddr = (IoAdapter->DspCodeBaseAddr
@@ -363,9 +390,11 @@ static dword pri_telindus_load (PISDN_ADAPTER IoAdapter) {
* store # of separate download files extracted from archive
*/
IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
- sharedRam = (dword *)DOWNLOAD_ADDR(IoAdapter) ;
+ p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
return (FileLength) ;
}
/* -------------------------------------------------------------------------
@@ -374,14 +403,17 @@ static dword pri_telindus_load (PISDN_ADAPTER IoAdapter) {
#define MIN_DSPS 0x30000000
static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
dword i ;
- struct mp_load *boot = (struct mp_load *)IoAdapter->ram ;
- if ( IoAdapter->Properties.Card != CARD_MAEP )
+ struct mp_load *boot = (struct mp_load *)DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
+ if ( IoAdapter->Properties.Card != CARD_MAEP ) {
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
return (0) ;
+ }
boot->err = 0 ;
#if 0
IoAdapter->rstFnc (IoAdapter) ;
#else
if ( MIN_DSPS != (MIN_DSPS & diva_pri_detect_dsps(IoAdapter)) ) { /* makes reset */
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
DBG_FTL(("%s: DSP error!", IoAdapter->Properties.Name))
return (0) ;
}
@@ -394,28 +426,36 @@ static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
diva_os_wait (10) ;
if ( i == boot->live )
{
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
DBG_FTL(("%s: CPU is not alive!", IoAdapter->Properties.Name))
return (0) ;
}
if ( boot->err )
{
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
DBG_FTL(("%s: Board Selftest failed!", IoAdapter->Properties.Name))
return (0) ;
}
/*
* download protocol and dsp files
*/
- if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) )
+ if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) ) {
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
return (0) ;
- if ( !pri_protocol_load (IoAdapter) )
+ }
+ if ( !pri_protocol_load (IoAdapter) ) {
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
return (0) ;
- if ( !pri_telindus_load (IoAdapter) )
+ }
+ if ( !pri_telindus_load (IoAdapter) ) {
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
return (0) ;
+ }
/*
* copy configuration parameters
*/
IoAdapter->ram += MP_SHARED_RAM_OFFSET ;
- memset (IoAdapter->ram, '\0', 256) ;
+ memset (boot + MP_SHARED_RAM_OFFSET, '\0', 256) ;
diva_configure_protocol (IoAdapter);
/*
* start adapter
@@ -430,11 +470,13 @@ static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
diva_os_wait (10) ;
if ( (boot->signature >> 16) == 0x4447 )
{
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
DBG_TRC(("Protocol startup time %d.%02d seconds",
(i / 100), (i % 100) ))
return (1) ;
}
}
+ DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
IoAdapter->Properties.Name, boot->signature >> 16))
pri_cpu_trapped (IoAdapter) ;
@@ -449,12 +491,16 @@ static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
PRI Adapter interrupt Service Routine
-------------------------------------------------------------------------- */
static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
- if ( !((READ_DWORD((dword *)IoAdapter->cfg)) & 0x80000000) )
+ byte *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+ if ( !((READ_DWORD((dword *)cfg)) & 0x80000000) ) {
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
return (0) ;
+ }
/*
clear interrupt line
*/
- WRITE_DWORD(((dword *)IoAdapter->cfg), (dword)~0x03E00000) ;
+ WRITE_DWORD(((dword *)cfg), (dword)~0x03E00000) ;
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
IoAdapter->IrqCount++ ;
if ( IoAdapter->Initialized )
{
@@ -466,10 +512,11 @@ static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
Disable interrupt in the card hardware
------------------------------------------------------------------------- */
static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
- dword volatile *cfgReg = (dword volatile *)IoAdapter->cfg ;
+ dword volatile *cfgReg = (dword volatile *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
cfgReg[3] = 0x00000000 ;
cfgReg[1] = 0x00000000 ;
WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
+ DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
}
/* -------------------------------------------------------------------------
Install entry points for PRI Adapter
diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c
index ef14ac9b1943..6ef0f5a5f64f 100644
--- a/drivers/isdn/hardware/eicon/um_idi.c
+++ b/drivers/isdn/hardware/eicon/um_idi.c
@@ -1,4 +1,4 @@
-/* $Id: um_idi.c,v 1.1.2.2 2001/02/11 14:40:41 armin Exp $ */
+/* $Id: um_idi.c,v 1.9 2003/09/09 06:00:47 schindler Exp $ */
#include "platform.h"
#include "di_defs.h"
@@ -37,6 +37,11 @@ static int process_idi_rc(divas_um_idi_entity_t * e, byte rc);
static int process_idi_ind(divas_um_idi_entity_t * e, byte ind);
static int write_return_code(divas_um_idi_entity_t * e, byte rc);
+/*
+ * include queue functions
+ */
+#include "dlist.c"
+
/* --------------------------------------------------------------------------
MAIN
-------------------------------------------------------------------------- */
@@ -171,7 +176,15 @@ static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr)
------------------------------------------------------------------------ */
int diva_um_idi_nr_of_adapters(void)
{
- return (diva_q_get_nr_of_entries(&adapter_q));
+ int i = 0;
+ const diva_entity_queue_t * q = &adapter_q;
+ const diva_entity_link_t *diva_current = q->head;
+
+ while (diva_current) {
+ i++;
+ diva_current = diva_current->next;
+ }
+ return(i);
}
/* ------------------------------------------------------------------------
diff --git a/drivers/isdn/hardware/eicon/xdi_adapter.h b/drivers/isdn/hardware/eicon/xdi_adapter.h
index 3db6211f5d39..b52b90580b96 100644
--- a/drivers/isdn/hardware/eicon/xdi_adapter.h
+++ b/drivers/isdn/hardware/eicon/xdi_adapter.h
@@ -1,4 +1,4 @@
-/* $Id: xdi_adapter.h,v 1.1.2.3 2001/02/16 08:40:36 armin Exp $ */
+/* $Id: xdi_adapter.h,v 1.5 2003/06/21 17:06:08 schindler Exp $ */
#ifndef __DIVA_OS_XDI_ADAPTER_H__
#define __DIVA_OS_XDI_ADAPTER_H__
@@ -14,7 +14,8 @@ typedef struct _divas_pci_card_resources {
dword bar[8]; /* contains context of appropriate BAR Register */
void *addr[8]; /* same bar, but mapped into memory */
dword length[8]; /* bar length */
-
+ int mem_type_id[10];
+ unsigned int qoffset;
byte irq;
} divas_pci_card_resources_t;
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 8e5f06315cb8..55c173224925 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -2113,7 +2113,7 @@ hisax_release_resources(struct IsdnCardState *cs)
#include <linux/pci.h>
-static struct pci_device_id hisax_pci_tbl[] __initdata = {
+static struct pci_device_id hisax_pci_tbl[] = {
#ifdef CONFIG_HISAX_FRITZPCI
{PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID},
#endif
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 5851cbe1f8e5..5cac2bf5f4b0 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -21,7 +21,7 @@
#include "hysdn_defs.h"
-static struct pci_device_id hysdn_pci_tbl[] __initdata = {
+static struct pci_device_id hysdn_pci_tbl[] = {
{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO},
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index d28d864cbaa5..21fd87cd4999 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -120,7 +120,7 @@ typedef unsigned int bool;
#include "dgrs_asstruct.h"
#include "dgrs_bcomm.h"
-static struct pci_device_id dgrs_pci_tbl[] __initdata = {
+static struct pci_device_id dgrs_pci_tbl[] = {
{ SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* Terminating entry */
};
diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c
index 4762724c8bc0..df3b9bd485e1 100644
--- a/drivers/net/fc/iph5526.c
+++ b/drivers/net/fc/iph5526.c
@@ -110,7 +110,7 @@ static const char *version =
#define ALIGNED_ADDR(addr, len) ((((unsigned long)(addr) + (len - 1)) & ~(len - 1)) - (unsigned long)(addr))
-static struct pci_device_id iph5526_pci_tbl[] __initdata = {
+static struct pci_device_id iph5526_pci_tbl[] = {
{ PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_5526, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTERPHASE, PCI_DEVICE_ID_INTERPHASE_55x6, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* Terminating entry */
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index f45719a216c2..38c802e16418 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -284,7 +284,7 @@ static struct hp100_pci_id hp100_pci_ids[] = {
#define HP100_PCI_IDS_SIZE (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
-static struct pci_device_id hp100_pci_tbl[] __initdata = {
+static struct pci_device_id hp100_pci_tbl[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 938ec4088c75..553de687f690 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -121,7 +121,7 @@ void iodelay(int udelay)
}
}
-static struct pci_device_id via_pci_tbl[] __initdata = {
+static struct pci_device_id via_pci_tbl[] = {
{ PCI_VENDOR_ID_VIA, DeviceID1, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
{ PCI_VENDOR_ID_VIA, DeviceID2, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
{ PCI_VENDOR_ID_VIA, DeviceID3, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index d72e5442eaa4..5482c82c1734 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -182,7 +182,7 @@ extern void mac_clear_multicast(struct s_smc *smc);
extern void enable_tx_irq(struct s_smc *smc, u_short queue);
extern void mac_drv_clear_txd(struct s_smc *smc);
-static struct pci_device_id skfddi_pci_tbl[] __initdata = {
+static struct pci_device_id skfddi_pci_tbl[] = {
{ PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* Terminating entry */
};
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index b91f7d0199bf..e499df6accc8 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -179,7 +179,7 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
where it could be referenced at any time due to hot plugging,
the __initdata reference should be removed. */
-struct pci_device_id happymeal_pci_ids[] __initdata = {
+struct pci_device_id happymeal_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_SUN,
.device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index 6f18910efbbd..6610ed33e6ba 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -201,7 +201,7 @@ static int pci_probe(sdlahw_t *hw);
* Note: All data must be explicitly initialized!!!
*/
-static struct pci_device_id sdladrv_pci_tbl[] __initdata = {
+static struct pci_device_id sdladrv_pci_tbl[] = {
{ V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* Terminating entry */
};
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index ba16a21a7a05..c60101ffc3ca 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -122,6 +122,7 @@ struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
+ unsigned int capabilities; /* port capabilities */
unsigned short rev;
unsigned char acr;
unsigned char ier;
@@ -683,6 +684,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
serial_outp(up, UART_LCR, save_lcr);
up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
+ up->capabilities = uart_config[up->port.type].flags;
if (up->port.type == PORT_UNKNOWN)
goto out;
@@ -1190,6 +1192,8 @@ static int serial8250_startup(struct uart_port *port)
unsigned long flags;
int retval;
+ up->capabilities = uart_config[up->port.type].flags;
+
if (up->port.type == PORT_16C950) {
/* Wake up and initialize UART */
up->acr = 0;
@@ -1215,7 +1219,7 @@ static int serial8250_startup(struct uart_port *port)
* Clear the FIFO buffers and disable them.
* (they will be reeanbled in set_termios())
*/
- if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
+ if (up->capabilities & UART_CLEAR_FIFO) {
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
@@ -1428,7 +1432,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
up->rev == 0x5201)
quot ++;
- if (uart_config[up->port.type].flags & UART_USE_FIFO) {
+ if (up->capabilities & UART_USE_FIFO) {
if (baud < 2400)
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
#ifdef CONFIG_SERIAL_8250_RSA
@@ -1489,13 +1493,13 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_out(up, UART_IER, up->ier);
- if (uart_config[up->port.type].flags & UART_STARTECH) {
+ if (up->capabilities & UART_STARTECH) {
serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR,
termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
}
- if (uart_config[up->port.type].flags & UART_NATSEMI) {
+ if (up->capabilities & UART_NATSEMI) {
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
serial_outp(up, UART_LCR, 0xe0);
} else {
@@ -1524,7 +1528,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
struct uart_8250_port *up = (struct uart_8250_port *)port;
if (state) {
/* sleep */
- if (uart_config[up->port.type].flags & UART_STARTECH) {
+ if (up->capabilities & UART_STARTECH) {
/* Arrange to enter sleep mode */
serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR, UART_EFR_ECB);
@@ -1543,7 +1547,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
up->pm(port, state, oldstate);
} else {
/* wake */
- if (uart_config[up->port.type].flags & UART_STARTECH) {
+ if (up->capabilities & UART_STARTECH) {
/* Wake up UART */
serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR, UART_EFR_ECB);
@@ -2101,9 +2105,9 @@ void serial8250_get_irq_map(unsigned int *map)
*
* Suspend one serial port.
*/
-void serial8250_suspend_port(int line, u32 level)
+void serial8250_suspend_port(int line)
{
- uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port, level);
+ uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
}
/**
@@ -2112,9 +2116,9 @@ void serial8250_suspend_port(int line, u32 level)
*
* Resume one serial port.
*/
-void serial8250_resume_port(int line, u32 level)
+void serial8250_resume_port(int line)
{
- uart_resume_port(&serial8250_reg, &serial8250_ports[line].port, level);
+ uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
}
static int __init serial8250_init(void)
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index cc206f9476ac..91ced9bdb3be 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -27,8 +27,8 @@ struct serial8250_probe {
int serial8250_register_probe(struct serial8250_probe *probe);
void serial8250_unregister_probe(struct serial8250_probe *probe);
void serial8250_get_irq_map(unsigned int *map);
-void serial8250_suspend_port(int line, u32 level);
-void serial8250_resume_port(int line, u32 level);
+void serial8250_suspend_port(int line);
+void serial8250_resume_port(int line);
struct old_serial_port {
unsigned int uart;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index dc90cc477844..778cd1eea5ba 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1600,19 +1600,6 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
}
}
-static int pciserial_save_state_one(struct pci_dev *dev, u32 state)
-{
- struct serial_private *priv = pci_get_drvdata(dev);
-
- if (priv) {
- int i;
-
- for (i = 0; i < priv->nr; i++)
- serial8250_suspend_port(priv->line[i], SUSPEND_SAVE_STATE);
- }
- return 0;
-}
-
static int pciserial_suspend_one(struct pci_dev *dev, u32 state)
{
struct serial_private *priv = pci_get_drvdata(dev);
@@ -1621,7 +1608,7 @@ static int pciserial_suspend_one(struct pci_dev *dev, u32 state)
int i;
for (i = 0; i < priv->nr; i++)
- serial8250_suspend_port(priv->line[i], SUSPEND_POWER_DOWN);
+ serial8250_suspend_port(priv->line[i]);
}
return 0;
}
@@ -1639,10 +1626,8 @@ static int pciserial_resume_one(struct pci_dev *dev)
if (priv->quirk->init)
priv->quirk->init(dev);
- for (i = 0; i < priv->nr; i++) {
- serial8250_resume_port(priv->line[i], RESUME_POWER_ON);
- serial8250_resume_port(priv->line[i], RESUME_RESTORE_STATE);
- }
+ for (i = 0; i < priv->nr; i++)
+ serial8250_resume_port(priv->line[i]);
}
return 0;
}
@@ -2040,7 +2025,6 @@ static struct pci_driver serial_pci_driver = {
.name = "serial",
.probe = pciserial_init_one,
.remove = __devexit_p(pciserial_remove_one),
- .save_state = pciserial_save_state_one,
.suspend = pciserial_suspend_one,
.resume = pciserial_resume_one,
.id_table = serial_pci_tbl,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 66cc7dfe5c56..333aa2f78f15 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -10,6 +10,7 @@ menu "Serial drivers"
# The new 8250/16550 serial drivers
config SERIAL_8250
tristate "8250/16550 and compatible serial support"
+ select SERIAL_CORE
---help---
This selects whether you want to include the driver for the standard
serial ports. The standard answer is Y. People who might say N
@@ -41,6 +42,7 @@ config SERIAL_8250
config SERIAL_8250_CONSOLE
bool "Console on 8250/16550 and compatible serial port"
depends on SERIAL_8250=y
+ select SERIAL_CORE_CONSOLE
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
@@ -167,12 +169,14 @@ config SERIAL_8250_ACORN
config SERIAL_ANAKIN
bool "Anakin serial port support"
depends on ARM && ARCH_ANAKIN
+ select SERIAL_CORE
help
::: To be written :::
config SERIAL_ANAKIN_CONSOLE
bool "Console on Anakin serial port"
depends on SERIAL_ANAKIN
+ select SERIAL_CORE_CONSOLE
help
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
@@ -190,7 +194,8 @@ config ANAKIN_DEFAULT_BAUDRATE
config SERIAL_AMBA
tristate "ARM AMBA serial port support"
- depends on ARM && ARCH_INTEGRATOR
+ depends on ARM_AMBA
+ select SERIAL_CORE
help
This selects the ARM(R) AMBA(R) PrimeCell UART. If you have an
Integrator platform, say Y or M here.
@@ -200,6 +205,7 @@ config SERIAL_AMBA
config SERIAL_AMBA_CONSOLE
bool "Support for console on AMBA serial port"
depends on SERIAL_AMBA=y
+ select SERIAL_CORE_CONSOLE
---help---
Say Y here if you wish to use an AMBA PrimeCell UART as the system
console (the system console is the device which receives all kernel
@@ -214,18 +220,20 @@ config SERIAL_AMBA_CONSOLE
config SERIAL_INTEGRATOR
bool
- depends on SERIAL_AMBA=y
+ depends on SERIAL_AMBA && ARCH_INTEGRATOR
default y
config SERIAL_CLPS711X
tristate "CLPS711X serial port support"
depends on ARM && ARCH_CLPS711X
+ select SERIAL_CORE
help
::: To be written :::
config SERIAL_CLPS711X_CONSOLE
bool "Support for console on CLPS711X serial port"
depends on SERIAL_CLPS711X=y
+ select SERIAL_CORE_CONSOLE
help
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
@@ -243,6 +251,7 @@ config SERIAL_CLPS711X_OLD_NAME
config SERIAL_21285
tristate "DC21285 serial port support"
depends on ARM && FOOTBRIDGE
+ select SERIAL_CORE
help
If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
PCI bridge you can enable its onboard serial port by enabling this
@@ -258,6 +267,7 @@ config SERIAL_21285_OLD
config SERIAL_21285_CONSOLE
bool "Console on DC21285 serial port"
depends on SERIAL_21285=y
+ select SERIAL_CORE_CONSOLE
help
If you have enabled the serial port on the 21285 footbridge you can
make it the console by answering Y to this option.
@@ -272,6 +282,7 @@ config SERIAL_21285_CONSOLE
config SERIAL_UART00
bool "Excalibur serial port (uart00) support"
depends on ARM && ARCH_CAMELOT
+ select SERIAL_CORE
help
Say Y here if you want to use the hard logic uart on Excalibur. This
driver also supports soft logic implentations of this uart core.
@@ -279,6 +290,7 @@ config SERIAL_UART00
config SERIAL_UART00_CONSOLE
bool "Support for console on Excalibur serial port"
depends on SERIAL_UART00
+ select SERIAL_CORE_CONSOLE
help
Say Y here if you want to support a serial console on an Excalibur
hard logic uart or uart00 IP core.
@@ -293,6 +305,7 @@ config SERIAL_UART00_CONSOLE
config SERIAL_SA1100
bool "SA1100 serial port support"
depends on ARM && ARCH_SA1100
+ select SERIAL_CORE
help
If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
can enable its onboard serial port by enabling this option.
@@ -302,6 +315,7 @@ config SERIAL_SA1100
config SERIAL_SA1100_CONSOLE
bool "Console on SA1100 serial port"
depends on SERIAL_SA1100
+ select SERIAL_CORE_CONSOLE
help
If you have enabled the serial port on the SA1100/SA1110 StrongARM
CPU you can make it the console by answering Y to this option.
@@ -316,6 +330,8 @@ config SERIAL_SA1100_CONSOLE
config SERIAL_SUNCORE
bool
depends on SPARC32 || SPARC64
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
default y
config SERIAL_SUNZILOG
@@ -352,6 +368,7 @@ config SERIAL_SUNSU_CONSOLE
config SERIAL_MUX
tristate "Serial MUX support"
depends on PARISC
+ select SERIAL_CORE
default y
---help---
Saying Y here will enable the hardware MUX serial driver for
@@ -369,6 +386,7 @@ config SERIAL_MUX
config SERIAL_MUX_CONSOLE
bool "Support for console on serial MUX"
depends on SERIAL_MUX
+ select SERIAL_CORE_CONSOLE
default y
config PDC_CONSOLE
@@ -406,6 +424,7 @@ config SERIAL_SUNSAB_CONSOLE
config V850E_UART
bool "NEC V850E on-chip UART support"
depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
+ select SERIAL_CORE
default y
config V850E_UARTB
@@ -416,10 +435,12 @@ config V850E_UARTB
config V850E_UART_CONSOLE
bool "Use NEC V850E on-chip UART for console"
depends on V850E_UART
+ select SERIAL_CORE_CONSOLE
config SERIAL98
tristate "PC-9800 8251-based primary serial port support"
depends on X86_PC9800
+ select SERIAL_CORE
help
If you want to use standard primary serial ports on PC-9800,
say Y. Otherwise, say N.
@@ -427,16 +448,13 @@ config SERIAL98
config SERIAL98_CONSOLE
bool "Support for console on PC-9800 standard serial port"
depends on SERIAL98=y
+ select SERIAL_CORE_CONSOLE
config SERIAL_CORE
tristate
- default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_UART && SERIAL_PMACZILOG!=y && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m || SERIAL_PMACZILOG=m)
- default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_UART || SERIAL98=y || SERIAL_PMACZILOG=y
config SERIAL_CORE_CONSOLE
bool
- depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_UART_CONSOLE || SERIAL98_CONSOLE || SERIAL_PMACZILOG_CONSOLE
- default y
config SERIAL_68328
bool "68328 serial support"
@@ -476,6 +494,7 @@ config SERIAL_68360
config SERIAL_PMACZILOG
tristate "PowerMac z85c30 ESCC support"
depends on PPC_OF
+ select SERIAL_CORE
help
This driver supports the Zilog z85C30 serial ports found on
PowerMac machines.
@@ -484,6 +503,7 @@ config SERIAL_PMACZILOG
config SERIAL_PMACZILOG_CONSOLE
bool "Console on PowerMac z85c30 serial port"
depends on SERIAL_PMACZILOG=y
+ select SERIAL_CORE_CONSOLE
help
If you would like to be able to use the z85c30 serial port
on your PowerMac as the console, you can do so by answering
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 611eb6c84e02..fdc96e347228 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -11,10 +11,10 @@ serial-8250-$(CONFIG_PNP) += 8250_pnp.o
serial-8250-$(CONFIG_SERIAL_8250_HCDP) += 8250_hcdp.o
serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o
-obj-$(CONFIG_SERIAL_CORE) += core.o
+obj-$(CONFIG_SERIAL_CORE) += serial_core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
-obj-$(CONFIG_SERIAL_8250_CS) += 8250_cs.o
+obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
obj-$(CONFIG_SERIAL_AMBA) += amba.o
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index a32dae486b77..1848756ca2bf 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -104,7 +104,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
{
}
-static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
{
struct uart_port *port = dev_id;
struct tty_struct *tty = port->info->tty;
@@ -139,7 +139,7 @@ static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
}
out:
tty_flip_buffer_push(tty);
- return;
+ return IRQ_HANDLED;
handle_error:
if (ch & UARTDR_PARERR)
@@ -180,7 +180,7 @@ static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
goto error_return;
}
-static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
{
struct uart_port *port = dev_id;
struct circ_buf *xmit = &port->info->xmit;
@@ -190,11 +190,11 @@ static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
clps_writel(port->x_char, UARTDR(port));
port->icount.tx++;
port->x_char = 0;
- return;
+ return IRQ_HANDLED;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
clps711xuart_stop_tx(port, 0);
- return;
+ return IRQ_HANDLED;
}
count = port->fifosize >> 1;
@@ -211,6 +211,8 @@ static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
if (uart_circ_empty(xmit))
clps711xuart_stop_tx(port, 0);
+
+ return IRQ_HANDLED;
}
static unsigned int clps711xuart_tx_empty(struct uart_port *port)
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 8ded3cf74f28..51b191307bad 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -862,8 +862,8 @@ static int sa1100_serial_suspend(struct device *_dev, u32 state, u32 level)
{
struct sa1100_port *sport = dev_get_drvdata(_dev);
- if (sport)
- uart_suspend_port(&sa1100_reg, &sport->port, level);
+ if (sport && level == SUSPEND_DISABLE)
+ uart_suspend_port(&sa1100_reg, &sport->port);
return 0;
}
@@ -872,8 +872,8 @@ static int sa1100_serial_resume(struct device *_dev, u32 level)
{
struct sa1100_port *sport = dev_get_drvdata(_dev);
- if (sport)
- uart_resume_port(&sa1100_reg, &sport->port, level);
+ if (sport && level == RESUME_ENABLE)
+ uart_resume_port(&sa1100_reg, &sport->port);
return 0;
}
diff --git a/drivers/serial/core.c b/drivers/serial/serial_core.c
index a264d72ca695..064b9631201f 100644
--- a/drivers/serial/core.c
+++ b/drivers/serial/serial_core.c
@@ -1875,84 +1875,72 @@ static void uart_change_pm(struct uart_state *state, int pm_state)
state->pm_state = pm_state;
}
-int uart_suspend_port(struct uart_driver *drv, struct uart_port *port, u32 level)
+int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
{
struct uart_state *state = drv->state + port->line;
down(&state->sem);
- switch (level) {
- case SUSPEND_SAVE_STATE:
- if (state->info && state->info->flags & UIF_INITIALIZED) {
- struct uart_ops *ops = port->ops;
+ if (state->info && state->info->flags & UIF_INITIALIZED) {
+ struct uart_ops *ops = port->ops;
- spin_lock_irq(&port->lock);
- ops->stop_tx(port, 0);
- ops->set_mctrl(port, 0);
- ops->stop_rx(port);
- spin_unlock_irq(&port->lock);
-
- /*
- * Wait for the transmitter to empty.
- */
- while (!ops->tx_empty(port)) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(10*HZ/1000);
- }
- set_current_state(TASK_RUNNING);
-
- ops->shutdown(port);
- }
- break;
+ spin_lock_irq(&port->lock);
+ ops->stop_tx(port, 0);
+ ops->set_mctrl(port, 0);
+ ops->stop_rx(port);
+ spin_unlock_irq(&port->lock);
- case SUSPEND_POWER_DOWN:
/*
- * Disable the console device before suspending.
+ * Wait for the transmitter to empty.
*/
- if (uart_console(port))
- port->cons->flags &= ~CON_ENABLED;
+ while (!ops->tx_empty(port)) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(10*HZ/1000);
+ }
+ set_current_state(TASK_RUNNING);
- uart_change_pm(state, 3);
- break;
+ ops->shutdown(port);
}
+ /*
+ * Disable the console device before suspending.
+ */
+ if (uart_console(port))
+ port->cons->flags &= ~CON_ENABLED;
+
+ uart_change_pm(state, 3);
+
up(&state->sem);
return 0;
}
-int uart_resume_port(struct uart_driver *drv, struct uart_port *port, u32 level)
+int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
{
struct uart_state *state = drv->state + port->line;
down(&state->sem);
- switch (level) {
- case RESUME_POWER_ON:
- uart_change_pm(state, 0);
+ uart_change_pm(state, 0);
- /*
- * Re-enable the console device after suspending.
- */
- if (uart_console(port)) {
- uart_change_speed(state, NULL);
- port->cons->flags |= CON_ENABLED;
- }
- break;
+ /*
+ * Re-enable the console device after suspending.
+ */
+ if (uart_console(port)) {
+ uart_change_speed(state, NULL);
+ port->cons->flags |= CON_ENABLED;
+ }
- case RESUME_RESTORE_STATE:
- if (state->info && state->info->flags & UIF_INITIALIZED) {
- struct uart_ops *ops = port->ops;
+ if (state->info && state->info->flags & UIF_INITIALIZED) {
+ struct uart_ops *ops = port->ops;
- ops->set_mctrl(port, 0);
- ops->startup(port);
- uart_change_speed(state, NULL);
- spin_lock_irq(&port->lock);
- ops->set_mctrl(port, port->mctrl);
- ops->start_tx(port, 0);
- spin_unlock_irq(&port->lock);
- }
- break;
+ ops->set_mctrl(port, 0);
+ ops->startup(port);
+ uart_change_speed(state, NULL);
+ spin_lock_irq(&port->lock);
+ ops->set_mctrl(port, port->mctrl);
+ ops->start_tx(port, 0);
+ spin_unlock_irq(&port->lock);
}
up(&state->sem);
diff --git a/drivers/serial/8250_cs.c b/drivers/serial/serial_cs.c
index a70c3ddfadfa..a70c3ddfadfa 100644
--- a/drivers/serial/8250_cs.c
+++ b/drivers/serial/serial_cs.c
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index f4b423fca589..fdf5a1bbb513 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -66,7 +66,7 @@ static const char *i810_pci_list[] __initdata = {
"Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
};
-static struct pci_device_id i810fb_pci_tbl[] __initdata = {
+static struct pci_device_id i810fb_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,
diff --git a/fs/Kconfig b/fs/Kconfig
index f00aba2856d3..89bb33cd459a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1505,7 +1505,7 @@ config CIFS
cifs module since smbfs is currently more stable and provides
support for older servers. The intent of this module is to provide the
most advanced network file system function for CIFS compliant servers,
- including support for dfs (heirarchical name space), secure per-user
+ including support for dfs (hierarchical name space), secure per-user
session establishment, safe distributed caching (oplock), optional
packet signing, Unicode and other internationalization improvements, and
optional Winbind (nsswitch) integration. This module is in an early
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index 8e7197379672..4029c9da4b86 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -2,6 +2,8 @@
# Makefile for Red Hat Linux AFS client.
#
+#CFLAGS += -finstrument-functions
+
kafs-objs := \
callback.o \
cell.o \
diff --git a/fs/afs/cache-layout.h b/fs/afs/cache-layout.h
deleted file mode 100644
index e71afd719a3f..000000000000
--- a/fs/afs/cache-layout.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* cache-layout.h: AFS cache layout
- *
- * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- *
- * The cache is stored on a block device and is laid out as:
- *
- * 0 +------------------------------------------------
- * |
- * | SuperBlock
- * |
- * 1 +------------------------------------------------
- * |
- * | file-meta-data File: Data block #0
- * | - file-meta-data file (volix #0 file #0) : Meta-data block
- * | - contains direct pointers to first 64 file data blocks
- * | - Cached cell catalogue file (volix #0 file #1) file: Meta-data block
- * | - Cached volume location catalogue file (volix #0 file #2): Meta-data block
- * | - Vnode catalogue hash bucket #n file: Meta-data block
- * |
- * 2 +------------------------------------------------
- * |
- * | Bitmap Block Allocation Bitmap
- * | - 1 bit per block in the bitmap block
- * | - bit 0 of dword 0 refers to the bitmap block 0
- * | - set if the bitmap block is full
- * | - 32768 bits per block, requiring 4 blocks for a 16Tb cache
- * | - bitmap bitmap blocks are cleared initially
- * | - not present if <4 bitmap blocks
- * |
- * +------------------------------------------------
- * |
- * | File Block Allocation Bitmap
- * | - 1 bit per block in the cache
- * | - bit 0 of dword 0 refers to the first block of the data cache
- * | - set if block is allocated
- * | - 32768 bits per block, requiring 131072 blocks for a 16Tb cache
- * | - bitmap blocks are cleared lazily (sb->bix_bitmap_unready)
- * |
- * +------------------------------------------------
- * |
- * | Data Cache
- * |
- * End +------------------------------------------------
- *
- * Blocks are indexed by an unsigned 32-bit word, meaning that the cache can hold up to 2^32 pages,
- * or 16Tb in total.
- *
- * Credentials will be cached in memory, since they are subject to change without notice, and are
- * difficult to derive manually, being constructed from the following information:
- * - per vnode user ID and mode mask
- * - parent directory ACL
- * - directory ACL (dirs only)
- * - group lists from ptserver
- */
-
-#ifndef _LINUX_AFS_CACHE_LAYOUT_H
-#define _LINUX_AFS_CACHE_LAYOUT_H
-
-#include "types.h"
-
-typedef u32 afsc_blockix_t;
-typedef u32 afsc_cellix_t;
-
-/* Cached volume index
- * - afsc_volix_t/4 is the index into the volume cache
- * - afsc_volix_t%4 is 0 for R/W, 1 for R/O and 2 for Bak (3 is not used)
- * - afsc_volix_t==0-3 refers to a "virtual" volume that stores meta-data about the cache
- */
-typedef struct {
- u32 index;
-} afsc_volix_t;
-
-#define AFSC_VNCAT_HASH_NBUCKETS 128
-
-/* special meta file IDs (all cell 0 vol 0) */
-enum afsc_meta_fids {
- AFSC_META_FID_METADATA = 0,
- AFSC_META_FID_CELL_CATALOGUE = 1,
- AFSC_META_FID_VLDB_CATALOGUE = 2,
- AFSC_META_FID_VNODE_CATALOGUE0 = 3,
- AFSC_META_FID__COUNT = AFSC_VNCAT_HASH_NBUCKETS + 3
-};
-
-/*****************************************************************************/
-/*
- * cache superblock block layout
- * - the blockdev is prepared for initialisation by 'echo "kafsuninit" >/dev/hdaXX' before mounting
- * - when initialised, the magic number is changed to "kafs-cache"
- */
-struct afsc_super_block
-{
- char magic[10]; /* magic number */
-#define AFSC_SUPER_MAGIC "kafs-cache"
-#define AFSC_SUPER_MAGIC_NEEDS_INIT "kafsuninit"
-#define AFSC_SUPER_MAGIC_SIZE 10
-
- unsigned short endian; /* 0x1234 stored CPU-normal order */
-#define AFSC_SUPER_ENDIAN 0x1234
-
- unsigned version; /* format version */
-#define AFSC_SUPER_VERSION 1
-
- /* layout */
- unsigned bsize; /* cache block size */
- afsc_blockix_t bix_bitmap_fullmap; /* block ix of bitmap full bitmap */
- afsc_blockix_t bix_bitmap; /* block ix of alloc bitmap */
- afsc_blockix_t bix_bitmap_unready; /* block ix of unready area of bitmap */
- afsc_blockix_t bix_cache; /* block ix of data cache */
- afsc_blockix_t bix_end; /* block ix of end of cache */
-};
-
-/*****************************************************************************/
-/*
- * vnode (inode) metadata cache record
- * - padded out to 512 bytes and stored eight to a page
- * - only the data version is necessary
- * - disconnected operation is not supported
- * - afs_iget() contacts the server to get the meta-data _anyway_ when an inode is first brought
- * into memory
- * - at least 64 direct block pointers will be available (a directory is max 256Kb)
- * - any block pointer which is 0 indicates an uncached page
- */
-struct afsc_vnode_meta
-{
- /* file ID */
- afsc_volix_t volume_ix; /* volume catalogue index */
- unsigned vnode; /* vnode number */
- unsigned unique; /* FID unique */
- unsigned size; /* size of file */
- time_t mtime; /* last modification time */
-
- /* file status */
- afs_dataversion_t version; /* current data version */
-
- /* file contents */
- afsc_blockix_t dbl_indirect; /* double indirect block index */
- afsc_blockix_t indirect; /* single indirect block 0 index */
- afsc_blockix_t direct[0]; /* direct block index (#AFSC_VNODE_META_DIRECT) */
-};
-
-#define AFSC_VNODE_META_RECSIZE 512 /* record size */
-
-#define AFSC_VNODE_META_DIRECT \
- ((AFSC_VNODE_META_RECSIZE-sizeof(struct afsc_vnode_meta))/sizeof(afsc_blockix_t))
-
-#define AFSC_VNODE_META_PER_PAGE (PAGE_SIZE / AFSC_VNODE_META_RECSIZE)
-
-/*****************************************************************************/
-/*
- * entry in the cached cell catalogue
- */
-struct afsc_cell_record
-{
- char name[64]; /* cell name (padded with NULs) */
- struct in_addr servers[16]; /* cached cell servers */
-};
-
-/*****************************************************************************/
-/*
- * entry in the cached volume location catalogue
- * - indexed by afsc_volix_t/4
- */
-struct afsc_vldb_record
-{
- char name[64]; /* volume name (padded with NULs) */
- afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */
- unsigned char vidmask; /* voltype mask for vid[] */
- unsigned char _pad[1];
- unsigned short nservers; /* number of entries used in servers[] */
- struct in_addr servers[8]; /* fileserver addresses */
- unsigned char srvtmask[8]; /* voltype masks for servers[] */
-#define AFSC_VOL_STM_RW 0x01 /* server holds a R/W version of the volume */
-#define AFSC_VOL_STM_RO 0x02 /* server holds a R/O version of the volume */
-#define AFSC_VOL_STM_BAK 0x04 /* server holds a backup version of the volume */
-
- afsc_cellix_t cell_ix; /* cell catalogue index (MAX_UINT if unused) */
- time_t ctime; /* time at which cached */
-};
-
-/*****************************************************************************/
-/*
- * vnode catalogue entry
- * - must be 2^x size so that do_generic_file_read doesn't present them split across pages
- */
-struct afsc_vnode_catalogue
-{
- afsc_volix_t volume_ix; /* volume catalogue index */
- afs_vnodeid_t vnode; /* vnode ID */
- u32 meta_ix; /* metadata file index */
- u32 atime; /* last time entry accessed */
-} __attribute__((packed));
-
-#define AFSC_VNODE_CATALOGUE_PER_BLOCK ((size_t)(PAGE_SIZE/sizeof(struct afsc_vnode_catalogue)))
-
-/*****************************************************************************/
-/*
- * vnode data "page directory" block
- * - first 1024 pages don't map through here
- * - PAGE_SIZE in size
- */
-struct afsc_indirect_block
-{
- afsc_blockix_t pt_bix[1024]; /* "page table" block indices */
-};
-
-/*****************************************************************************/
-/*
- * vnode data "page table" block
- * - PAGE_SIZE in size
- */
-struct afsc_dbl_indirect_block
-{
- afsc_blockix_t page_bix[1024]; /* "page" block indices */
-};
-
-
-#endif /* _LINUX_AFS_CACHE_LAYOUT_H */
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
new file mode 100644
index 000000000000..9eb7722b34d5
--- /dev/null
+++ b/fs/afs/cache.h
@@ -0,0 +1,27 @@
+/* cache.h: AFS local cache management interface
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_AFS_CACHE_H
+#define _LINUX_AFS_CACHE_H
+
+#undef AFS_CACHING_SUPPORT
+
+#include <linux/mm.h>
+#ifdef AFS_CACHING_SUPPORT
+#include <linux/cachefs.h>
+#endif
+#include "types.h"
+
+#ifdef __KERNEL__
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_AFS_CACHE_H */
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index 368a94a285a0..76ac0b9dbf48 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -68,7 +68,7 @@ int SRXAFSCM_InitCallBackState(afs_server_t *server)
spin_unlock(&vnode->lock);
iput(inode);
- if (release) afs_put_server(server);
+ afs_put_server(server);
spin_lock(&server->cb_lock);
}
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index f7f00a2bec9e..43e16714a7e8 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -36,6 +36,19 @@ static char *rootcell;
MODULE_PARM(rootcell,"s");
MODULE_PARM_DESC(rootcell,"root AFS cell name and VL server IP addr list");
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry);
+static void afs_cell_cache_update(void *source, void *entry);
+
+struct cachefs_index_def afs_cache_cell_index_def = {
+ .name = "cell_ix",
+ .data_size = sizeof(afs_cell_t),
+ .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
+ .match = afs_cell_cache_match,
+ .update = afs_cell_cache_update,
+};
+#endif
+
/*****************************************************************************/
/*
* create a cell record
@@ -65,7 +78,6 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
atomic_set(&cell->usage,0);
INIT_LIST_HEAD(&cell->link);
- INIT_LIST_HEAD(&cell->caches);
rwlock_init(&cell->sv_lock);
INIT_LIST_HEAD(&cell->sv_list);
@@ -96,7 +108,7 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
cell->vl_addrs[cell->vl_naddrs++].s_addr =
htonl((a<<24)|(b<<16)|(c<<8)|d);
- if (cell->vl_naddrs>=16)
+ if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS)
break;
} while(vllist=next, vllist);
@@ -106,6 +118,14 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
if (ret<0)
goto error;
+#ifdef AFS_CACHING_SUPPORT
+ /* put it up for caching */
+ cachefs_acquire_cookie(afs_cache_netfs.primary_index,
+ &afs_vlocation_cache_index_def,
+ cell,
+ &cell->cache);
+#endif
+
/* add to the cell lists */
write_lock(&afs_cells_lock);
list_add_tail(&cell->link,&afs_cells);
@@ -166,36 +186,45 @@ int afs_cell_init(void)
/*
* lookup a cell record
*/
-int afs_cell_lookup(const char *name, afs_cell_t **_cell)
+int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
{
struct list_head *_p;
afs_cell_t *cell;
+ int ret;
- _enter("\"%s\",",name?name:"*thiscell*");
+ _enter("\"%*.*s\",", namesz, namesz, name ? name : "");
- cell = afs_cell_root;
+ *_cell = NULL;
if (name) {
/* if the cell was named, look for it in the cell record list */
+ ret = -ENOENT;
cell = NULL;
read_lock(&afs_cells_lock);
list_for_each(_p,&afs_cells) {
- cell = list_entry(_p,afs_cell_t,link);
- if (strcmp(cell->name,name)==0)
+ cell = list_entry(_p, struct afs_cell, link);
+ if (strncmp(cell->name, name, namesz) == 0) {
+ afs_get_cell(cell);
break;
+ }
cell = NULL;
}
read_unlock(&afs_cells_lock);
- }
- if (cell)
+ if (cell)
+ ret = 0;
+ }
+ else {
+ cell = afs_cell_root;
afs_get_cell(cell);
+ ret = 0;
+ }
*_cell = cell;
- _leave(" = %d (%p)",cell?0:-ENOENT,cell);
- return cell ? 0 : -ENOENT;
+ _leave(" = %d (%p)", ret, cell);
+ return ret;
} /* end afs_cell_lookup() */
@@ -211,8 +240,8 @@ afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell)
cell = *_cell;
if (cell && !list_empty(&cell->link))
- atomic_inc(&cell->usage);
- else
+ afs_get_cell(cell);
+ else
cell = NULL;
write_unlock(&afs_cells_lock);
@@ -226,6 +255,9 @@ afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell)
*/
void afs_put_cell(afs_cell_t *cell)
{
+ if (!cell)
+ return;
+
_enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name);
/* sanity check */
@@ -278,6 +310,10 @@ static void afs_cell_destroy(afs_cell_t *cell)
list_del_init(&cell->proc_link);
up_write(&afs_proc_cells_sem);
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_relinquish_cookie(cell->cache,0);
+#endif
+
up_write(&afs_cells_sem);
if (!list_empty(&cell->sv_list)) BUG();
@@ -377,8 +413,7 @@ void afs_cell_purge(void)
_enter("");
- if (afs_cell_root)
- afs_put_cell(afs_cell_root);
+ afs_put_cell(afs_cell_root);
while (!list_empty(&afs_cells)) {
cell = NULL;
@@ -450,3 +485,46 @@ void afs_cell_purge(void)
_leave("");
} /* end afs_cell_purge() */
+
+/*****************************************************************************/
+/*
+ * match a cell record obtained from the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry)
+{
+ const struct afs_cache_cell *ccell = entry;
+ struct afs_cell *cell = target;
+
+ _enter("{%s},{%s}", ccell->name, cell->name);
+
+ if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
+ _leave(" = SUCCESS");
+ return CACHEFS_MATCH_SUCCESS;
+ }
+
+ _leave(" = FAILED");
+ return CACHEFS_MATCH_FAILED;
+} /* end afs_cell_cache_match() */
+#endif
+
+/*****************************************************************************/
+/*
+ * update a cell record in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_cell_cache_update(void *source, void *entry)
+{
+ struct afs_cache_cell *ccell = entry;
+ struct afs_cell *cell = source;
+
+ _enter("%p,%p", source, entry);
+
+ strncpy(ccell->name, cell->name, sizeof(ccell->name));
+
+ memcpy(ccell->vl_servers,
+ cell->vl_addrs,
+ min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
+
+} /* end afs_cell_cache_update() */
+#endif
diff --git a/fs/afs/cell.h b/fs/afs/cell.h
index 48eb9fa91f19..7784a48bd694 100644
--- a/fs/afs/cell.h
+++ b/fs/afs/cell.h
@@ -13,11 +13,24 @@
#define _LINUX_AFS_CELL_H
#include "types.h"
+#include "cache.h"
+
+#define AFS_CELL_MAX_ADDRS 15
extern volatile int afs_cells_being_purged; /* T when cells are being purged by rmmod */
/*****************************************************************************/
/*
+ * entry in the cached cell catalogue
+ */
+struct afs_cache_cell
+{
+ char name[64]; /* cell name (padded with NULs) */
+ struct in_addr vl_servers[15]; /* cached cell VL servers */
+};
+
+/*****************************************************************************/
+/*
* AFS cell record
*/
struct afs_cell
@@ -26,7 +39,9 @@ struct afs_cell
struct list_head link; /* main cell list link */
struct list_head proc_link; /* /proc cell list link */
struct proc_dir_entry *proc_dir; /* /proc dir for this cell */
- struct list_head caches; /* list of caches currently backing this cell */
+#ifdef AFS_CACHING_SUPPORT
+ struct cachefs_cookie *cache; /* caching cookie */
+#endif
/* server record management */
rwlock_t sv_lock; /* active server list lock */
@@ -41,22 +56,22 @@ struct afs_cell
spinlock_t vl_gylock; /* graveyard lock */
unsigned short vl_naddrs; /* number of VL servers in addr list */
unsigned short vl_curr_svix; /* current server index */
- struct in_addr vl_addrs[16]; /* cell VL server addresses */
+ struct in_addr vl_addrs[AFS_CELL_MAX_ADDRS]; /* cell VL server addresses */
char name[0]; /* cell name - must go last */
};
extern int afs_cell_init(void);
-extern int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell);
+extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
-extern int afs_cell_lookup(const char *name, afs_cell_t **_cell);
+extern int afs_cell_lookup(const char *name, unsigned nmsize, struct afs_cell **_cell);
#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
-extern afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell);
+extern struct afs_cell *afs_get_cell_maybe(struct afs_cell **_cell);
-extern void afs_put_cell(afs_cell_t *cell);
+extern void afs_put_cell(struct afs_cell *cell);
extern void afs_cell_purge(void);
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 23eb95d23f62..809402a8c725 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -119,6 +119,7 @@ static int kafscmd(void *arg)
int die;
printk("kAFS: Started kafscmd %d\n",current->pid);
+
daemonize("kafscmd");
complete(&kafscmd_alive);
@@ -293,15 +294,20 @@ int afscm_start(void)
down_write(&afscm_sem);
if (!afscm_usage) {
- ret = kernel_thread(kafscmd,NULL,0);
- if (ret<0)
+ ret = kernel_thread(kafscmd, NULL, 0);
+ if (ret < 0)
goto out;
wait_for_completion(&kafscmd_alive);
- ret = rxrpc_add_service(afs_transport,&AFSCM_service);
+ ret = rxrpc_add_service(afs_transport, &AFSCM_service);
if (ret<0)
goto kill;
+
+#ifdef AFS_AUTOMOUNT_SUPPORT
+ afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
+ afs_mntpt_expiry_timeout * HZ);
+#endif
}
afscm_usage++;
@@ -330,17 +336,20 @@ void afscm_stop(void)
down_write(&afscm_sem);
- if (afscm_usage==0) BUG();
+ if (afscm_usage == 0) BUG();
afscm_usage--;
- if (afscm_usage==0) {
+ if (afscm_usage == 0) {
/* don't want more incoming calls */
- rxrpc_del_service(afs_transport,&AFSCM_service);
+ rxrpc_del_service(afs_transport, &AFSCM_service);
/* abort any calls I've still got open (the afscm_error() will dequeue them) */
spin_lock(&afscm_calls_lock);
while (!list_empty(&afscm_calls)) {
- call = list_entry(afscm_calls.next,struct rxrpc_call,app_link);
+ call = list_entry(afscm_calls.next,
+ struct rxrpc_call,
+ app_link);
+
list_del_init(&call->app_link);
rxrpc_get_call(call);
spin_unlock(&afscm_calls_lock);
@@ -348,7 +357,8 @@ void afscm_stop(void)
rxrpc_call_abort(call,-ESRCH); /* abort, dequeue and put */
_debug("nuking active call %08x.%d",
- ntohl(call->conn->conn_id),ntohl(call->call_id));
+ ntohl(call->conn->conn_id),
+ ntohl(call->call_id));
rxrpc_put_call(call);
rxrpc_put_call(call);
@@ -376,6 +386,10 @@ void afscm_stop(void)
spin_lock(&kafscmd_attention_lock);
}
spin_unlock(&kafscmd_attention_lock);
+
+#ifdef AFS_AUTOMOUNT_SUPPORT
+ afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
+#endif
}
up_write(&afscm_sem);
@@ -490,7 +504,7 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
if (ret<0)
rxrpc_call_abort(call,ret);
- if (server) afs_put_server(server);
+ afs_put_server(server);
_leave(" = %d",ret);
@@ -556,7 +570,7 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
if (ret<0)
rxrpc_call_abort(call,ret);
- if (server) afs_put_server(server);
+ afs_put_server(server);
_leave(" = %d",ret);
@@ -622,7 +636,7 @@ static void _SRXAFSCM_Probe(struct rxrpc_call *call)
if (ret<0)
rxrpc_call_abort(call,ret);
- if (server) afs_put_server(server);
+ afs_put_server(server);
_leave(" = %d",ret);
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 30d3246cc91e..9d6a7104cc79 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -23,10 +23,11 @@
#include "super.h"
#include "internal.h"
-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
+static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd);
static int afs_dir_open(struct inode *inode, struct file *file);
static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
-static int afs_d_revalidate(struct dentry *dentry, struct nameidata *);
+static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
static int afs_d_delete(struct dentry *dentry);
static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, loff_t fpos,
ino_t ino, unsigned dtype);
@@ -70,7 +71,7 @@ typedef union afs_dirent {
u8 name[16];
u8 overflow[4]; /* if any char of the name (inc NUL) reaches here, consume
* the next dirent too */
- } parts;
+ } u;
u8 extended_name[32];
} afs_dirent_t;
@@ -256,7 +257,7 @@ static int afs_dir_iterate_block(unsigned *fpos,
/* got a valid entry */
dire = &block->dirents[offset];
- nlen = strnlen(dire->parts.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
+ nlen = strnlen(dire->u.name,sizeof(*block) - offset*sizeof(afs_dirent_t));
_debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n",
blkoff/sizeof(afs_dir_block_t),offset,
@@ -288,11 +289,11 @@ static int afs_dir_iterate_block(unsigned *fpos,
/* found the next entry */
ret = filldir(cookie,
- dire->parts.name,
+ dire->u.name,
nlen,
blkoff + offset * sizeof(afs_dirent_t),
- ntohl(dire->parts.vnode),
- filldir==afs_dir_lookup_filldir ? dire->parts.unique : DT_UNKNOWN);
+ ntohl(dire->u.vnode),
+ filldir==afs_dir_lookup_filldir ? dire->u.unique : DT_UNKNOWN);
if (ret<0) {
_leave(" = 0 [full]");
return 0;
@@ -414,7 +415,8 @@ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, lof
/*
* look up an entry in a directory
*/
-static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
{
struct afs_dir_lookup_cookie cookie;
struct afs_super_info *as;
@@ -423,11 +425,11 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, s
unsigned fpos;
int ret;
- _enter("{%lu},{%s}",dir->i_ino,dentry->d_name.name);
+ _enter("{%lu},%p{%s}",dir->i_ino,dentry,dentry->d_name.name);
/* insanity checks first */
- if (sizeof(afs_dir_block_t) != 2048) BUG();
- if (sizeof(afs_dirent_t) != 32) BUG();
+ BUG_ON(sizeof(afs_dir_block_t) != 2048);
+ BUG_ON(sizeof(afs_dirent_t) != 32);
if (dentry->d_name.len > 255) {
_leave(" = -ENAMETOOLONG");
@@ -495,9 +497,11 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
unsigned fpos;
int ret;
- _enter("%s,%p",dentry->d_name.name,nd);
+ _enter("{sb=%p n=%s},",dentry->d_sb,dentry->d_name.name);
+
+ /* lock down the parent dentry so we can peer at it */
+ parent = dget_parent(dentry->d_parent);
- parent = dget_parent(dentry);
dir = parent->d_inode;
inode = dentry->d_inode;
diff --git a/fs/afs/file.c b/fs/afs/file.c
index c0344ae61ef2..eeb9ff893635 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/buffer_head.h>
#include "volume.h"
#include "vnode.h"
#include <rxrpc/call.h>
@@ -27,6 +28,8 @@ static int afs_file_release(struct inode *inode, struct file *file);
#endif
static int afs_file_readpage(struct file *file, struct page *page);
+static int afs_file_invalidatepage(struct page *page, unsigned long offset);
+static int afs_file_releasepage(struct page *page, int gfp_flags);
static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off);
@@ -37,7 +40,7 @@ struct inode_operations afs_file_inode_operations = {
struct file_operations afs_file_file_operations = {
.read = generic_file_read,
.write = afs_file_write,
- .mmap = generic_file_readonly_mmap,
+ .mmap = generic_file_mmap,
#if 0
.open = afs_file_open,
.release = afs_file_release,
@@ -47,6 +50,10 @@ struct file_operations afs_file_file_operations = {
struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
+ .sync_page = block_sync_page,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+ .releasepage = afs_file_releasepage,
+ .invalidatepage = afs_file_invalidatepage,
};
/*****************************************************************************/
@@ -66,11 +73,48 @@ static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, l
/*****************************************************************************/
/*
+ * deal with notification that a page was read from the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_file_readpage_read_complete(void *cookie_data, struct page *page, void *data,
+ int error)
+{
+ _enter("%p,%p,%p,%d",cookie_data,page,data,error);
+
+ if (error)
+ SetPageError(page);
+ else
+ SetPageUptodate(page);
+ unlock_page(page);
+
+} /* end afs_file_readpage_read_complete() */
+#endif
+
+/*****************************************************************************/
+/*
+ * deal with notification that a page was written to the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_file_readpage_write_complete(void *cookie_data, struct page *page, void *data,
+ int error)
+{
+ _enter("%p,%p,%p,%d",cookie_data,page,data,error);
+
+ unlock_page(page);
+
+} /* end afs_file_readpage_write_complete() */
+#endif
+
+/*****************************************************************************/
+/*
* AFS read page from file (or symlink)
*/
static int afs_file_readpage(struct file *file, struct page *page)
{
struct afs_rxfs_fetch_descriptor desc;
+#ifdef AFS_CACHING_SUPPORT
+ struct cachefs_page *pageio;
+#endif
struct inode *inode;
afs_vnode_t *vnode;
int ret;
@@ -88,28 +132,73 @@ static int afs_file_readpage(struct file *file, struct page *page)
if (vnode->flags & AFS_VNODE_DELETED)
goto error;
- /* work out how much to get and from where */
- desc.fid = vnode->fid;
- desc.offset = page->index << PAGE_CACHE_SHIFT;
- desc.size = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
- desc.buffer = kmap(page);
-
- clear_page(desc.buffer);
-
- /* read the contents of the file from the server into the page */
- ret = afs_vnode_fetch_data(vnode,&desc);
- kunmap(page);
- if (ret<0) {
- if (ret==-ENOENT) {
- _debug("got NOENT from server - marking file deleted and stale");
- vnode->flags |= AFS_VNODE_DELETED;
- ret = -ESTALE;
- }
+#ifdef AFS_CACHING_SUPPORT
+ ret = cachefs_page_get_private(page,&pageio,GFP_NOIO);
+ if (ret<0)
goto error;
- }
- SetPageUptodate(page);
- unlock_page(page);
+ /* is it cached? */
+ ret = cachefs_read_or_alloc_page(vnode->cache,
+ page,
+ afs_file_readpage_read_complete,
+ NULL,
+ GFP_KERNEL);
+#else
+ ret = -ENOBUFS;
+#endif
+
+ switch (ret) {
+ /* read BIO submitted and wb-journal entry found */
+ case 1:
+ BUG(); // TODO - handle wb-journal match
+
+ /* read BIO submitted (page in cache) */
+ case 0:
+ break;
+
+ /* no page available in cache */
+ case -ENOBUFS:
+ case -ENODATA:
+ default:
+ desc.fid = vnode->fid;
+ desc.offset = page->index << PAGE_CACHE_SHIFT;
+ desc.size = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE);
+ desc.buffer = kmap(page);
+
+ clear_page(desc.buffer);
+
+ /* read the contents of the file from the server into the page */
+ ret = afs_vnode_fetch_data(vnode,&desc);
+ kunmap(page);
+ if (ret<0) {
+ if (ret==-ENOENT) {
+ _debug("got NOENT from server - marking file deleted and stale");
+ vnode->flags |= AFS_VNODE_DELETED;
+ ret = -ESTALE;
+ }
+
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_uncache_page(vnode->cache,page);
+#endif
+ goto error;
+ }
+
+ SetPageUptodate(page);
+
+#ifdef AFS_CACHING_SUPPORT
+ if (cachefs_write_page(vnode->cache,
+ page,
+ afs_file_readpage_write_complete,
+ NULL,
+ GFP_KERNEL) != 0
+ ) {
+ cachefs_uncache_page(vnode->cache,page);
+ unlock_page(page);
+ }
+#else
+ unlock_page(page);
+#endif
+ }
_leave(" = 0");
return 0;
@@ -122,3 +211,83 @@ static int afs_file_readpage(struct file *file, struct page *page)
return ret;
} /* end afs_file_readpage() */
+
+/*****************************************************************************/
+/*
+ * get a page cookie for the specified page
+ */
+#ifdef AFS_CACHING_SUPPORT
+int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie)
+{
+ int ret;
+
+ _enter("");
+ ret = cachefs_page_get_private(page,_page_cookie,GFP_NOIO);
+
+ _leave(" = %d",ret);
+ return ret;
+} /* end afs_cache_get_page_cookie() */
+#endif
+
+/*****************************************************************************/
+/*
+ * invalidate part or all of a page
+ */
+static int afs_file_invalidatepage(struct page *page, unsigned long offset)
+{
+ int ret = 1;
+
+ _enter("{%lu},%lu",page->index,offset);
+
+ BUG_ON(!PageLocked(page));
+ if (PagePrivate(page)) {
+#ifdef AFS_CACHING_SUPPORT
+ struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
+ cachefs_uncache_page(vnode->cache,page);
+#endif
+
+ /*
+ * We release buffers only if the entire page is being invalidated.
+ * The get_block cached value has been unconditionally invalidated,
+ * so real IO is not possible anymore.
+ */
+ if (offset == 0) {
+ BUG_ON(!PageLocked(page));
+
+ ret = 0;
+ if (!PageWriteback(page))
+ ret = page->mapping->a_ops->releasepage(page, 0);
+ }
+ }
+
+ _leave(" = %d",ret);
+ return ret;
+} /* end afs_file_invalidatepage() */
+
+/*****************************************************************************/
+/*
+ * release a page and cleanup its private data
+ */
+static int afs_file_releasepage(struct page *page, int gfp_flags)
+{
+ struct cachefs_page *pageio;
+
+ _enter("{%lu},%x",page->index,gfp_flags);
+
+ if (PagePrivate(page)) {
+#ifdef AFS_CACHING_SUPPORT
+ struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
+ cachefs_uncache_page(vnode->cache,page);
+#endif
+
+ pageio = (struct cachefs_page *) page->private;
+ page->private = 0;
+ ClearPagePrivate(page);
+
+ if (pageio)
+ kfree(pageio);
+ }
+
+ _leave(" = 0");
+ return 0;
+} /* end afs_file_releasepage() */
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 1c83000f2c3d..a9c253e67003 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -69,17 +69,16 @@ static int afs_inode_map_status(afs_vnode_t *vnode)
inode->i_uid = vnode->status.owner;
inode->i_gid = 0;
inode->i_size = vnode->status.size;
- inode->i_atime.tv_sec = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = vnode->status.mtime_server;
- inode->i_atime.tv_nsec =
- inode->i_mtime.tv_nsec =
- inode->i_ctime.tv_nsec = 0;
+ inode->i_ctime.tv_sec = vnode->status.mtime_server;
+ inode->i_ctime.tv_nsec = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_version = vnode->fid.unique;
inode->i_mapping->a_ops = &afs_fs_aops;
/* check to see whether a symbolic link is really a mountpoint */
- if (vnode->status.type==AFS_FTYPE_SYMLINK) {
+ if (vnode->status.type == AFS_FTYPE_SYMLINK) {
afs_mntpt_check_symlink(vnode);
if (vnode->flags & AFS_VNODE_MOUNTPOINT) {
@@ -105,7 +104,7 @@ int afs_inode_fetch_status(struct inode *inode)
ret = afs_vnode_fetch_status(vnode);
- if (ret==0)
+ if (ret == 0)
ret = afs_inode_map_status(vnode);
return ret;
@@ -120,8 +119,8 @@ static int afs_iget5_test(struct inode *inode, void *opaque)
{
struct afs_iget_data *data = opaque;
- /* only match inodes with the same version number */
- return inode->i_ino==data->fid.vnode && inode->i_version==data->fid.unique;
+ return inode->i_ino == data->fid.vnode &&
+ inode->i_version == data->fid.unique;
} /* end afs_iget5_test() */
/*****************************************************************************/
@@ -145,20 +144,22 @@ static int afs_iget5_set(struct inode *inode, void *opaque)
/*
* inode retrieval
*/
-inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode)
+inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
+ struct inode **_inode)
{
- struct afs_iget_data data = { .fid = *fid };
+ struct afs_iget_data data = { fid: *fid };
struct afs_super_info *as;
+ struct afs_vnode *vnode;
struct inode *inode;
- afs_vnode_t *vnode;
int ret;
- _enter(",{%u,%u,%u},,",fid->vid,fid->vnode,fid->unique);
+ _enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique);
as = sb->s_fs_info;
data.volume = as->volume;
- inode = iget5_locked(sb,fid->vnode,afs_iget5_test,afs_iget5_set,&data);
+ inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
+ &data);
if (!inode) {
_leave(" = -ENOMEM");
return -ENOMEM;
@@ -173,10 +174,19 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inod
*_inode = inode;
else
iput(inode);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
}
+#ifdef AFS_CACHING_SUPPORT
+ /* set up caching before reading the status, as fetch-status reads the
+ * first page of symlinks to see if they're really mntpts */
+ cachefs_acquire_cookie(vnode->volume->cache,
+ NULL,
+ vnode,
+ &vnode->cache);
+#endif
+
/* okay... it's a new inode */
vnode->flags |= AFS_VNODE_CHANGED;
ret = afs_inode_fetch_status(inode);
@@ -187,11 +197,11 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inod
unlock_new_inode(inode);
*_inode = inode;
- _leave(" = 0 [CB { v=%u x=%lu t=%u nix=%u }]",
+ _leave(" = 0 [CB { v=%u x=%lu t=%u } c=%p]",
vnode->cb_version,
vnode->cb_timeout.timo_jif,
vnode->cb_type,
- vnode->nix
+ vnode->cache
);
return 0;
@@ -201,7 +211,7 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inod
unlock_new_inode(inode);
iput(inode);
- _leave(" = %d [bad]",ret);
+ _leave(" = %d [bad]", ret);
return ret;
} /* end afs_iget() */
@@ -209,7 +219,8 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inod
/*
* read the attributes of an inode
*/
-int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
{
struct inode *inode;
afs_vnode_t *vnode;
@@ -217,23 +228,25 @@ int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
inode = dentry->d_inode;
- _enter("{ ino=%lu v=%lu }",inode->i_ino,inode->i_version);
+ _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version);
vnode = AFS_FS_I(inode);
ret = afs_inode_fetch_status(inode);
- if (ret==-ENOENT) {
- _leave(" = %d [%d %p]",ret,atomic_read(&dentry->d_count),dentry->d_inode);
+ if (ret == -ENOENT) {
+ _leave(" = %d [%d %p]",
+ ret, atomic_read(&dentry->d_count), dentry->d_inode);
return ret;
}
- else if (ret<0) {
+ else if (ret < 0) {
make_bad_inode(inode);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
}
- /* transfer attributes from the inode structure to the stat structure */
- generic_fillattr(inode,stat);
+ /* transfer attributes from the inode structure to the stat
+ * structure */
+ generic_fillattr(inode, stat);
_leave(" = 0 CB { v=%u x=%u t=%u }",
vnode->cb_version,
@@ -261,9 +274,14 @@ void afs_clear_inode(struct inode *inode)
vnode->cb_type
);
- if (inode->i_ino!=vnode->fid.vnode) BUG();
+ BUG_ON(inode->i_ino != vnode->fid.vnode);
afs_vnode_give_up_callback(vnode);
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_relinquish_cookie(vnode->cache, 0);
+ vnode->cache = NULL;
+#endif
+
_leave("");
} /* end afs_clear_inode() */
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 068f98071456..b5279c59bc2f 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -26,7 +26,7 @@
#define kproto(FMT, a...) printk("### "FMT"\n" , ## a)
#define knet(FMT, a...) printk(FMT"\n" , ## a)
-#if 0
+#ifdef __KDEBUG
#define _enter(FMT, a...) kenter(FMT , ## a)
#define _leave(FMT, a...) kleave(FMT , ## a)
#define _debug(FMT, a...) kdebug(FMT , ## a)
@@ -56,6 +56,9 @@ static inline void afs_discard_my_signals(void)
*/
extern struct rw_semaphore afs_proc_cells_sem;
extern struct list_head afs_proc_cells;
+#ifdef AFS_CACHING_SUPPORT
+extern struct cachefs_index_def afs_cache_cell_index_def;
+#endif
/*
* dir.c
@@ -70,6 +73,10 @@ extern struct address_space_operations afs_fs_aops;
extern struct inode_operations afs_file_inode_operations;
extern struct file_operations afs_file_file_operations;
+#ifdef AFS_CACHING_SUPPORT
+extern int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie);
+#endif
+
/*
* inode.c
*/
@@ -78,10 +85,22 @@ extern int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
extern void afs_clear_inode(struct inode *inode);
/*
+ * main.c
+ */
+#ifdef AFS_CACHING_SUPPORT
+extern struct cachefs_netfs afs_cache_netfs;
+#endif
+
+/*
* mntpt.c
*/
extern struct inode_operations afs_mntpt_inode_operations;
extern struct file_operations afs_mntpt_file_operations;
+#ifdef AFS_AUTOMOUNT_SUPPORT
+extern struct afs_timer afs_mntpt_expiry_timer;
+extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
+extern unsigned long afs_mntpt_expiry_timeout;
+#endif
extern int afs_mntpt_check_symlink(afs_vnode_t *vnode);
diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
index 0af8f31477e5..dc6505578f8d 100644
--- a/fs/afs/kafsasyncd.c
+++ b/fs/afs/kafsasyncd.c
@@ -153,8 +153,7 @@ static int kafsasyncd(void *arg)
spin_lock(&kafsasyncd_async_lock);
/* fold the busy and attention queues together */
- list_splice(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
- list_del_init(&kafsasyncd_async_busyq);
+ list_splice_init(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq);
/* dequeue kafsasyncd from all their wait queues */
list_for_each(_p,&kafsasyncd_async_attnq) {
@@ -197,6 +196,7 @@ void afs_kafsasyncd_begin_op(afs_async_op_t *op)
spin_lock(&kafsasyncd_async_lock);
init_waitqueue_entry(&op->waiter,kafsasyncd_task);
+ add_wait_queue(&op->call->waitq,&op->waiter);
list_del(&op->link);
list_add_tail(&op->link,&kafsasyncd_async_busyq);
@@ -238,7 +238,10 @@ void afs_kafsasyncd_terminate_op(afs_async_op_t *op)
spin_lock(&kafsasyncd_async_lock);
- list_del_init(&op->link);
+ if (!list_empty(&op->link)) {
+ list_del_init(&op->link);
+ remove_wait_queue(&op->call->waitq,&op->waiter);
+ }
spin_unlock(&kafsasyncd_async_lock);
diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
index 0963711ac015..81b73a8ead4b 100644
--- a/fs/afs/kafstimod.c
+++ b/fs/afs/kafstimod.c
@@ -82,7 +82,7 @@ static int kafstimod(void *arg)
for (;;) {
unsigned long jif;
- unsigned long timeout;
+ signed long timeout;
/* deal with the server being asked to die */
if (kafstimod_die) {
@@ -98,18 +98,18 @@ static int kafstimod(void *arg)
spin_lock(&kafstimod_lock);
if (list_empty(&kafstimod_list)) {
timeout = MAX_SCHEDULE_TIMEOUT;
- } else {
- unsigned long tmo;
-
- timer = list_entry(kafstimod_list.next,
- afs_timer_t, link);
- tmo = timer->timo_jif;
+ }
+ else {
+ timer = list_entry(kafstimod_list.next,afs_timer_t,link);
+ timeout = timer->timo_jif;
jif = jiffies;
- if (time_before_eq(tmo,jif))
+ if (time_before_eq((unsigned long)timeout,jif))
goto immediate;
- timeout = (long)tmo - (long)jiffies;
+ else {
+ timeout = (long)timeout - (long)jiffies;
+ }
}
spin_unlock(&kafstimod_lock);
@@ -170,7 +170,7 @@ void afs_kafstimod_add_timer(afs_timer_t *timer, unsigned long timeout)
wake_up(&kafstimod_sleepq);
_leave("");
-} /* end afs_kafstimod_queue_vlocation() */
+} /* end afs_kafstimod_add_timer() */
/*****************************************************************************/
/*
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 2a2e4b60a4ef..f31b28c05ab7 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -17,6 +17,7 @@
#include <rxrpc/transport.h>
#include <rxrpc/call.h>
#include <rxrpc/peer.h>
+#include "cache.h"
#include "cell.h"
#include "server.h"
#include "fsclient.h"
@@ -47,6 +48,18 @@ static struct rxrpc_peer_ops afs_peer_ops = {
struct list_head afs_cb_hash_tbl[AFS_CB_HASH_COUNT];
spinlock_t afs_cb_hash_lock = SPIN_LOCK_UNLOCKED;
+#ifdef AFS_CACHING_SUPPORT
+static struct cachefs_netfs_operations afs_cache_ops = {
+ .get_page_cookie = afs_cache_get_page_cookie,
+};
+
+struct cachefs_netfs afs_cache_netfs = {
+ .name = "afs",
+ .version = 0,
+ .ops = &afs_cache_ops,
+};
+#endif
+
/*****************************************************************************/
/*
* initialise the AFS client FS module
@@ -64,34 +77,41 @@ static int afs_init(void)
/* register the /proc stuff */
ret = afs_proc_init();
- if (ret<0)
+ if (ret < 0)
return ret;
+#ifdef AFS_CACHING_SUPPORT
+ /* we want to be able to cache */
+ ret = cachefs_register_netfs(&afs_cache_netfs,&afs_cache_cell_index_def);
+ if (ret < 0)
+ goto error;
+#endif
+
/* initialise the cell DB */
ret = afs_cell_init();
- if (ret<0)
- goto error;
+ if (ret < 0)
+ goto error_cache;
/* start the timeout daemon */
ret = afs_kafstimod_start();
- if (ret<0)
- goto error;
+ if (ret < 0)
+ goto error_cache;
/* start the async operation daemon */
ret = afs_kafsasyncd_start();
- if (ret<0)
+ if (ret < 0)
goto error_kafstimod;
/* create the RxRPC transport */
ret = rxrpc_create_transport(7001,&afs_transport);
- if (ret<0)
+ if (ret < 0)
goto error_kafsasyncd;
afs_transport->peer_ops = &afs_peer_ops;
/* register the filesystems */
ret = afs_fs_init();
- if (ret<0)
+ if (ret < 0)
goto error_transport;
return ret;
@@ -102,7 +122,11 @@ static int afs_init(void)
afs_kafsasyncd_stop();
error_kafstimod:
afs_kafstimod_stop();
+ error_cache:
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_unregister_netfs(&afs_cache_netfs);
error:
+#endif
afs_cell_purge();
afs_proc_cleanup();
printk(KERN_ERR "kAFS: failed to register: %d\n",ret);
@@ -122,6 +146,9 @@ static void __exit afs_exit(void)
afs_kafstimod_stop();
afs_kafsasyncd_stop();
afs_cell_purge();
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_unregister_netfs(&afs_cache_netfs);
+#endif
afs_proc_cleanup();
} /* end afs_exit() */
@@ -142,7 +169,7 @@ static int afs_adding_peer(struct rxrpc_peer *peer)
/* determine which server the peer resides in (if any) */
ret = afs_server_find_by_peer(peer,&server);
- if (ret<0)
+ if (ret < 0)
return ret; /* none that we recognise, so abort */
_debug("Server %p{u=%d}\n",server,atomic_read(&server->usage));
@@ -191,3 +218,48 @@ static void afs_discarding_peer(struct rxrpc_peer *peer)
_leave("");
} /* end afs_discarding_peer() */
+
+/*****************************************************************************/
+/*
+ * clear the dead space between task_struct and kernel stack
+ * - called by supplying -finstrument-functions to gcc
+ */
+#if 0
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+{
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xedededed,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+{
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xdadadada,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
+#endif
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index d22887d47f38..93082fa5771e 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -16,24 +16,52 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/namespace.h>
+#include "super.h"
+#include "cell.h"
#include "volume.h"
#include "vnode.h"
#include "internal.h"
-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
+static struct dentry *afs_mntpt_lookup(struct inode *dir,
+ struct dentry *dentry,
+ struct nameidata *nd);
static int afs_mntpt_open(struct inode *inode, struct file *file);
+#ifdef AFS_AUTOMOUNT_SUPPORT
+static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
+#endif
+
struct file_operations afs_mntpt_file_operations = {
.open = afs_mntpt_open,
};
struct inode_operations afs_mntpt_inode_operations = {
.lookup = afs_mntpt_lookup,
+#ifdef AFS_AUTOMOUNT_SUPPORT
+ .follow_link = afs_mntpt_follow_link,
+#endif
.readlink = page_readlink,
.getattr = afs_inode_getattr,
};
+#ifdef AFS_AUTOMOUNT_SUPPORT
+static LIST_HEAD(afs_vfsmounts);
+
+static void afs_mntpt_expiry_timed_out(struct afs_timer *timer);
+
+struct afs_timer_ops afs_mntpt_expiry_timer_ops = {
+ .timed_out = afs_mntpt_expiry_timed_out,
+};
+
+struct afs_timer afs_mntpt_expiry_timer;
+
+unsigned long afs_mntpt_expiry_timeout = 20;
+#endif
+
/*****************************************************************************/
/*
* check a symbolic link to see whether it actually encodes a mountpoint
@@ -93,8 +121,17 @@ int afs_mntpt_check_symlink(afs_vnode_t *vnode)
/*
* no valid lookup procedure on this sort of dir
*/
-static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *afs_mntpt_lookup(struct inode *dir,
+ struct dentry *dentry,
+ struct nameidata *nd)
{
+ kenter("%p,%p{%p{%s},%s}",
+ dir,
+ dentry,
+ dentry->d_parent,
+ dentry->d_parent ? dentry->d_parent->d_name.name : (const unsigned char*)"",
+ dentry->d_name.name);
+
return ERR_PTR(-EREMOTE);
} /* end afs_mntpt_lookup() */
@@ -104,5 +141,146 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry,
*/
static int afs_mntpt_open(struct inode *inode, struct file *file)
{
+ kenter("%p,%p{%p{%s},%s}",
+ inode, file,
+ file->f_dentry->d_parent,
+ file->f_dentry->d_parent ? file->f_dentry->d_parent->d_name.name : (const unsigned char*)"",
+ file->f_dentry->d_name.name);
+
return -EREMOTE;
} /* end afs_mntpt_open() */
+
+#ifdef AFS_AUTOMOUNT_SUPPORT
+/*****************************************************************************/
+/*
+ * create a vfsmount to be automounted
+ */
+static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
+{
+ struct afs_super_info *super;
+ struct vfsmount *mnt;
+ struct page *page = NULL;
+ size_t size;
+ char *buf, *devname = NULL, *options = NULL;
+ int ret;
+
+ kenter("{%s}", mntpt->d_name.name);
+
+ BUG_ON(!mntpt->d_inode);
+
+ ret = -EINVAL;
+ size = mntpt->d_inode->i_size;
+ if (size > PAGE_SIZE - 1)
+ goto error;
+
+ ret = -ENOMEM;
+ devname = (char *) get_zeroed_page(GFP_KERNEL);
+ if (!devname)
+ goto error;
+
+ options = (char *) get_zeroed_page(GFP_KERNEL);
+ if (!options)
+ goto error;
+
+ /* read the contents of the AFS special symlink */
+ page = read_cache_page(mntpt->d_inode->i_mapping,
+ 0,
+ (filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage,
+ NULL);
+ if (IS_ERR(page)) {
+ ret = PTR_ERR(page);
+ goto error;
+ }
+
+ ret = -EIO;
+ wait_on_page_locked(page);
+ if (!PageUptodate(page) || PageError(page))
+ goto error;
+
+ buf = kmap(page);
+ memcpy(devname, buf, size);
+ kunmap(page);
+ page_cache_release(page);
+ page = NULL;
+
+ /* work out what options we want */
+ super = AFS_FS_S(mntpt->d_sb);
+ memcpy(options, "cell=", 5);
+ strcpy(options + 5, super->volume->cell->name);
+ if (super->volume->type == AFSVL_RWVOL)
+ strcat(options,",rwpath");
+
+ /* try and do the mount */
+ kdebug("--- attempting mount %s -o %s ---", devname, options);
+ mnt = do_kern_mount("afs", 0, devname, options);
+ kdebug("--- mount result %p ---", mnt);
+
+ free_page((unsigned long)devname);
+ free_page((unsigned long)options);
+ kleave(" = %p",mnt);
+ return mnt;
+
+ error:
+ if (page)
+ page_cache_release(page);
+ if (devname)
+ free_page((unsigned long)devname);
+ if (options)
+ free_page((unsigned long)options);
+ kleave(" = %d",ret);
+ return ERR_PTR(ret);
+} /* end afs_mntpt_do_automount() */
+
+/*****************************************************************************/
+/*
+ * follow a link from a mountpoint directory, thus causing it to be mounted
+ */
+static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ struct nameidata newnd;
+ struct vfsmount *newmnt;
+ int err;
+
+ kenter("%p{%s},{%s:%p{%s}}",
+ dentry,
+ dentry->d_name.name,
+ nd->mnt->mnt_devname,
+ dentry,
+ nd->dentry->d_name.name);
+
+ newmnt = afs_mntpt_do_automount(dentry);
+ if (IS_ERR(newmnt))
+ return PTR_ERR(newmnt);
+
+ struct_cpy(&newnd,nd);
+ newnd.dentry = dentry;
+ err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts);
+
+ if (!err) {
+ path_release(nd);
+ mntget(newmnt);
+ nd->mnt = newmnt;
+ dget(newmnt->mnt_root);
+ nd->dentry = newmnt->mnt_root;
+ }
+
+ kleave(" = %d", err);
+ return err;
+} /* end afs_mntpt_follow_link() */
+
+/*****************************************************************************/
+/*
+ * handle mountpoint expiry timer going off
+ */
+static void afs_mntpt_expiry_timed_out(struct afs_timer *timer)
+{
+ kenter("");
+
+ mark_mounts_for_expiry(&afs_vfsmounts);
+
+ afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
+ afs_mntpt_expiry_timeout * HZ);
+
+ kleave("");
+} /* end afs_mntpt_expiry_timed_out() */
+#endif
diff --git a/fs/afs/mount.h b/fs/afs/mount.h
index fbdd77878546..9d2f46ec549f 100644
--- a/fs/afs/mount.h
+++ b/fs/afs/mount.h
@@ -17,7 +17,7 @@ struct afs_mountdata {
const char *cell; /* name of cell containing volume */
const char *cache; /* name of cache block device */
size_t nservers; /* number of server addresses listed */
- u_int32_t servers[10]; /* IP addresses of servers in this cell */
+ uint32_t servers[10]; /* IP addresses of servers in this cell */
};
#endif /* _LINUX_AFS_MOUNT_H */
diff --git a/fs/afs/server.c b/fs/afs/server.c
index b249d7cc3261..0d9d404b1d6f 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -148,6 +148,9 @@ void afs_put_server(afs_server_t *server)
{
afs_cell_t *cell;
+ if (!server)
+ return;
+
_enter("%p",server);
cell = server->cell;
diff --git a/fs/afs/super.c b/fs/afs/super.c
index d7fd182b9902..ac65a1fb6009 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -29,15 +29,22 @@
#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
+struct afs_mount_params {
+ int rwpath;
+ struct afs_cell *default_cell;
+ struct afs_volume *volume;
+};
+
static inline char *strdup(const char *s)
{
- char *ns = kmalloc(strlen(s)+1,GFP_KERNEL);
+ char *ns = kmalloc(strlen(s) + 1, GFP_KERNEL);
if (ns)
- strcpy(ns,s);
+ strcpy(ns, s);
return ns;
}
-static void afs_i_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags);
+static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
+ unsigned long flags);
static struct super_block *afs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name,
@@ -66,6 +73,7 @@ static struct super_operations afs_super_ops = {
};
static kmem_cache_t *afs_inode_cachep;
+static atomic_t afs_count_active_inodes;
/*****************************************************************************/
/*
@@ -75,16 +83,22 @@ int __init afs_fs_init(void)
{
int ret;
- kenter("");
+ _enter("");
+
+#ifdef AFS_AUTOMOUNT_SUPPORT
+ afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops);
+#endif
/* create ourselves an inode cache */
+ atomic_set(&afs_count_active_inodes, 0);
+
ret = -ENOMEM;
afs_inode_cachep = kmem_cache_create("afs_inode_cache",
- sizeof(afs_vnode_t),
- 0,
- SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
- afs_i_init_once,
- NULL);
+ sizeof(afs_vnode_t),
+ 0,
+ SLAB_HWCACHE_ALIGN,
+ afs_i_init_once,
+ NULL);
if (!afs_inode_cachep) {
printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
return ret;
@@ -92,9 +106,9 @@ int __init afs_fs_init(void)
/* now export our filesystem to lesser mortals */
ret = register_filesystem(&afs_fs_type);
- if (ret<0) {
+ if (ret < 0) {
kmem_cache_destroy(afs_inode_cachep);
- kleave(" = %d",ret);
+ kleave(" = %d", ret);
return ret;
}
@@ -108,11 +122,16 @@ int __init afs_fs_init(void)
*/
void __exit afs_fs_exit(void)
{
- /* destroy our private inode cache */
- kmem_cache_destroy(afs_inode_cachep);
-
unregister_filesystem(&afs_fs_type);
+ if (atomic_read(&afs_count_active_inodes) != 0) {
+ printk("kAFS: %d active inode objects still present\n",
+ atomic_read(&afs_count_active_inodes));
+ BUG();
+ }
+
+ kmem_cache_destroy(afs_inode_cachep);
+
} /* end afs_fs_exit() */
/*****************************************************************************/
@@ -122,7 +141,7 @@ void __exit afs_fs_exit(void)
static int want_arg(char **_value, const char *option)
{
if (!_value || !*_value || !**_value) {
- printk(KERN_NOTICE "kAFS: %s: argument missing\n",option);
+ printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
return 0;
}
return 1;
@@ -130,27 +149,13 @@ static int want_arg(char **_value, const char *option)
/*****************************************************************************/
/*
- * check that there is a value
- */
-#if 0
-static int want_value(char **_value, const char *option)
-{
- if (!_value || !*_value || !**_value) {
- printk(KERN_NOTICE "kAFS: %s: argument incomplete\n",option);
- return 0;
- }
- return 1;
-} /* end want_value() */
-#endif
-
-/*****************************************************************************/
-/*
* check that there's no subsequent value
*/
static int want_no_value(char *const *_value, const char *option)
{
if (*_value && **_value) {
- printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",option,*_value);
+ printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
+ option, *_value);
return 0;
}
return 1;
@@ -158,150 +163,55 @@ static int want_no_value(char *const *_value, const char *option)
/*****************************************************************************/
/*
- * extract a number from an option string value
- */
-#if 0
-static int want_number(char **_value, const char *option, unsigned long *number,
- unsigned long limit)
-{
- char *value = *_value;
-
- if (!want_value(_value,option))
- return 0;
-
- *number = simple_strtoul(value,_value,0);
-
- if (value==*_value) {
- printk(KERN_NOTICE "kAFS: %s: Invalid number: %s\n",option,value);
- return 0;
- }
-
- if (*number>limit) {
- printk(KERN_NOTICE "kAFS: %s: numeric value %lu > %lu\n",option,*number,limit);
- return 0;
- }
-
- return 1;
-} /* end want_number() */
-#endif
-
-/*****************************************************************************/
-/*
- * extract a separator from an option string value
- */
-#if 0
-static int want_sep(char **_value, const char *option, char sep)
-{
- if (!want_value(_value,option))
- return 0;
-
- if (*(*_value)++ != sep) {
- printk(KERN_NOTICE "kAFS: %s: '%c' expected: %s\n",option,sep,*_value-1);
- return 0;
- }
-
- return 1;
-} /* end want_number() */
-#endif
-
-/*****************************************************************************/
-/*
- * extract an IP address from an option string value
- */
-#if 0
-static int want_ipaddr(char **_value, const char *option, struct in_addr *addr)
-{
- unsigned long number[4];
-
- if (!want_value(_value,option))
- return 0;
-
- if (!want_number(_value,option,&number[0],255) ||
- !want_sep(_value,option,'.') ||
- !want_number(_value,option,&number[1],255) ||
- !want_sep(_value,option,'.') ||
- !want_number(_value,option,&number[2],255) ||
- !want_sep(_value,option,'.') ||
- !want_number(_value,option,&number[3],255))
- return 0;
-
- ((u8*)addr)[0] = number[0];
- ((u8*)addr)[1] = number[1];
- ((u8*)addr)[2] = number[2];
- ((u8*)addr)[3] = number[3];
-
- return 1;
-} /* end want_numeric() */
-#endif
-
-/*****************************************************************************/
-/*
* parse the mount options
* - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from
* the msdos fs
*/
-static int afs_super_parse_options(struct afs_super_info *as, char *options, const char ** devname)
+static int afs_super_parse_options(struct afs_mount_params *params,
+ char *options,
+ const char **devname)
{
char *key, *value;
int ret;
- _enter("%s",options);
+ _enter("%s", options);
+
+ options[PAGE_SIZE - 1] = 0;
ret = 0;
- while ((key = strsep(&options,",")))
+ while ((key = strsep(&options, ",")))
{
- value = strchr(key,'=');
+ value = strchr(key, '=');
if (value)
*value++ = 0;
- printk("kAFS: KEY: %s, VAL:%s\n",key,value?:"-");
+ printk("kAFS: KEY: %s, VAL:%s\n", key, value ?: "-");
- if (strcmp(key,"rwpath")==0) {
- if (!want_no_value(&value,"rwpath")) return -EINVAL;
- as->rwparent = 1;
+ if (strcmp(key, "rwpath") == 0) {
+ if (!want_no_value(&value, "rwpath"))
+ return -EINVAL;
+ params->rwpath = 1;
continue;
}
- else if (strcmp(key,"vol")==0) {
- if (!want_arg(&value,"vol")) return -EINVAL;
+ else if (strcmp(key, "vol") == 0) {
+ if (!want_arg(&value, "vol"))
+ return -EINVAL;
*devname = value;
continue;
}
-
-#if 0
- if (strcmp(key,"servers")==0) {
- if (!want_arg(&value,"servers")) return -EINVAL;
-
- _debug("servers=%s",value);
-
- for (;;) {
- struct in_addr addr;
-
- if (!want_ipaddr(&value,"servers",&addr))
- return -EINVAL;
-
- ret = afs_create_server(as->cell,&addr,&as->server);
- if (ret<0) {
- printk("kAFS: unable to create server: %d\n",ret);
- return ret;
- }
-
- if (!*value)
- break;
-
- if (as->server) {
- printk(KERN_NOTICE
- "kAFS: only one server can be specified\n");
- return -EINVAL;
- }
-
- if (!want_sep(&value,"servers",':'))
- return -EINVAL;
- }
+ else if (strcmp(key, "cell") == 0) {
+ if (!want_arg(&value, "cell"))
+ return -EINVAL;
+ afs_put_cell(params->default_cell);
+ ret = afs_cell_lookup(value,
+ strlen(value),
+ &params->default_cell);
+ if (ret < 0)
+ return -EINVAL;
continue;
}
-#endif
- printk("kAFS: Unknown mount option: '%s'\n",key);
+ printk("kAFS: Unknown mount option: '%s'\n", key);
ret = -EINVAL;
goto error;
}
@@ -309,67 +219,48 @@ static int afs_super_parse_options(struct afs_super_info *as, char *options, con
ret = 0;
error:
- _leave(" = %d",ret);
-
+ _leave(" = %d", ret);
return ret;
} /* end afs_super_parse_options() */
-struct fill_super_options {
- const char *dev_name;
- void *options;
-};
+/*****************************************************************************/
+/*
+ * check a superblock to see if it's the one we're looking for
+ */
+static int afs_test_super(struct super_block *sb, void *data)
+{
+ struct afs_mount_params *params = data;
+ struct afs_super_info *as = sb->s_fs_info;
+
+ return as->volume == params->volume;
+} /* end afs_test_super() */
/*****************************************************************************/
/*
* fill in the superblock
*/
-static int afs_fill_super(struct super_block *sb, void *_data, int silent)
+static int afs_fill_super(struct super_block *sb, void *data, int silent)
{
+ struct afs_mount_params *params = data;
struct afs_super_info *as = NULL;
struct dentry *root = NULL;
struct inode *inode = NULL;
afs_fid_t fid;
- struct fill_super_options *data = _data;
- const char *devname;
- char *options;
int ret;
- _enter("");
-
- if (!data) {
- _leave(" = -EINVAL");
- return -EINVAL;
- }
- devname = data->dev_name;
- options = data->options;
- if (options)
- options[PAGE_SIZE-1] = 0;
+ kenter("");
/* allocate a superblock info record */
- as = kmalloc(sizeof(struct afs_super_info),GFP_KERNEL);
+ as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL);
if (!as) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
- memset(as,0,sizeof(struct afs_super_info));
-
- /* parse the options */
- if (options) {
- ret = afs_super_parse_options(as,options,&devname);
- if (ret<0)
- goto error;
- if (!devname) {
- printk("kAFS: no volume name specified\n");
- ret = -EINVAL;
- goto error;
- }
- }
+ memset(as, 0, sizeof(struct afs_super_info));
- /* parse the device name */
- ret = afs_volume_lookup(devname,as->rwparent,&as->volume);
- if (ret<0)
- goto error;
+ afs_get_volume(params->volume);
+ as->volume = params->volume;
/* fill in the superblock */
sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -382,8 +273,8 @@ static int afs_fill_super(struct super_block *sb, void *_data, int silent)
fid.vid = as->volume->vid;
fid.vnode = 1;
fid.unique = 1;
- ret = afs_iget(sb,&fid,&inode);
- if (ret<0)
+ ret = afs_iget(sb, &fid, &inode);
+ if (ret < 0)
goto error;
ret = -ENOMEM;
@@ -393,19 +284,18 @@ static int afs_fill_super(struct super_block *sb, void *_data, int silent)
sb->s_root = root;
- _leave(" = 0");
+ kleave(" = 0");
return 0;
error:
- if (root) dput(root);
- if (inode) iput(inode);
- if (as) {
- if (as->volume) afs_put_volume(as->volume);
- kfree(as);
- }
+ dput(root);
+ iput(inode);
+ afs_put_volume(as->volume);
+ kfree(as);
+
sb->s_fs_info = NULL;
- _leave(" = %d",ret);
+ kleave(" = %d", ret);
return ret;
} /* end afs_fill_super() */
@@ -414,32 +304,72 @@ static int afs_fill_super(struct super_block *sb, void *_data, int silent)
* get an AFS superblock
* - TODO: don't use get_sb_nodev(), but rather call sget() directly
*/
-static struct super_block *
-afs_get_sb(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *options)
+static struct super_block *afs_get_sb(struct file_system_type *fs_type,
+ int flags,
+ const char *dev_name,
+ void *options)
{
+ struct afs_mount_params params;
struct super_block *sb;
- struct fill_super_options data = { dev_name, options };
int ret;
- _enter(",,%s,%p",dev_name,options);
+ _enter(",,%s,%p", dev_name, options);
+
+ memset(&params, 0, sizeof(params));
/* start the cache manager */
ret = afscm_start();
- if (ret<0) {
- _leave(" = %d",ret);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ERR_PTR(ret);
}
+ /* parse the options */
+ if (options) {
+ ret = afs_super_parse_options(&params, options, &dev_name);
+ if (ret < 0)
+ goto error;
+ if (!dev_name) {
+ printk("kAFS: no volume name specified\n");
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+
+ /* parse the device name */
+ ret = afs_volume_lookup(dev_name,
+ params.default_cell,
+ params.rwpath,
+ &params.volume);
+ if (ret < 0)
+ goto error;
+
/* allocate a deviceless superblock */
- sb = get_sb_nodev(fs_type, flags, &data, afs_fill_super);
- if (IS_ERR(sb)) {
- afscm_stop();
- return sb;
+ sb = sget(fs_type, afs_test_super, set_anon_super, &params);
+ if (IS_ERR(sb))
+ goto error;
+
+ sb->s_flags = flags;
+
+ ret = afs_fill_super(sb, &params, flags & MS_VERBOSE ? 1 : 0);
+ if (ret < 0) {
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ goto error;
}
+ sb->s_flags |= MS_ACTIVE;
- _leave("");
+ afs_put_volume(params.volume);
+ afs_put_cell(params.default_cell);
+ _leave(" = %p", sb);
return sb;
+
+ error:
+ afs_put_volume(params.volume);
+ afs_put_cell(params.default_cell);
+ afscm_stop();
+ _leave(" = %d", ret);
+ return ERR_PTR(ret);
} /* end afs_get_sb() */
/*****************************************************************************/
@@ -452,11 +382,7 @@ static void afs_put_super(struct super_block *sb)
_enter("");
- if (as) {
- if (as->volume) afs_put_volume(as->volume);
- }
-
- /* stop the cache manager */
+ afs_put_volume(as->volume);
afscm_stop();
_leave("");
@@ -466,18 +392,21 @@ static void afs_put_super(struct super_block *sb)
/*
* initialise an inode cache slab element prior to any use
*/
-static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, unsigned long flags)
+static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
+ unsigned long flags)
{
afs_vnode_t *vnode = (afs_vnode_t *) _vnode;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) {
- memset(vnode,0,sizeof(*vnode));
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR) {
+ memset(vnode, 0, sizeof(*vnode));
inode_init_once(&vnode->vfs_inode);
init_waitqueue_head(&vnode->update_waitq);
spin_lock_init(&vnode->lock);
INIT_LIST_HEAD(&vnode->cb_link);
INIT_LIST_HEAD(&vnode->cb_hash_link);
- afs_timer_init(&vnode->cb_timeout,&afs_vnode_cb_timed_out_ops);
+ afs_timer_init(&vnode->cb_timeout,
+ &afs_vnode_cb_timed_out_ops);
}
} /* end afs_i_init_once() */
@@ -490,16 +419,19 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
{
afs_vnode_t *vnode;
- vnode = (afs_vnode_t *) kmem_cache_alloc(afs_inode_cachep,SLAB_KERNEL);
+ vnode = (afs_vnode_t *)
+ kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL);
if (!vnode)
return NULL;
- memset(&vnode->fid,0,sizeof(vnode->fid));
- memset(&vnode->status,0,sizeof(vnode->status));
+ atomic_inc(&afs_count_active_inodes);
- vnode->volume = NULL;
- vnode->update_cnt = 0;
- vnode->flags = 0;
+ memset(&vnode->fid, 0, sizeof(vnode->fid));
+ memset(&vnode->status, 0, sizeof(vnode->status));
+
+ vnode->volume = NULL;
+ vnode->update_cnt = 0;
+ vnode->flags = 0;
return &vnode->vfs_inode;
} /* end afs_alloc_inode() */
@@ -510,6 +442,10 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
*/
static void afs_destroy_inode(struct inode *inode)
{
- _enter("{%lu}",inode->i_ino);
+ _enter("{%lu}", inode->i_ino);
+
kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
+
+ atomic_dec(&afs_count_active_inodes);
+
} /* end afs_destroy_inode() */
diff --git a/fs/afs/super.h b/fs/afs/super.h
index b307b0884181..ac11362f4e95 100644
--- a/fs/afs/super.h
+++ b/fs/afs/super.h
@@ -29,7 +29,7 @@
*/
struct afs_super_info
{
- afs_volume_t *volume; /* volume record */
+ struct afs_volume *volume; /* volume record */
char rwparent; /* T if parent is R/W AFS volume */
};
diff --git a/fs/afs/types.h b/fs/afs/types.h
index 411925f4fa04..2606f01e217a 100644
--- a/fs/afs/types.h
+++ b/fs/afs/types.h
@@ -33,26 +33,13 @@ typedef struct afs_volsync afs_volsync_t;
typedef struct afs_volume afs_volume_t;
typedef struct afs_volume_info afs_volume_info_t;
-typedef struct afsc_cache afsc_cache_t;
-typedef struct afsc_cache_cell afsc_cache_cell_t;
-typedef struct afsc_cache_vldb afsc_cache_vldb_t;
-typedef struct afsc_cell_record afsc_cell_record_t;
-typedef struct afsc_inode afsc_inode_t;
-typedef struct afsc_io afsc_io_t;
-typedef struct afsc_io_subop afsc_io_subop_t;
-typedef struct afsc_io_queue afsc_io_queue_t;
-typedef struct afsc_super_block afsc_super_block_t;
-typedef struct afsc_vldb_record afsc_vldb_record_t;
-typedef struct afsc_vnode_catalogue afsc_vnode_catalogue_t;
-typedef struct afsc_vnode_meta afsc_vnode_meta_t;
-
typedef struct afsvl_dbentry afsvl_dbentry_t;
typedef enum {
AFSVL_RWVOL, /* read/write volume */
AFSVL_ROVOL, /* read-only volume */
AFSVL_BACKVOL, /* backup volume */
-} afs_voltype_t;
+} __attribute__((packed)) afs_voltype_t;
extern const char *afs_voltypes[];
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c
index 4acdb1aed641..fb3426786429 100644
--- a/fs/afs/vlclient.c
+++ b/fs/afs/vlclient.c
@@ -176,8 +176,8 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags)
/*
* look up a volume location database entry by name
*/
-int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
- afsc_vldb_record_t *entry)
+int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsigned volnamesz,
+ struct afs_cache_vlocation *entry)
{
DECLARE_WAITQUEUE(myself,current);
@@ -189,29 +189,29 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
int ret, loop;
u32 *bp, param[2], zero;
- _enter(",%s,",volname);
+ _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
- memset(entry,0,sizeof(*entry));
+ memset(entry, 0, sizeof(*entry));
/* get hold of the vlserver connection */
- ret = afs_server_get_vlconn(server,&conn);
+ ret = afs_server_get_vlconn(server, &conn);
if (ret<0)
goto out;
/* create a call through that connection */
- ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call);
- if (ret<0) {
- printk("kAFS: Unable to create call: %d\n",ret);
+ ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
+ if (ret < 0) {
+ printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn;
}
call->app_opcode = VLGETENTRYBYNAME;
/* we want to get event notifications from the call */
- add_wait_queue(&call->waitq,&myself);
+ add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */
- piov[1].iov_len = strlen(volname);
- piov[1].iov_base = (char*)volname;
+ piov[1].iov_len = volnamesz;
+ piov[1].iov_base = (char*) volname;
zero = 0;
piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
@@ -224,16 +224,16 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
piov[0].iov_base = param;
/* send the parameters to the server */
- ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent);
+ ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 0, &sent);
if (ret<0)
goto abort;
/* wait for the reply to completely arrive */
- bp = rxrpc_call_alloc_scratch(call,384);
+ bp = rxrpc_call_alloc_scratch(call, 384);
- ret = rxrpc_call_read_data(call,bp,384,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
- if (ret<0) {
- if (ret==-ECONNABORTED) {
+ ret = rxrpc_call_read_data(call, bp, 384, RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL);
+ if (ret < 0) {
+ if (ret == -ECONNABORTED) {
ret = call->app_errno;
goto out_unwait;
}
@@ -255,9 +255,9 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
for (loop=0; loop<8; loop++) {
tmp = ntohl(*bp++);
- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
}
entry->vid[0] = ntohl(*bp++);
@@ -267,26 +267,26 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */
- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM;
if (!entry->vidmask)
goto abort;
/* success */
- entry->ctime = get_seconds();
+ entry->rtime = get_seconds();
ret = 0;
out_unwait:
set_current_state(TASK_RUNNING);
- remove_wait_queue(&call->waitq,&myself);
+ remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call);
out_put_conn:
rxrpc_put_connection(conn);
out:
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
abort:
@@ -303,7 +303,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname,
int afs_rxvl_get_entry_by_id(afs_server_t *server,
afs_volid_t volid,
afs_voltype_t voltype,
- afsc_vldb_record_t *entry)
+ struct afs_cache_vlocation *entry)
{
DECLARE_WAITQUEUE(myself,current);
@@ -375,9 +375,9 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
for (loop=0; loop<8; loop++) {
tmp = ntohl(*bp++);
- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
}
entry->vid[0] = ntohl(*bp++);
@@ -387,9 +387,9 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */
- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM;
if (!entry->vidmask)
@@ -401,13 +401,13 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
entry->servers[1].s_addr = htonl(0xac101243);
entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
- entry->srvtmask[0] = AFSC_VOL_STM_RO;
- entry->srvtmask[1] = AFSC_VOL_STM_RO;
- entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
+ entry->srvtmask[0] = AFS_VOL_VTM_RO;
+ entry->srvtmask[1] = AFS_VOL_VTM_RO;
+ entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
#endif
/* success */
- entry->ctime = get_seconds();
+ entry->rtime = get_seconds();
ret = 0;
out_unwait:
@@ -520,7 +520,7 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
* attend to the asynchronous get VLDB entry by ID
*/
int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
- afsc_vldb_record_t *entry)
+ struct afs_cache_vlocation *entry)
{
unsigned *bp, tmp;
int loop, ret;
@@ -550,9 +550,9 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
for (loop=0; loop<8; loop++) {
tmp = ntohl(*bp++);
- if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
}
entry->vid[0] = ntohl(*bp++);
@@ -562,9 +562,9 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */
- if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFSC_VOL_STM_RW;
- if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFSC_VOL_STM_RO;
- if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFSC_VOL_STM_BAK;
+ if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW;
+ if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO;
+ if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM;
if (!entry->vidmask) {
@@ -578,13 +578,13 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
entry->servers[1].s_addr = htonl(0xac101243);
entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
- entry->srvtmask[0] = AFSC_VOL_STM_RO;
- entry->srvtmask[1] = AFSC_VOL_STM_RO;
- entry->srvtmask[2] = AFSC_VOL_STM_RO | AFSC_VOL_STM_RW;
+ entry->srvtmask[0] = AFS_VOL_VTM_RO;
+ entry->srvtmask[1] = AFS_VOL_VTM_RO;
+ entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
#endif
/* success */
- entry->ctime = get_seconds();
+ entry->rtime = get_seconds();
ret = 0;
goto done;
}
@@ -626,7 +626,8 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
case RXRPC_CSTATE_CLNT_GOT_REPLY:
if (call->app_read_count==0)
break;
- printk("kAFS: Reply bigger than expected {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
+ printk("kAFS: Reply bigger than expected"
+ " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
call->app_call_state,
call->app_async_read,
call->app_mark,
diff --git a/fs/afs/vlclient.h b/fs/afs/vlclient.h
index 5791e04d6382..29f0784287cd 100644
--- a/fs/afs/vlclient.h
+++ b/fs/afs/vlclient.h
@@ -46,7 +46,7 @@ enum AFSVL_Errors {
};
/* maps to "struct vldbentry" in vvl-spec.pdf */
-struct afsvl_dbentry {
+struct afs_vldbentry {
char name[65]; /* name of volume (including NUL char) */
afs_voltype_t type; /* volume type */
unsigned num_servers; /* num servers that hold instances of this vol */
@@ -77,19 +77,20 @@ extern int afs_rxvl_probe(afs_server_t *server, int alloc_flags);
/* look up a volume location database entry by name */
extern int afs_rxvl_get_entry_by_name(afs_server_t *server,
const char *volname,
- afsc_vldb_record_t *entry);
+ unsigned volnamesz,
+ struct afs_cache_vlocation *entry);
/* look up a volume location database entry by ID */
extern int afs_rxvl_get_entry_by_id(afs_server_t *server,
afs_volid_t volid,
afs_voltype_t voltype,
- afsc_vldb_record_t *entry);
+ struct afs_cache_vlocation *entry);
extern int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
afs_volid_t volid,
afs_voltype_t voltype);
extern int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
- afsc_vldb_record_t *entry);
+ struct afs_cache_vlocation *entry);
#endif /* _LINUX_AFS_VLCLIENT_H */
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 8d9f4d7e8f29..3042dea7517a 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -56,6 +56,19 @@ static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */
static afs_vlocation_t *afs_vlocation_update; /* VL currently being updated */
static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_vlocation_cache_match(void *target, const void *entry);
+static void afs_vlocation_cache_update(void *source, void *entry);
+
+struct cachefs_index_def afs_vlocation_cache_index_def = {
+ .name = "vldb",
+ .data_size = sizeof(struct afs_cache_vlocation),
+ .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
+ .match = afs_vlocation_cache_match,
+ .update = afs_vlocation_cache_update,
+};
+#endif
+
/*****************************************************************************/
/*
* iterate through the VL servers in a cell until one of them admits knowing about the volume in
@@ -64,21 +77,23 @@ static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guardi
*/
static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
const char *name,
- afsc_vldb_record_t *vldb)
+ unsigned namesz,
+ struct afs_cache_vlocation *vldb)
{
afs_server_t *server = NULL;
afs_cell_t *cell = vlocation->cell;
int count, ret;
- _enter("%s,%s,",cell->name,name);
+ _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
ret = -ENOMEDIUM;
for (count=cell->vl_naddrs; count>0; count--) {
_debug("CellServ[%hu]: %08x",
- cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
+ cell->vl_curr_svix,
+ cell->vl_addrs[cell->vl_curr_svix].s_addr);
/* try and create a server */
- ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
+ ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
switch (ret) {
case 0:
break;
@@ -90,7 +105,7 @@ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
}
/* attempt to access the VL server */
- ret = afs_rxvl_get_entry_by_name(server,name,vldb);
+ ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
switch (ret) {
case 0:
afs_put_server(server);
@@ -107,7 +122,7 @@ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
}
up_write(&server->sem);
afs_put_server(server);
- if (ret==-ENOMEM || ret==-ENONET)
+ if (ret == -ENOMEM || ret == -ENONET)
goto out;
goto rotate;
case -ENOMEDIUM:
@@ -140,21 +155,22 @@ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
afs_volid_t volid,
afs_voltype_t voltype,
- afsc_vldb_record_t *vldb)
+ struct afs_cache_vlocation *vldb)
{
afs_server_t *server = NULL;
afs_cell_t *cell = vlocation->cell;
int count, ret;
- _enter("%s,%x,%d,",cell->name,volid,voltype);
+ _enter("%s,%x,%d,", cell->name, volid, voltype);
ret = -ENOMEDIUM;
for (count=cell->vl_naddrs; count>0; count--) {
_debug("CellServ[%hu]: %08x",
- cell->vl_curr_svix,cell->vl_addrs[cell->vl_curr_svix].s_addr);
+ cell->vl_curr_svix,
+ cell->vl_addrs[cell->vl_curr_svix].s_addr);
/* try and create a server */
- ret = afs_server_lookup(cell,&cell->vl_addrs[cell->vl_curr_svix],&server);
+ ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server);
switch (ret) {
case 0:
break;
@@ -166,7 +182,7 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
}
/* attempt to access the VL server */
- ret = afs_rxvl_get_entry_by_id(server,volid,voltype,vldb);
+ ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
switch (ret) {
case 0:
afs_put_server(server);
@@ -183,7 +199,7 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
}
up_write(&server->sem);
afs_put_server(server);
- if (ret==-ENOMEM || ret==-ENONET)
+ if (ret == -ENOMEM || ret == -ENONET)
goto out;
goto rotate;
case -ENOMEDIUM:
@@ -216,74 +232,83 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
* - lookup in the local cache if not able to find on the VL server
* - insert/update in the local cache if did get a VL response
*/
-int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation)
+int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
+ afs_vlocation_t **_vlocation)
{
- afsc_vldb_record_t vldb;
+ struct afs_cache_vlocation vldb;
struct list_head *_p;
afs_vlocation_t *vlocation;
afs_voltype_t voltype;
afs_volid_t vid;
int active = 0, ret;
- _enter(",%s,%s,",cell->name,name);
+ _enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
- if (strlen(name)>sizeof(vlocation->vldb.name)) {
+ if (namesz > sizeof(vlocation->vldb.name)) {
_leave(" = -ENAMETOOLONG");
return -ENAMETOOLONG;
}
/* search the cell's active list first */
- list_for_each(_p,&cell->vl_list) {
- vlocation = list_entry(_p,afs_vlocation_t,link);
- if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
+ list_for_each(_p, &cell->vl_list) {
+ vlocation = list_entry(_p, afs_vlocation_t, link);
+ if (namesz < sizeof(vlocation->vldb.name) &&
+ vlocation->vldb.name[namesz] != '\0')
+ continue;
+
+ if (memcmp(vlocation->vldb.name, name, namesz) == 0)
goto found_in_memory;
}
/* search the cell's graveyard list second */
spin_lock(&cell->vl_gylock);
- list_for_each(_p,&cell->vl_graveyard) {
- vlocation = list_entry(_p,afs_vlocation_t,link);
- if (strncmp(vlocation->vldb.name,name,sizeof(vlocation->vldb.name))==0)
+ list_for_each(_p, &cell->vl_graveyard) {
+ vlocation = list_entry(_p, afs_vlocation_t, link);
+ if (namesz < sizeof(vlocation->vldb.name) &&
+ vlocation->vldb.name[namesz] != '\0')
+ continue;
+
+ if (memcmp(vlocation->vldb.name, name, namesz) == 0)
goto found_in_graveyard;
}
spin_unlock(&cell->vl_gylock);
/* not in the cell's in-memory lists - create a new record */
- vlocation = kmalloc(sizeof(afs_vlocation_t),GFP_KERNEL);
+ vlocation = kmalloc(sizeof(afs_vlocation_t), GFP_KERNEL);
if (!vlocation)
return -ENOMEM;
- memset(vlocation,0,sizeof(afs_vlocation_t));
- atomic_set(&vlocation->usage,1);
+ memset(vlocation, 0, sizeof(afs_vlocation_t));
+ atomic_set(&vlocation->usage, 1);
INIT_LIST_HEAD(&vlocation->link);
rwlock_init(&vlocation->lock);
- strncpy(vlocation->vldb.name,name,sizeof(vlocation->vldb.name));
-
- afs_timer_init(&vlocation->timeout,&afs_vlocation_timer_ops);
- afs_timer_init(&vlocation->upd_timer,&afs_vlocation_update_timer_ops);
- afs_async_op_init(&vlocation->upd_op,&afs_vlocation_update_op_ops);
+ memcpy(vlocation->vldb.name, name, namesz);
- INIT_LIST_HEAD(&vlocation->caches);
+ afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
+ afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
+ afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
afs_get_cell(cell);
vlocation->cell = cell;
- list_add_tail(&vlocation->link,&cell->vl_list);
+ list_add_tail(&vlocation->link, &cell->vl_list);
-#if 0
- /* search local cache if wasn't in memory */
- ret = afsc_lookup_vlocation(vlocation);
- switch (ret) {
- default: goto error; /* disk error */
- case 0: goto found_in_cache; /* pulled from local cache into memory */
- case -ENOENT: break; /* not in local cache */
- }
+#ifdef AFS_CACHING_SUPPORT
+ /* we want to store it in the cache, plus it might already be encached */
+ cachefs_acquire_cookie(cell->cache,
+ &afs_volume_cache_index_def,
+ vlocation,
+ &vlocation->cache);
+
+ if (vlocation->valid)
+ goto found_in_cache;
#endif
/* try to look up an unknown volume in the cell VL databases by name */
- ret = afs_vlocation_access_vl_by_name(vlocation,name,&vldb);
+ ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
if (ret<0) {
- printk("kAFS: failed to locate '%s' in cell '%s'\n",name,cell->name);
+ printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
+ namesz, namesz, name, cell->name);
goto error;
}
@@ -294,7 +319,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
_debug("found in graveyard");
atomic_inc(&vlocation->usage);
list_del(&vlocation->link);
- list_add_tail(&vlocation->link,&cell->vl_list);
+ list_add_tail(&vlocation->link, &cell->vl_list);
spin_unlock(&cell->vl_gylock);
afs_kafstimod_del_timer(&vlocation->timeout);
@@ -308,30 +333,32 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
active:
active = 1;
-/* found_in_cache: */
+#ifdef AFS_CACHING_SUPPORT
+ found_in_cache:
+#endif
/* try to look up a cached volume in the cell VL databases by ID */
_debug("found in cache");
_debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
vlocation->vldb.name,
vlocation->vldb.vidmask,
- ntohl(vlocation->vldb.servers[0].s_addr),vlocation->vldb.srvtmask[0],
- ntohl(vlocation->vldb.servers[1].s_addr),vlocation->vldb.srvtmask[1],
- ntohl(vlocation->vldb.servers[2].s_addr),vlocation->vldb.srvtmask[2]
+ ntohl(vlocation->vldb.servers[0].s_addr), vlocation->vldb.srvtmask[0],
+ ntohl(vlocation->vldb.servers[1].s_addr), vlocation->vldb.srvtmask[1],
+ ntohl(vlocation->vldb.servers[2].s_addr), vlocation->vldb.srvtmask[2]
);
_debug("Vids: %08x %08x %08x",
- vlocation->vldb.vid[0],vlocation->vldb.vid[1],vlocation->vldb.vid[2]);
+ vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2]);
- if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
+ if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
vid = vlocation->vldb.vid[0];
voltype = AFSVL_RWVOL;
}
- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
+ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
vid = vlocation->vldb.vid[1];
voltype = AFSVL_ROVOL;
}
- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
+ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
vid = vlocation->vldb.vid[2];
voltype = AFSVL_BACKVOL;
}
@@ -341,41 +368,44 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
voltype = 0;
}
- ret = afs_vlocation_access_vl_by_id(vlocation,vid,voltype,&vldb);
+ ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
switch (ret) {
/* net error */
default:
- printk("kAFS: failed to volume '%s' (%x) up in '%s': %d\n",
- name,vid,cell->name,ret);
+ printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
+ namesz, namesz, name, vid, cell->name, ret);
goto error;
/* pulled from local cache into memory */
- case 0:
+ case 0:
goto found_on_vlserver;
/* uh oh... looks like the volume got deleted */
case -ENOMEDIUM:
- printk("kAFS: volume '%s' (%x) does not exist '%s'\n",name,vid,cell->name);
+ printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
+ namesz, namesz, name, vid, cell->name);
/* TODO: make existing record unavailable */
goto error;
}
found_on_vlserver:
- _debug("Done VL Lookup: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
- name,
+ _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
+ namesz, namesz, name,
vldb.vidmask,
- ntohl(vldb.servers[0].s_addr),vldb.srvtmask[0],
- ntohl(vldb.servers[1].s_addr),vldb.srvtmask[1],
- ntohl(vldb.servers[2].s_addr),vldb.srvtmask[2]
+ ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
+ ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
+ ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
);
- _debug("Vids: %08x %08x %08x",vldb.vid[0],vldb.vid[1],vldb.vid[2]);
+ _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
- if (strncmp(vldb.name,name,sizeof(vlocation->vldb.name))!=0)
- printk("kAFS: name of volume '%s' changed to '%s' on server\n",name,vldb.name);
+ if ((namesz < sizeof(vlocation->vldb.name) && vlocation->vldb.name[namesz] != '\0') ||
+ memcmp(vldb.name, name, namesz) != 0)
+ printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
+ namesz, namesz, name, vldb.name);
- memcpy(&vlocation->vldb,&vldb,sizeof(vlocation->vldb));
+ memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
#if 0
/* add volume entry to local cache */
@@ -384,7 +414,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
goto error;
#endif
- afs_kafstimod_add_timer(&vlocation->upd_timer,10*HZ);
+ afs_kafstimod_add_timer(&vlocation->upd_timer, 10*HZ);
*_vlocation = vlocation;
_leave(" = 0 (%p)",vlocation);
@@ -397,10 +427,10 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
}
else {
list_del(&vlocation->link);
- afs_put_cell(vlocation->cell);
-#if 0
- afs_put_cache(vlocation->cache);
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_relinquish_cookie(vlocation->cache, 0);
#endif
+ afs_put_cell(vlocation->cell);
kfree(vlocation);
}
}
@@ -414,12 +444,17 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_
* finish using a volume location record
* - caller must have cell->vol_sem write-locked
*/
-void __afs_put_vlocation(afs_vlocation_t *vlocation)
+void __afs_put_vlocation(struct afs_vlocation *vlocation)
{
- afs_cell_t *cell = vlocation->cell;
+ struct afs_cell *cell;
+
+ if (!vlocation)
+ return;
_enter("%s",vlocation->vldb.name);
+ cell = vlocation->cell;
+
/* sanity check */
if (atomic_read(&vlocation->usage)<=0)
BUG();
@@ -453,11 +488,13 @@ void __afs_put_vlocation(afs_vlocation_t *vlocation)
*/
void afs_put_vlocation(afs_vlocation_t *vlocation)
{
- afs_cell_t *cell = vlocation->cell;
+ if (vlocation) {
+ struct afs_cell *cell = vlocation->cell;
- down_write(&cell->vl_sem);
- __afs_put_vlocation(vlocation);
- up_write(&cell->vl_sem);
+ down_write(&cell->vl_sem);
+ __afs_put_vlocation(vlocation);
+ up_write(&cell->vl_sem);
+ }
} /* end afs_put_vlocation() */
/*****************************************************************************/
@@ -489,10 +526,10 @@ void afs_vlocation_do_timeout(afs_vlocation_t *vlocation)
}
/* we can now destroy it properly */
- afs_put_cell(cell);
-#if 0
- afs_put_cache(vlocation->cache);
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_relinquish_cookie(vlocation->cache,0);
#endif
+ afs_put_cell(cell);
kfree(vlocation);
@@ -513,15 +550,15 @@ static int afs_vlocation_update_begin(afs_vlocation_t *vlocation)
vlocation->vldb.name,vlocation->upd_first_svix,vlocation->upd_curr_svix);
/* try to look up a cached volume in the cell VL databases by ID */
- if (vlocation->vldb.vidmask & AFSC_VOL_STM_RW) {
+ if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
vid = vlocation->vldb.vid[0];
voltype = AFSVL_RWVOL;
}
- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_RO) {
+ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
vid = vlocation->vldb.vid[1];
voltype = AFSVL_ROVOL;
}
- else if (vlocation->vldb.vidmask & AFSC_VOL_STM_BAK) {
+ else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
vid = vlocation->vldb.vid[2];
voltype = AFSVL_BACKVOL;
}
@@ -571,10 +608,8 @@ static void afs_vlocation_update_abandon(afs_vlocation_t *vlocation,
printk("kAFS: Abandoning VL update '%s': %d\n",vlocation->vldb.name,ret);
/* discard the server record */
- if (vlocation->upd_op.server) {
- afs_put_server(vlocation->upd_op.server);
- vlocation->upd_op.server = NULL;
- }
+ afs_put_server(vlocation->upd_op.server);
+ vlocation->upd_op.server = NULL;
spin_lock(&afs_vlocation_update_lock);
afs_vlocation_update = NULL;
@@ -669,7 +704,7 @@ static void afs_vlocation_update_timer(afs_timer_t *timer)
*/
static void afs_vlocation_update_attend(afs_async_op_t *op)
{
- afsc_vldb_record_t vldb;
+ struct afs_cache_vlocation vldb;
afs_vlocation_t *vlocation = list_entry(op,afs_vlocation_t,upd_op);
unsigned tmp;
int ret;
@@ -762,11 +797,9 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
try_next:
vlocation->upd_busy_cnt = 0;
- if (vlocation->upd_op.server) {
- /* discard the server record */
- afs_put_server(vlocation->upd_op.server);
- vlocation->upd_op.server = NULL;
- }
+ /* discard the server record */
+ afs_put_server(vlocation->upd_op.server);
+ vlocation->upd_op.server = NULL;
tmp = vlocation->cell->vl_naddrs;
if (tmp==0)
@@ -822,3 +855,68 @@ static void afs_vlocation_update_discard(afs_async_op_t *op)
_leave("");
} /* end afs_vlocation_update_discard() */
+
+/*****************************************************************************/
+/*
+ * match a VLDB record stored in the cache
+ * - may also load target from entry
+ */
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_vlocation_cache_match(void *target,
+ const void *entry)
+{
+ const struct afs_cache_vlocation *vldb = entry;
+ struct afs_vlocation *vlocation = target;
+
+ _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
+
+ if (strncmp(vlocation->vldb.name,
+ vldb->name,
+ sizeof(vldb->name)) == 0) {
+ if (!vlocation->valid ||
+ vlocation->vldb.rtime == vldb->rtime) {
+ struct_cpy(&vlocation->vldb, vldb);
+ vlocation->valid = 1;
+ _leave(" = SUCCESS [c->m]");
+ return CACHEFS_MATCH_SUCCESS;
+ }
+ /* need to update cache if cached info differs */
+ else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
+ /* delete if VIDs for this name differ */
+ if (memcmp(&vlocation->vldb.vid,
+ &vldb->vid,
+ sizeof(vldb->vid)) != 0) {
+ _leave(" = DELETE");
+ return CACHEFS_MATCH_SUCCESS_DELETE;
+ }
+
+ _leave(" = UPDATE");
+ return CACHEFS_MATCH_SUCCESS_UPDATE;
+ }
+ else {
+ _leave(" = SUCCESS");
+ return CACHEFS_MATCH_SUCCESS;
+ }
+ }
+
+ _leave(" = FAILED");
+ return CACHEFS_MATCH_FAILED;
+} /* end afs_vlocation_cache_match() */
+#endif
+
+/*****************************************************************************/
+/*
+ * update a VLDB record stored in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_vlocation_cache_update(void *source, void *entry)
+{
+ struct afs_cache_vlocation *vldb = entry;
+ struct afs_vlocation *vlocation = source;
+
+ _enter("");
+
+ struct_cpy(vldb,&vlocation->vldb);
+
+} /* end afs_vlocation_cache_update() */
+#endif
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c
index 8fe1cc583413..b982317733e1 100644
--- a/fs/afs/vnode.c
+++ b/fs/afs/vnode.c
@@ -29,6 +29,19 @@ struct afs_timer_ops afs_vnode_cb_timed_out_ops = {
.timed_out = afs_vnode_cb_timed_out,
};
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry);
+static void afs_vnode_cache_update(void *source, void *entry);
+
+struct cachefs_index_def afs_vnode_cache_index_def = {
+ .name = "vnode",
+ .data_size = sizeof(struct afs_cache_vnode),
+ .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
+ .match = afs_vnode_cache_match,
+ .update = afs_vnode_cache_update,
+};
+#endif
+
/*****************************************************************************/
/*
* handle a callback timing out
@@ -61,8 +74,7 @@ static void afs_vnode_cb_timed_out(struct afs_timer *timer)
spin_unlock(&vnode->lock);
- if (oldserver)
- afs_put_server(oldserver);
+ afs_put_server(oldserver);
_leave("");
} /* end afs_vnode_cb_timed_out() */
@@ -126,8 +138,7 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server,
wake_up_all(&vnode->update_waitq);
- if (oldserver)
- afs_put_server(oldserver);
+ afs_put_server(oldserver);
_leave("");
@@ -272,7 +283,7 @@ int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *d
/*****************************************************************************/
/*
* break any outstanding callback on a vnode
- * - only relevant to server that issued it
+ * - only relevent to server that issued it
*/
int afs_vnode_give_up_callback(afs_vnode_t *vnode)
{
@@ -314,3 +325,56 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
_leave(" = %d",ret);
return ret;
} /* end afs_vnode_give_up_callback() */
+
+/*****************************************************************************/
+/*
+ * match a vnode record stored in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry)
+{
+ const struct afs_cache_vnode *cvnode = entry;
+ struct afs_vnode *vnode = target;
+
+ _enter("{%x,%x,%Lx},{%x,%x,%Lx}",
+ vnode->fid.vnode,
+ vnode->fid.unique,
+ vnode->status.version,
+ cvnode->vnode_id,
+ cvnode->vnode_unique,
+ cvnode->data_version);
+
+ if (vnode->fid.vnode != cvnode->vnode_id) {
+ _leave(" = FAILED");
+ return CACHEFS_MATCH_FAILED;
+ }
+
+ if (vnode->fid.unique != cvnode->vnode_unique ||
+ vnode->status.version != cvnode->data_version) {
+ _leave(" = DELETE");
+ return CACHEFS_MATCH_SUCCESS_DELETE;
+ }
+
+ _leave(" = SUCCESS");
+ return CACHEFS_MATCH_SUCCESS;
+} /* end afs_vnode_cache_match() */
+#endif
+
+/*****************************************************************************/
+/*
+ * update a vnode record stored in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_vnode_cache_update(void *source, void *entry)
+{
+ struct afs_cache_vnode *cvnode = entry;
+ struct afs_vnode *vnode = source;
+
+ _enter("");
+
+ cvnode->vnode_id = vnode->fid.vnode;
+ cvnode->vnode_unique = vnode->fid.unique;
+ cvnode->data_version = vnode->status.version;
+
+} /* end afs_vnode_cache_update() */
+#endif
diff --git a/fs/afs/vnode.h b/fs/afs/vnode.h
index 67710bb92d39..b35663e0647c 100644
--- a/fs/afs/vnode.h
+++ b/fs/afs/vnode.h
@@ -15,6 +15,7 @@
#include <linux/fs.h>
#include "server.h"
#include "kafstimod.h"
+#include "cache.h"
#ifdef __KERNEL__
@@ -22,16 +23,33 @@ struct afs_rxfs_fetch_descriptor;
/*****************************************************************************/
/*
+ * vnode catalogue entry
+ */
+struct afs_cache_vnode
+{
+ afs_vnodeid_t vnode_id; /* vnode ID */
+ unsigned vnode_unique; /* vnode ID uniquifier */
+ afs_dataversion_t data_version; /* data version */
+};
+
+#ifdef AFS_CACHING_SUPPORT
+extern struct cachefs_index_def afs_vnode_cache_index_def;
+#endif
+
+/*****************************************************************************/
+/*
* AFS inode private data
*/
struct afs_vnode
{
struct inode vfs_inode; /* the VFS's inode record */
- afs_volume_t *volume; /* volume on which vnode resides */
- afs_fid_t fid; /* the file identifier for this inode */
- afs_file_status_t status; /* AFS status info for this file */
- unsigned nix; /* vnode index in cache */
+ struct afs_volume *volume; /* volume on which vnode resides */
+ struct afs_fid fid; /* the file identifier for this inode */
+ struct afs_file_status status; /* AFS status info for this file */
+#ifdef AFS_CACHING_SUPPORT
+ struct cachefs_cookie *cache; /* caching cookie */
+#endif
wait_queue_head_t update_waitq; /* status fetch waitqueue */
unsigned update_cnt; /* number of outstanding ops that will update the
@@ -43,10 +61,10 @@ struct afs_vnode
#define AFS_VNODE_MOUNTPOINT 0x00000004 /* set if vnode is a mountpoint symlink */
/* outstanding callback notification on this file */
- afs_server_t *cb_server; /* server that made the current promise */
+ struct afs_server *cb_server; /* server that made the current promise */
struct list_head cb_link; /* link in server's promises list */
struct list_head cb_hash_link; /* link in master callback hash */
- afs_timer_t cb_timeout; /* timeout on promise */
+ struct afs_timer cb_timeout; /* timeout on promise */
unsigned cb_version; /* callback version */
unsigned cb_expiry; /* callback expiry time */
afs_callback_type_t cb_type; /* type of callback */
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 283e8530fa33..9f9823ebfa7c 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -16,7 +16,9 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include "volume.h"
+#include "vnode.h"
#include "cell.h"
+#include "cache.h"
#include "cmservice.h"
#include "fsclient.h"
#include "vlclient.h"
@@ -24,6 +26,20 @@
const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry);
+static void afs_volume_cache_update(void *source, void *entry);
+
+struct cachefs_index_def afs_volume_cache_index_def = {
+ .name = "volume",
+ .data_size = sizeof(struct afs_cache_vhash),
+ .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 },
+ .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 },
+ .match = afs_volume_cache_match,
+ .update = afs_volume_cache_update,
+};
+#endif
+
/*****************************************************************************/
/*
* lookup a volume by name
@@ -43,19 +59,19 @@ const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
* - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available
* - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise
*/
-int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
+int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
+ afs_volume_t **_volume)
{
- afs_vlocation_t *vlocation = NULL;
+ struct afs_vlocation *vlocation = NULL;
+ struct afs_volume *volume = NULL;
afs_voltype_t type;
- afs_volume_t *volume = NULL;
- afs_cell_t *cell = NULL;
- char *cellname, *volname, *suffix;
+ const char *cellname, *volname, *suffix;
char srvtmask;
- int force, ret, loop;
+ int force, ret, loop, cellnamesz, volnamesz;
- _enter(",%s,",name);
+ _enter("%s,,%d,", name, rwpath);
- if (!name || (name[0]!='%' && name[0]!='#') || !name[1]) {
+ if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
printk("kAFS: unparsable volume name\n");
return -EINVAL;
}
@@ -64,24 +80,22 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
force = 0;
type = AFSVL_ROVOL;
- if (rwparent || name[0]=='%') {
+ if (rwpath || name[0] == '%') {
type = AFSVL_RWVOL;
force = 1;
}
- suffix = strrchr(name,'.');
+ suffix = strrchr(name, '.');
if (suffix) {
- if (strcmp(suffix,".readonly")==0) {
+ if (strcmp(suffix, ".readonly") == 0) {
type = AFSVL_ROVOL;
force = 1;
}
- else if (strcmp(suffix,".backup")==0) {
+ else if (strcmp(suffix, ".backup") == 0) {
type = AFSVL_BACKVOL;
force = 1;
}
- else if (suffix[1]==0) {
- *suffix = 0;
- suffix = NULL;
+ else if (suffix[1] == 0) {
}
else {
suffix = NULL;
@@ -90,38 +104,45 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
/* split the cell and volume names */
name++;
- volname = strchr(name,':');
+ volname = strchr(name, ':');
if (volname) {
- *volname++ = 0;
cellname = name;
+ cellnamesz = volname - name;
}
else {
volname = name;
cellname = NULL;
+ cellnamesz = 0;
}
- _debug("CELL:%s VOLUME:%s SUFFIX:%s TYPE:%d%s",
- cellname,volname,suffix?:"-",type,force?" FORCE":"");
+ volnamesz = suffix ? suffix - volname : strlen(volname);
- /* lookup the cell record */
- ret = afs_cell_lookup(cellname,&cell);
- if (ret<0)
- printk("kAFS: unable to lookup cell '%s'\n",cellname?:"");
+ _debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
+ cellnamesz, cellnamesz, cellname ?: "", cell,
+ volnamesz, volnamesz, volname, suffix ?: "-",
+ type,
+ force ? " FORCE" : "");
- if (cellname) volname[-1] = ':';
- if (ret<0)
- goto error;
+ /* lookup the cell record */
+ if (cellname || !cell) {
+ ret = afs_cell_lookup(cellname, cellnamesz, &cell);
+ if (ret<0) {
+ printk("kAFS: unable to lookup cell '%s'\n", cellname ?: "");
+ goto error;
+ }
+ }
+ else {
+ afs_get_cell(cell);
+ }
/* lookup the volume location record */
- if (suffix) *suffix = 0;
- ret = afs_vlocation_lookup(cell,volname,&vlocation);
- if (suffix) *suffix = '.';
- if (ret<0)
+ ret = afs_vlocation_lookup(cell, volname, volnamesz, &vlocation);
+ if (ret < 0)
goto error;
/* make the final decision on the type we want */
ret = -ENOMEDIUM;
- if (force && !(vlocation->vldb.vidmask & (1<<type)))
+ if (force && !(vlocation->vldb.vidmask & (1 << type)))
goto error;
srvtmask = 0;
@@ -129,13 +150,13 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
srvtmask |= vlocation->vldb.srvtmask[loop];
if (force) {
- if (!(srvtmask & (1 <<type)))
+ if (!(srvtmask & (1 << type)))
goto error;
}
- else if (srvtmask & AFSC_VOL_STM_RO) {
+ else if (srvtmask & AFS_VOL_VTM_RO) {
type = AFSVL_ROVOL;
}
- else if (srvtmask & AFSC_VOL_STM_RW) {
+ else if (srvtmask & AFS_VOL_VTM_RW) {
type = AFSVL_RWVOL;
}
else {
@@ -156,16 +177,16 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
_debug("creating new volume record");
ret = -ENOMEM;
- volume = kmalloc(sizeof(afs_volume_t),GFP_KERNEL);
+ volume = kmalloc(sizeof(afs_volume_t), GFP_KERNEL);
if (!volume)
goto error_up;
- memset(volume,0,sizeof(afs_volume_t));
- atomic_set(&volume->usage,1);
- volume->type = type;
- volume->type_force = force;
- volume->cell = cell;
- volume->vid = vlocation->vldb.vid[type];
+ memset(volume, 0, sizeof(afs_volume_t));
+ atomic_set(&volume->usage, 1);
+ volume->type = type;
+ volume->type_force = force;
+ volume->cell = cell;
+ volume->vid = vlocation->vldb.vid[type];
init_rwsem(&volume->server_sem);
@@ -183,15 +204,20 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
}
/* attach the cache and volume location */
-#if 0
- afs_get_cache(cache); volume->cache = cache;
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_acquire_cookie(vlocation->cache,
+ &afs_vnode_cache_index_def,
+ volume,
+ &volume->cache);
#endif
- afs_get_vlocation(vlocation); volume->vlocation = vlocation;
+
+ afs_get_vlocation(vlocation);
+ volume->vlocation = vlocation;
vlocation->vols[type] = volume;
success:
- _debug("kAFS selected %s volume %08x",afs_voltypes[volume->type],volume->vid);
+ _debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid);
*_volume = volume;
ret = 0;
@@ -199,18 +225,17 @@ int afs_volume_lookup(const char *name, int rwparent, afs_volume_t **_volume)
error_up:
up_write(&cell->vl_sem);
error:
- if (vlocation) afs_put_vlocation(vlocation);
- if (cell) afs_put_cell(cell);
+ afs_put_vlocation(vlocation);
+ afs_put_cell(cell);
- _leave(" = %d (%p)",ret,volume);
+ _leave(" = %d (%p)", ret, volume);
return ret;
error_discard:
up_write(&cell->vl_sem);
for (loop=volume->nservers-1; loop>=0; loop--)
- if (volume->servers[loop])
- afs_put_server(volume->servers[loop]);
+ afs_put_server(volume->servers[loop]);
kfree(volume);
goto error;
@@ -225,6 +250,9 @@ void afs_put_volume(afs_volume_t *volume)
afs_vlocation_t *vlocation;
int loop;
+ if (!volume)
+ return;
+
_enter("%p",volume);
vlocation = volume->vlocation;
@@ -246,16 +274,14 @@ void afs_put_volume(afs_volume_t *volume)
up_write(&vlocation->cell->vl_sem);
- afs_put_vlocation(vlocation);
-
/* finish cleaning up the volume */
-#if 0
- if (volume->cache) afs_put_cache(volume->cache);
+#ifdef AFS_CACHING_SUPPORT
+ cachefs_relinquish_cookie(volume->cache,0);
#endif
+ afs_put_vlocation(vlocation);
for (loop=volume->nservers-1; loop>=0; loop--)
- if (volume->servers[loop])
- afs_put_server(volume->servers[loop]);
+ afs_put_server(volume->servers[loop]);
kfree(volume);
@@ -428,3 +454,42 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in
return 0;
} /* end afs_volume_release_fileserver() */
+
+/*****************************************************************************/
+/*
+ * match a volume hash record stored in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry)
+{
+ const struct afs_cache_vhash *vhash = entry;
+ struct afs_volume *volume = target;
+
+ _enter("{%u},{%u}", volume->type, vhash->vtype);
+
+ if (volume->type == vhash->vtype) {
+ _leave(" = SUCCESS");
+ return CACHEFS_MATCH_SUCCESS;
+ }
+
+ _leave(" = FAILED");
+ return CACHEFS_MATCH_FAILED;
+} /* end afs_volume_cache_match() */
+#endif
+
+/*****************************************************************************/
+/*
+ * update a volume hash record stored in the cache
+ */
+#ifdef AFS_CACHING_SUPPORT
+static void afs_volume_cache_update(void *source, void *entry)
+{
+ struct afs_cache_vhash *vhash = entry;
+ struct afs_volume *volume = source;
+
+ _enter("");
+
+ vhash->vtype = volume->type;
+
+} /* end afs_volume_cache_update() */
+#endif
diff --git a/fs/afs/volume.h b/fs/afs/volume.h
index b9dc6d1b5cdd..bbe463464848 100644
--- a/fs/afs/volume.h
+++ b/fs/afs/volume.h
@@ -16,7 +16,7 @@
#include "fsclient.h"
#include "kafstimod.h"
#include "kafsasyncd.h"
-#include "cache-layout.h"
+#include "cache.h"
#define __packed __attribute__((packed))
@@ -30,21 +30,60 @@ typedef enum {
/*****************************************************************************/
/*
+ * entry in the cached volume location catalogue
+ */
+struct afs_cache_vlocation
+{
+ uint8_t name[64]; /* volume name (lowercase, padded with NULs) */
+ uint8_t nservers; /* number of entries used in servers[] */
+ uint8_t vidmask; /* voltype mask for vid[] */
+ uint8_t srvtmask[8]; /* voltype masks for servers[] */
+#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */
+#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */
+#define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */
+
+ afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */
+ struct in_addr servers[8]; /* fileserver addresses */
+ time_t rtime; /* last retrieval time */
+};
+
+#ifdef AFS_CACHING_SUPPORT
+extern struct cachefs_index_def afs_vlocation_cache_index_def;
+#endif
+
+/*****************************************************************************/
+/*
+ * volume -> vnode hash table entry
+ */
+struct afs_cache_vhash
+{
+ afs_voltype_t vtype; /* which volume variation */
+ uint8_t hash_bucket; /* which hash bucket this represents */
+} __attribute__((packed));
+
+#ifdef AFS_CACHING_SUPPORT
+extern struct cachefs_index_def afs_volume_cache_index_def;
+#endif
+
+/*****************************************************************************/
+/*
* AFS volume location record
*/
struct afs_vlocation
{
atomic_t usage;
struct list_head link; /* link in cell volume location list */
- afs_timer_t timeout; /* decaching timer */
- afs_cell_t *cell; /* cell to which volume belongs */
- struct list_head caches; /* backing caches */
- afsc_vldb_record_t vldb; /* volume information DB record */
+ struct afs_timer timeout; /* decaching timer */
+ struct afs_cell *cell; /* cell to which volume belongs */
+#ifdef AFS_CACHING_SUPPORT
+ struct cachefs_cookie *cache; /* caching cookie */
+#endif
+ struct afs_cache_vlocation vldb; /* volume information DB record */
struct afs_volume *vols[3]; /* volume access record pointer (index by type) */
rwlock_t lock; /* access lock */
unsigned long read_jif; /* time at which last read from vlserver */
- afs_timer_t upd_timer; /* update timer */
- afs_async_op_t upd_op; /* update operation */
+ struct afs_timer upd_timer; /* update timer */
+ struct afs_async_op upd_op; /* update operation */
afs_vlocation_upd_t upd_state; /* update state */
unsigned short upd_first_svix; /* first server index during update */
unsigned short upd_curr_svix; /* current server index during update */
@@ -53,13 +92,16 @@ struct afs_vlocation
unsigned short valid; /* T if valid */
};
-extern int afs_vlocation_lookup(afs_cell_t *cell, const char *name, afs_vlocation_t **_vlocation);
+extern int afs_vlocation_lookup(struct afs_cell *cell,
+ const char *name,
+ unsigned namesz,
+ struct afs_vlocation **_vlocation);
#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
-extern void __afs_put_vlocation(afs_vlocation_t *vlocation);
-extern void afs_put_vlocation(afs_vlocation_t *vlocation);
-extern void afs_vlocation_do_timeout(afs_vlocation_t *vlocation);
+extern void __afs_put_vlocation(struct afs_vlocation *vlocation);
+extern void afs_put_vlocation(struct afs_vlocation *vlocation);
+extern void afs_vlocation_do_timeout(struct afs_vlocation *vlocation);
/*****************************************************************************/
/*
@@ -68,25 +110,34 @@ extern void afs_vlocation_do_timeout(afs_vlocation_t *vlocation);
struct afs_volume
{
atomic_t usage;
- afs_cell_t *cell; /* cell to which belongs (unrefd ptr) */
- afs_vlocation_t *vlocation; /* volume location */
+ struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */
+ struct afs_vlocation *vlocation; /* volume location */
+#ifdef AFS_CACHING_SUPPORT
+ struct cachefs_cookie *cache; /* caching cookie */
+#endif
afs_volid_t vid; /* volume ID */
afs_voltype_t __packed type; /* type of volume */
char type_force; /* force volume type (suppress R/O -> R/W) */
unsigned short nservers; /* number of server slots filled */
unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
- afs_server_t *servers[8]; /* servers on which volume resides (ordered) */
+ struct afs_server *servers[8]; /* servers on which volume resides (ordered) */
struct rw_semaphore server_sem; /* lock for accessing current server */
};
-extern int afs_volume_lookup(const char *name, int ro, afs_volume_t **_volume);
+extern int afs_volume_lookup(const char *name,
+ struct afs_cell *cell,
+ int rwpath,
+ struct afs_volume **_volume);
#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
-extern void afs_put_volume(afs_volume_t *volume);
+extern void afs_put_volume(struct afs_volume *volume);
-extern int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server);
+extern int afs_volume_pick_fileserver(struct afs_volume *volume,
+ struct afs_server **_server);
-extern int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, int result);
+extern int afs_volume_release_fileserver(struct afs_volume *volume,
+ struct afs_server *server,
+ int result);
#endif /* _LINUX_AFS_VOLUME_H */
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 35561cea2f16..e15552bf175a 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -288,8 +288,10 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
static int ep_alloc_pages(char **pages, int numpages);
static int ep_free_pages(char **pages, int numpages);
static int ep_file_init(struct file *file, unsigned int hashbits);
-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd);
-static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
+static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file,
+ int fd);
+static struct list_head *ep_hash_entry(struct eventpoll *ep,
+ unsigned int index);
static int ep_init(struct eventpoll *ep, unsigned int hashbits);
static void ep_free(struct eventpoll *ep);
static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
@@ -299,7 +301,8 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
poll_table *pt);
static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
struct file *tfile, int fd);
-static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
+static int ep_modify(struct eventpoll *ep, struct epitem *epi,
+ struct epoll_event *event);
static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
static int ep_remove(struct eventpoll *ep, struct epitem *epi);
@@ -309,11 +312,12 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
static int ep_collect_ready_items(struct eventpoll *ep,
struct list_head *txlist, int maxevents);
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event *events);
+ struct epoll_event __user *events);
static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
static int ep_events_transfer(struct eventpoll *ep,
- struct epoll_event *events, int maxevents);
-static int ep_poll(struct eventpoll *ep, struct epoll_event *events,
+ struct epoll_event __user *events,
+ int maxevents);
+static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
int maxevents, long timeout);
static int eventpollfs_delete_dentry(struct dentry *dentry);
static struct inode *ep_eventpoll_inode(void);
@@ -532,11 +536,13 @@ eexit_1:
/*
- * The following function implement the controller interface for the eventpoll
- * file that enable the insertion/removal/change of file descriptors inside
- * the interest set. It rapresents the kernel part of the user space epoll_ctl(2).
+ * The following function implements the controller interface for
+ * the eventpoll file that enables the insertion/removal/change of
+ * file descriptors inside the interest set. It represents
+ * the kernel part of the user space epoll_ctl(2).
*/
-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+asmlinkage long
+sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
{
int error;
struct file *file, *tfile;
@@ -637,8 +643,8 @@ eexit_1:
* Implement the event wait interface for the eventpoll file. It is the kernel
* part of the user space epoll_wait(2).
*/
-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
- int timeout)
+asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
+ int maxevents, int timeout)
{
int error;
struct file *file;
@@ -662,7 +668,7 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxeven
goto eexit_1;
/*
- * We have to check that the file structure underneath the file descriptor
+ * We have to check that the file structure underneath the fd
* the user passed to us _is_ an eventpoll file.
*/
error = -EINVAL;
@@ -1409,7 +1415,7 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
* because of the way poll() is traditionally implemented in Linux.
*/
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event *events)
+ struct epoll_event __user *events)
{
int eventcnt = 0, eventbuf = 0;
unsigned int revents;
@@ -1521,7 +1527,8 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
/*
* Perform the transfer of events to user space.
*/
-static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
+static int ep_events_transfer(struct eventpoll *ep,
+ struct epoll_event __user *events, int maxevents)
{
int eventcnt = 0;
struct list_head txlist;
@@ -1549,8 +1556,8 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
}
-static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
- long timeout)
+static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
+ int maxevents, long timeout)
{
int res, eavail;
unsigned long flags;
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index 02f2db028047..b282670a54bc 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -20,7 +20,8 @@
#include "ext2.h"
#include "xattr.h"
-static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
+static int
+ext2_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 029190ca34e3..7e16d8d6ba90 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -11,8 +11,8 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
- loff_t *ppos);
+static ssize_t fat_file_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos);
struct file_operations fat_file_operations = {
.llseek = generic_file_llseek,
@@ -66,8 +66,8 @@ int fat_get_block(struct inode *inode, sector_t iblock,
return 0;
}
-static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
- loff_t *ppos)
+static ssize_t fat_file_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
{
struct inode *inode = filp->f_dentry->d_inode;
int retval;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 5cfb0fcb4596..d23db3257efa 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -18,13 +18,13 @@
#include <asm/uaccess.h>
#include <asm/bitops.h>
-static ssize_t proc_file_read(struct file * file, char * buf,
+static ssize_t proc_file_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos);
-static ssize_t proc_file_write(struct file * file, const char * buffer,
+static ssize_t proc_file_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos);
static loff_t proc_file_lseek(struct file *, loff_t, int);
-int proc_match(int len, const char *name,struct proc_dir_entry * de)
+int proc_match(int len, const char *name, struct proc_dir_entry *de)
{
if (de->namelen != len)
return 0;
@@ -45,7 +45,8 @@ static struct file_operations proc_file_operations = {
#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
static ssize_t
-proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+proc_file_read(struct file *file, char __user *buf, size_t nbytes,
+ loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
char *page;
@@ -59,8 +60,7 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
- while ((nbytes > 0) && !eof)
- {
+ while ((nbytes > 0) && !eof) {
count = MIN(PROC_BLOCK_SIZE, nbytes);
start = NULL;
@@ -184,7 +184,7 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
}
static ssize_t
-proc_file_write(struct file * file, const char * buffer,
+proc_file_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
@@ -201,7 +201,7 @@ proc_file_write(struct file * file, const char * buffer,
static loff_t
-proc_file_lseek(struct file * file, loff_t offset, int orig)
+proc_file_lseek(struct file *file, loff_t offset, int orig)
{
lock_kernel();
@@ -299,15 +299,16 @@ out:
return i;
}
-static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
+static int
+proc_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
- char *s=PDE(dentry->d_inode)->data;
+ char *s = PDE(dentry->d_inode)->data;
return vfs_readlink(dentry, buffer, buflen, s);
}
static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- char *s=PDE(dentry->d_inode)->data;
+ char *s = PDE(dentry->d_inode)->data;
return vfs_follow_link(nd, s);
}
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 93551065f4cf..f5db5985455c 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -27,7 +27,7 @@ static int open_kcore(struct inode * inode, struct file * filp)
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
-static ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
+static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
struct file_operations proc_kcore_operations = {
.read = read_kcore,
@@ -267,7 +267,8 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff)
/*
* read from the ELF header and then kernel memory
*/
-static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos)
+static ssize_t
+read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
{
ssize_t acc = 0;
size_t size, tsz;
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 5706afe8e887..9cfb5d6d3c5e 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
extern wait_queue_head_t log_wait;
-extern int do_syslog(int type, char * bug, int count);
+extern int do_syslog(int type, char __user *bug, int count);
static int kmsg_open(struct inode * inode, struct file * file)
{
@@ -30,13 +30,13 @@ static int kmsg_release(struct inode * inode, struct file * file)
return 0;
}
-static ssize_t kmsg_read(struct file * file, char * buf,
+static ssize_t kmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- return do_syslog(2,buf,count);
+ return do_syslog(2, buf, count);
}
-static unsigned int kmsg_poll(struct file *file, poll_table * wait)
+static unsigned int kmsg_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &log_wait, wait);
if (do_syslog(9, 0, 0))
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index e042f16e8764..9ccdfe207e75 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -343,7 +343,7 @@ static struct file_operations proc_modules_operations = {
#endif
extern struct seq_operations slabinfo_op;
-extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
+extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
static int slabinfo_open(struct inode *inode, struct file *file)
{
return seq_open(file, &slabinfo_op);
@@ -548,8 +548,8 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
* buffer. Use of the program readprofile is recommended in order to
* get meaningful info out of these data.
*/
-static ssize_t read_profile(struct file *file, char *buf,
- size_t count, loff_t *ppos)
+static ssize_t
+read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
ssize_t read;
@@ -580,13 +580,13 @@ static ssize_t read_profile(struct file *file, char *buf,
* Writing a 'profiling multiplier' value into it also re-sets the profiling
* interrupt frequency, on architectures that support this.
*/
-static ssize_t write_profile(struct file * file, const char * buf,
+static ssize_t write_profile(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
#ifdef CONFIG_SMP
extern int setup_profiling_timer (unsigned int multiplier);
- if (count==sizeof(int)) {
+ if (count == sizeof(int)) {
unsigned int multiplier;
if (copy_from_user(&multiplier, buf, sizeof(int)))
@@ -610,8 +610,8 @@ static struct file_operations proc_profile_operations = {
/*
* writing 'C' to /proc/sysrq-trigger is like sysrq-C
*/
-static ssize_t write_sysrq_trigger(struct file *file, const char *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
{
if (count) {
char c;
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 224d2c08d771..4b4d5af34c69 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -112,11 +112,13 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{
- struct inode * inode;
+ struct inode *inode;
+ int err;
+
if (!old_valid_dev(rdev))
return -EINVAL;
inode = ufs_new_inode(dir, mode);
- int err = PTR_ERR(inode);
+ err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
/* NOTE: that'll go when we get wide dev_t */
diff --git a/fs/xattr.c b/fs/xattr.c
index 37d2a109eef7..175d3e817619 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -53,7 +53,8 @@ xattr_free(void *ptr, size_t size)
* Extended attribute SET operations
*/
static long
-setxattr(struct dentry *d, char *name, void *value, size_t size, int flags)
+setxattr(struct dentry *d, char __user *name, void __user *value,
+ size_t size, int flags)
{
int error;
void *kvalue;
@@ -94,7 +95,8 @@ out:
}
asmlinkage long
-sys_setxattr(char *path, char *name, void *value, size_t size, int flags)
+sys_setxattr(char __user *path, char __user *name, void __user *value,
+ size_t size, int flags)
{
struct nameidata nd;
int error;
@@ -108,7 +110,8 @@ sys_setxattr(char *path, char *name, void *value, size_t size, int flags)
}
asmlinkage long
-sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags)
+sys_lsetxattr(char __user *path, char __user *name, void __user *value,
+ size_t size, int flags)
{
struct nameidata nd;
int error;
@@ -122,7 +125,8 @@ sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags)
}
asmlinkage long
-sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags)
+sys_fsetxattr(int fd, char __user *name, void __user *value,
+ size_t size, int flags)
{
struct file *f;
int error = -EBADF;
@@ -139,7 +143,7 @@ sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags)
* Extended attribute GET operations
*/
static ssize_t
-getxattr(struct dentry *d, char *name, void *value, size_t size)
+getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
{
ssize_t error;
void *kvalue;
@@ -172,7 +176,8 @@ out:
}
asmlinkage ssize_t
-sys_getxattr(char *path, char *name, void *value, size_t size)
+sys_getxattr(char __user *path, char __user *name, void __user *value,
+ size_t size)
{
struct nameidata nd;
ssize_t error;
@@ -186,7 +191,8 @@ sys_getxattr(char *path, char *name, void *value, size_t size)
}
asmlinkage ssize_t
-sys_lgetxattr(char *path, char *name, void *value, size_t size)
+sys_lgetxattr(char __user *path, char __user *name, void __user *value,
+ size_t size)
{
struct nameidata nd;
ssize_t error;
@@ -200,7 +206,7 @@ sys_lgetxattr(char *path, char *name, void *value, size_t size)
}
asmlinkage ssize_t
-sys_fgetxattr(int fd, char *name, void *value, size_t size)
+sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
{
struct file *f;
ssize_t error = -EBADF;
@@ -217,7 +223,7 @@ sys_fgetxattr(int fd, char *name, void *value, size_t size)
* Extended attribute LIST operations
*/
static ssize_t
-listxattr(struct dentry *d, char *list, size_t size)
+listxattr(struct dentry *d, char __user *list, size_t size)
{
ssize_t error;
char *klist;
@@ -243,7 +249,7 @@ out:
}
asmlinkage ssize_t
-sys_listxattr(char *path, char *list, size_t size)
+sys_listxattr(char __user *path, char __user *list, size_t size)
{
struct nameidata nd;
ssize_t error;
@@ -257,7 +263,7 @@ sys_listxattr(char *path, char *list, size_t size)
}
asmlinkage ssize_t
-sys_llistxattr(char *path, char *list, size_t size)
+sys_llistxattr(char __user *path, char __user *list, size_t size)
{
struct nameidata nd;
ssize_t error;
@@ -271,7 +277,7 @@ sys_llistxattr(char *path, char *list, size_t size)
}
asmlinkage ssize_t
-sys_flistxattr(int fd, char *list, size_t size)
+sys_flistxattr(int fd, char __user *list, size_t size)
{
struct file *f;
ssize_t error = -EBADF;
@@ -288,7 +294,7 @@ sys_flistxattr(int fd, char *list, size_t size)
* Extended attribute REMOVE operations
*/
static long
-removexattr(struct dentry *d, char *name)
+removexattr(struct dentry *d, char __user *name)
{
int error;
char kname[XATTR_NAME_MAX + 1];
@@ -313,7 +319,7 @@ out:
}
asmlinkage long
-sys_removexattr(char *path, char *name)
+sys_removexattr(char __user *path, char __user *name)
{
struct nameidata nd;
int error;
@@ -327,7 +333,7 @@ sys_removexattr(char *path, char *name)
}
asmlinkage long
-sys_lremovexattr(char *path, char *name)
+sys_lremovexattr(char __user *path, char __user *name)
{
struct nameidata nd;
int error;
@@ -341,7 +347,7 @@ sys_lremovexattr(char *path, char *name)
}
asmlinkage long
-sys_fremovexattr(int fd, char *name)
+sys_fremovexattr(int fd, char __user *name)
{
struct file *f;
int error = -EBADF;
diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
index 580b1093f119..51d587edf419 100644
--- a/include/asm-ia64/acpi.h
+++ b/include/asm-ia64/acpi.h
@@ -54,47 +54,35 @@
#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE()
-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
- do { \
- __asm__ volatile ("1: ld4 r29=[%1]\n" \
- ";;\n" \
- "mov ar.ccv=r29\n" \
- "mov r2=r29\n" \
- "shr.u r30=r29,1\n" \
- "and r29=-4,r29\n" \
- ";;\n" \
- "add r29=2,r29\n" \
- "and r30=1,r30\n" \
- ";;\n" \
- "add r29=r29,r30\n" \
- ";;\n" \
- "cmpxchg4.acq r30=[%1],r29,ar.ccv\n" \
- ";;\n" \
- "cmp.eq p6,p7=r2,r30\n" \
- "(p7) br.dpnt.few 1b\n" \
- "cmp.gt p8,p9=3,r29\n" \
- ";;\n" \
- "(p8) mov %0=-1\n" \
- "(p9) mov %0=r0\n" \
- :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
- } while (0)
+static inline int
+ia64_acpi_acquire_global_lock (unsigned int *lock)
+{
+ unsigned int old, new, val;
+ do {
+ old = *lock;
+ new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
+ val = ia64_cmpxchg4_acq(lock, new, old);
+ } while (unlikely (val != old));
+ return (new < 3) ? -1 : 0;
+}
-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
- do { \
- __asm__ volatile ("1: ld4 r29=[%1]\n" \
- ";;\n" \
- "mov ar.ccv=r29\n" \
- "mov r2=r29\n" \
- "and r29=-4,r29\n" \
- ";;\n" \
- "cmpxchg4.acq r30=[%1],r29,ar.ccv\n" \
- ";;\n" \
- "cmp.eq p6,p7=r2,r30\n" \
- "(p7) br.dpnt.few 1b\n" \
- "and %0=1,r2\n" \
- ";;\n" \
- :"=r"(Acq):"r"(GLptr):"r2","r29","r30","memory"); \
- } while (0)
+static inline int
+ia64_acpi_release_global_lock (unsigned int *lock)
+{
+ unsigned int old, new, val;
+ do {
+ old = *lock;
+ new = old & ~0x3;
+ val = ia64_cmpxchg4_acq(lock, new, old);
+ } while (unlikely (val != old));
+ return old & 0x1;
+}
+
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+ ((Acq) = ia64_acpi_acquire_global_lock((unsigned int *) GLptr))
+
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+ ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr))
const char *acpi_get_sysname (void);
int acpi_request_vector (u32 int_type);
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index 2e1398577c91..be653c915f21 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/profile.h>
#include <asm/machvec.h>
#include <asm/ptrace.h>
diff --git a/include/asm-ia64/intel_intrin.h b/include/asm-ia64/intel_intrin.h
new file mode 100644
index 000000000000..542f8421a099
--- /dev/null
+++ b/include/asm-ia64/intel_intrin.h
@@ -0,0 +1,254 @@
+#ifndef _ASM_IA64_INTEL_INTRIN_H
+#define _ASM_IA64_INTEL_INTRIN_H
+/*
+ * Intel Compiler Intrinsics
+ *
+ * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
+ * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
+ *
+ */
+#include <asm/types.h>
+
+void __lfetch(int lfhint, void *y);
+void __lfetch_excl(int lfhint, void *y);
+void __lfetch_fault(int lfhint, void *y);
+void __lfetch_fault_excl(int lfhint, void *y);
+
+/* In the following, whichFloatReg should be an integer from 0-127 */
+void __ldfs(const int whichFloatReg, void *src);
+void __ldfd(const int whichFloatReg, void *src);
+void __ldfe(const int whichFloatReg, void *src);
+void __ldf8(const int whichFloatReg, void *src);
+void __ldf_fill(const int whichFloatReg, void *src);
+void __stfs(void *dst, const int whichFloatReg);
+void __stfd(void *dst, const int whichFloatReg);
+void __stfe(void *dst, const int whichFloatReg);
+void __stf8(void *dst, const int whichFloatReg);
+void __stf_spill(void *dst, const int whichFloatReg);
+
+void __st1_rel(void *dst, const __s8 value);
+void __st2_rel(void *dst, const __s16 value);
+void __st4_rel(void *dst, const __s32 value);
+void __st8_rel(void *dst, const __s64 value);
+__u8 __ld1_acq(void *src);
+__u16 __ld2_acq(void *src);
+__u32 __ld4_acq(void *src);
+__u64 __ld8_acq(void *src);
+
+__u64 __fetchadd4_acq(__u32 *addend, const int increment);
+__u64 __fetchadd4_rel(__u32 *addend, const int increment);
+__u64 __fetchadd8_acq(__u64 *addend, const int increment);
+__u64 __fetchadd8_rel(__u64 *addend, const int increment);
+
+__u64 __getf_exp(double d);
+
+/* OS Related Itanium(R) Intrinsics */
+
+/* The names to use for whichReg and whichIndReg below come from
+ the include file asm/ia64regs.h */
+
+__u64 __getIndReg(const int whichIndReg, __s64 index);
+__u64 __getReg(const int whichReg);
+
+void __setIndReg(const int whichIndReg, __s64 index, __u64 value);
+void __setReg(const int whichReg, __u64 value);
+
+void __mf(void);
+void __mfa(void);
+void __synci(void);
+void __itcd(__s64 pa);
+void __itci(__s64 pa);
+void __itrd(__s64 whichTransReg, __s64 pa);
+void __itri(__s64 whichTransReg, __s64 pa);
+void __ptce(__s64 va);
+void __ptcl(__s64 va, __s64 pagesz);
+void __ptcg(__s64 va, __s64 pagesz);
+void __ptcga(__s64 va, __s64 pagesz);
+void __ptri(__s64 va, __s64 pagesz);
+void __ptrd(__s64 va, __s64 pagesz);
+void __invala (void);
+void __invala_gr(const int whichGeneralReg /* 0-127 */ );
+void __invala_fr(const int whichFloatReg /* 0-127 */ );
+void __nop(const int);
+void __fc(__u64 *addr);
+void __sum(int mask);
+void __rum(int mask);
+void __ssm(int mask);
+void __rsm(int mask);
+__u64 __thash(__s64);
+__u64 __ttag(__s64);
+__s64 __tpa(__s64);
+
+/* Intrinsics for implementing get/put_user macros */
+void __st_user(const char *tableName, __u64 addr, char size, char relocType, __u64 val);
+void __ld_user(const char *tableName, __u64 addr, char size, char relocType);
+
+/* This intrinsic does not generate code, it creates a barrier across which
+ * the compiler will not schedule data access instructions.
+ */
+void __memory_barrier(void);
+
+void __isrlz(void);
+void __dsrlz(void);
+
+__u64 _m64_mux1(__u64 a, const int n);
+__u64 __thash(__u64);
+
+/* Lock and Atomic Operation Related Intrinsics */
+__u64 _InterlockedExchange8(volatile __u8 *trgt, __u8 value);
+__u64 _InterlockedExchange16(volatile __u16 *trgt, __u16 value);
+__s64 _InterlockedExchange(volatile __u32 *trgt, __u32 value);
+__s64 _InterlockedExchange64(volatile __u64 *trgt, __u64 value);
+
+__u64 _InterlockedCompareExchange8_rel(volatile __u8 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange8_acq(volatile __u8 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange16_rel(volatile __u16 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange16_acq(volatile __u16 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange_rel(volatile __u32 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange_acq(volatile __u32 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange64_rel(volatile __u64 *dest, __u64 xchg, __u64 comp);
+__u64 _InterlockedCompareExchange64_acq(volatile __u64 *dest, __u64 xchg, __u64 comp);
+
+__s64 _m64_dep_mi(const int v, __s64 s, const int p, const int len);
+__s64 _m64_shrp(__s64 a, __s64 b, const int count);
+__s64 _m64_popcnt(__s64 a);
+
+#define ia64_barrier() __memory_barrier()
+
+#define ia64_stop() /* Nothing: As of now stop bit is generated for each
+ * intrinsic
+ */
+
+#define ia64_getreg __getReg
+#define ia64_setreg __setReg
+
+#define ia64_hint(x)
+
+#define ia64_mux1_brcst 0
+#define ia64_mux1_mix 8
+#define ia64_mux1_shuf 9
+#define ia64_mux1_alt 10
+#define ia64_mux1_rev 11
+
+#define ia64_mux1 _m64_mux1
+#define ia64_popcnt _m64_popcnt
+#define ia64_getf_exp __getf_exp
+#define ia64_shrp _m64_shrp
+
+#define ia64_tpa __tpa
+#define ia64_invala __invala
+#define ia64_invala_gr __invala_gr
+#define ia64_invala_fr __invala_fr
+#define ia64_nop __nop
+#define ia64_sum __sum
+#define ia64_ssm __ssm
+#define ia64_rum __rum
+#define ia64_rsm __rsm
+#define ia64_fc __fc
+
+#define ia64_ldfs __ldfs
+#define ia64_ldfd __ldfd
+#define ia64_ldfe __ldfe
+#define ia64_ldf8 __ldf8
+#define ia64_ldf_fill __ldf_fill
+
+#define ia64_stfs __stfs
+#define ia64_stfd __stfd
+#define ia64_stfe __stfe
+#define ia64_stf8 __stf8
+#define ia64_stf_spill __stf_spill
+
+#define ia64_mf __mf
+#define ia64_mfa __mfa
+
+#define ia64_fetchadd4_acq __fetchadd4_acq
+#define ia64_fetchadd4_rel __fetchadd4_rel
+#define ia64_fetchadd8_acq __fetchadd8_acq
+#define ia64_fetchadd8_rel __fetchadd8_rel
+
+#define ia64_xchg1 _InterlockedExchange8
+#define ia64_xchg2 _InterlockedExchange16
+#define ia64_xchg4 _InterlockedExchange
+#define ia64_xchg8 _InterlockedExchange64
+
+#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel
+#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq
+#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel
+#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq
+#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel
+#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq
+#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel
+#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq
+
+#define __ia64_set_dbr(index, val) \
+ __setIndReg(_IA64_REG_INDR_DBR, index, val)
+#define ia64_set_ibr(index, val) \
+ __setIndReg(_IA64_REG_INDR_IBR, index, val)
+#define ia64_set_pkr(index, val) \
+ __setIndReg(_IA64_REG_INDR_PKR, index, val)
+#define ia64_set_pmc(index, val) \
+ __setIndReg(_IA64_REG_INDR_PMC, index, val)
+#define ia64_set_pmd(index, val) \
+ __setIndReg(_IA64_REG_INDR_PMD, index, val)
+#define ia64_set_rr(index, val) \
+ __setIndReg(_IA64_REG_INDR_RR, index, val)
+
+#define ia64_get_cpuid(index) __getIndReg(_IA64_REG_INDR_CPUID, index)
+#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
+#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
+#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
+#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
+#define ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
+#define ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
+
+#define ia64_srlz_d __dsrlz
+#define ia64_srlz_i __isrlz
+
+#define ia64_st1_rel __st1_rel
+#define ia64_st2_rel __st2_rel
+#define ia64_st4_rel __st4_rel
+#define ia64_st8_rel __st8_rel
+
+#define ia64_ld1_acq __ld1_acq
+#define ia64_ld2_acq __ld2_acq
+#define ia64_ld4_acq __ld4_acq
+#define ia64_ld8_acq __ld8_acq
+
+#define ia64_sync_i __synci
+#define ia64_thash __thash
+#define ia64_ttag __ttag
+#define ia64_itcd __itcd
+#define ia64_itci __itci
+#define ia64_itrd __itrd
+#define ia64_itri __itri
+#define ia64_ptce __ptce
+#define ia64_ptcl __ptcl
+#define ia64_ptcg __ptcg
+#define ia64_ptcga __ptcga
+#define ia64_ptri __ptri
+#define ia64_ptrd __ptrd
+#define ia64_dep_mi _m64_dep_mi
+
+/* Values for lfhint in __lfetch and __lfetch_fault */
+
+#define ia64_lfhint_none 0
+#define ia64_lfhint_nt1 1
+#define ia64_lfhint_nt2 2
+#define ia64_lfhint_nta 3
+
+#define ia64_lfetch __lfetch
+#define ia64_lfetch_excl __lfetch_excl
+#define ia64_lfetch_fault __lfetch_fault
+#define ia64_lfetch_fault_excl __lfetch_fault_excl
+
+#define ia64_intrin_local_irq_restore(x) \
+do { \
+ if ((x) != 0) { \
+ ia64_ssm(IA64_PSR_I); \
+ ia64_srlz_d(); \
+ } else { \
+ ia64_rsm(IA64_PSR_I); \
+ } \
+} while (0)
+
+#endif /* _ASM_IA64_INTEL_INTRIN_H */
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index 6125e24cc296..48398a30de81 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -223,6 +223,12 @@ struct switch_stack {
};
#ifdef __KERNEL__
+/*
+ * We use the ia64_psr(regs)->ri to determine which of the three
+ * instructions in bundle (16 bytes) took the sample. Generate
+ * the canonical representation by adding to instruction pointer.
+ */
+# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
/* given a pointer to a task_struct, return the user's pt_regs */
# define ia64_task_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
# define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
diff --git a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h
index 2bd050863527..f98d3bb65a92 100644
--- a/include/asm-ia64/signal.h
+++ b/include/asm-ia64/signal.h
@@ -2,7 +2,7 @@
#define _ASM_IA64_SIGNAL_H
/*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* Unfortunately, this file is being included by bits/signal.h in
@@ -96,7 +96,16 @@
* ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
* more than 16KB of space.
*/
-#define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
+#if 1
+ /*
+ * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
+ * in wrong. ;-( To preserve backwards compatibility, we leave the kernel at the
+ * incorrect value and fix libc only.
+ */
+# define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
+#else
+# define MINSIGSTKSZ 131072 /* min. stack size for sigaltstack() */
+#endif
#define SIGSTKSZ 262144 /* default stack size for sigaltstack() */
#ifdef __KERNEL__
diff --git a/include/asm-ia64/sn/hcl.h b/include/asm-ia64/sn/hcl.h
index 4e571362db74..1c1ad00fc907 100644
--- a/include/asm-ia64/sn/hcl.h
+++ b/include/asm-ia64/sn/hcl.h
@@ -10,6 +10,7 @@
#define _ASM_IA64_SN_HCL_H
#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
extern vertex_hdl_t hwgraph_root;
extern vertex_hdl_t linux_busnum;
diff --git a/include/asm-ia64/sn/ioc3.h b/include/asm-ia64/sn/ioc3.h
deleted file mode 100644
index 379b632eb1d4..000000000000
--- a/include/asm-ia64/sn/ioc3.h
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-/* $Id: ioc3.h,v 1.2 2000/11/16 19:49:17 pfg Exp $
- *
- * Copyright (C) 1999 Ralf Baechle
- * This file is part of the Linux driver for the SGI IOC3.
- */
-#ifndef _ASM_IA64_SN_IOC3_H
-#define _ASM_IA64_SN_IOC3_H
-
-#include <asm/types.h>
-
-/* SUPERIO uart register map */
-typedef volatile struct ioc3_uartregs {
- union {
- volatile u8 rbr; /* read only, DLAB == 0 */
- volatile u8 thr; /* write only, DLAB == 0 */
- volatile u8 dll; /* DLAB == 1 */
- } u1;
- union {
- volatile u8 ier; /* DLAB == 0 */
- volatile u8 dlm; /* DLAB == 1 */
- } u2;
- union {
- volatile u8 iir; /* read only */
- volatile u8 fcr; /* write only */
- } u3;
- volatile u8 iu_lcr;
- volatile u8 iu_mcr;
- volatile u8 iu_lsr;
- volatile u8 iu_msr;
- volatile u8 iu_scr;
-} ioc3_uregs_t;
-
-#define iu_rbr u1.rbr
-#define iu_thr u1.thr
-#define iu_dll u1.dll
-#define iu_ier u2.ier
-#define iu_dlm u2.dlm
-#define iu_iir u3.iir
-#define iu_fcr u3.fcr
-
-struct ioc3_sioregs {
- volatile u8 fill[0x141]; /* starts at 0x141 */
-
- volatile u8 uartc;
- volatile u8 kbdcg;
-
- volatile u8 fill0[0x150 - 0x142 - 1];
-
- volatile u8 pp_data;
- volatile u8 pp_dsr;
- volatile u8 pp_dcr;
-
- volatile u8 fill1[0x158 - 0x152 - 1];
-
- volatile u8 pp_fifa;
- volatile u8 pp_cfgb;
- volatile u8 pp_ecr;
-
- volatile u8 fill2[0x168 - 0x15a - 1];
-
- volatile u8 rtcad;
- volatile u8 rtcdat;
-
- volatile u8 fill3[0x170 - 0x169 - 1];
-
- struct ioc3_uartregs uartb; /* 0x20170 */
- struct ioc3_uartregs uarta; /* 0x20178 */
-};
-
-/* Register layout of IOC3 in configuration space. */
-struct ioc3 {
- volatile u32 pad0[7]; /* 0x00000 */
- volatile u32 sio_ir; /* 0x0001c */
- volatile u32 sio_ies; /* 0x00020 */
- volatile u32 sio_iec; /* 0x00024 */
- volatile u32 sio_cr; /* 0x00028 */
- volatile u32 int_out; /* 0x0002c */
- volatile u32 mcr; /* 0x00030 */
-
- /* General Purpose I/O registers */
- volatile u32 gpcr_s; /* 0x00034 */
- volatile u32 gpcr_c; /* 0x00038 */
- volatile u32 gpdr; /* 0x0003c */
- volatile u32 gppr_0; /* 0x00040 */
- volatile u32 gppr_1; /* 0x00044 */
- volatile u32 gppr_2; /* 0x00048 */
- volatile u32 gppr_3; /* 0x0004c */
- volatile u32 gppr_4; /* 0x00050 */
- volatile u32 gppr_5; /* 0x00054 */
- volatile u32 gppr_6; /* 0x00058 */
- volatile u32 gppr_7; /* 0x0005c */
- volatile u32 gppr_8; /* 0x00060 */
- volatile u32 gppr_9; /* 0x00064 */
- volatile u32 gppr_10; /* 0x00068 */
- volatile u32 gppr_11; /* 0x0006c */
- volatile u32 gppr_12; /* 0x00070 */
- volatile u32 gppr_13; /* 0x00074 */
- volatile u32 gppr_14; /* 0x00078 */
- volatile u32 gppr_15; /* 0x0007c */
-
- /* Parallel Port Registers */
- volatile u32 ppbr_h_a; /* 0x00080 */
- volatile u32 ppbr_l_a; /* 0x00084 */
- volatile u32 ppcr_a; /* 0x00088 */
- volatile u32 ppcr; /* 0x0008c */
- volatile u32 ppbr_h_b; /* 0x00090 */
- volatile u32 ppbr_l_b; /* 0x00094 */
- volatile u32 ppcr_b; /* 0x00098 */
-
- /* Keyboard and Mouse Registers */
- volatile u32 km_csr; /* 0x0009c */
- volatile u32 k_rd; /* 0x000a0 */
- volatile u32 m_rd; /* 0x000a4 */
- volatile u32 k_wd; /* 0x000a8 */
- volatile u32 m_wd; /* 0x000ac */
-
- /* Serial Port Registers */
- volatile u32 sbbr_h; /* 0x000b0 */
- volatile u32 sbbr_l; /* 0x000b4 */
- volatile u32 sscr_a; /* 0x000b8 */
- volatile u32 stpir_a; /* 0x000bc */
- volatile u32 stcir_a; /* 0x000c0 */
- volatile u32 srpir_a; /* 0x000c4 */
- volatile u32 srcir_a; /* 0x000c8 */
- volatile u32 srtr_a; /* 0x000cc */
- volatile u32 shadow_a; /* 0x000d0 */
- volatile u32 sscr_b; /* 0x000d4 */
- volatile u32 stpir_b; /* 0x000d8 */
- volatile u32 stcir_b; /* 0x000dc */
- volatile u32 srpir_b; /* 0x000e0 */
- volatile u32 srcir_b; /* 0x000e4 */
- volatile u32 srtr_b; /* 0x000e8 */
- volatile u32 shadow_b; /* 0x000ec */
-
- /* Ethernet Registers */
- volatile u32 emcr; /* 0x000f0 */
- volatile u32 eisr; /* 0x000f4 */
- volatile u32 eier; /* 0x000f8 */
- volatile u32 ercsr; /* 0x000fc */
- volatile u32 erbr_h; /* 0x00100 */
- volatile u32 erbr_l; /* 0x00104 */
- volatile u32 erbar; /* 0x00108 */
- volatile u32 ercir; /* 0x0010c */
- volatile u32 erpir; /* 0x00110 */
- volatile u32 ertr; /* 0x00114 */
- volatile u32 etcsr; /* 0x00118 */
- volatile u32 ersr; /* 0x0011c */
- volatile u32 etcdc; /* 0x00120 */
- volatile u32 ebir; /* 0x00124 */
- volatile u32 etbr_h; /* 0x00128 */
- volatile u32 etbr_l; /* 0x0012c */
- volatile u32 etcir; /* 0x00130 */
- volatile u32 etpir; /* 0x00134 */
- volatile u32 emar_h; /* 0x00138 */
- volatile u32 emar_l; /* 0x0013c */
- volatile u32 ehar_h; /* 0x00140 */
- volatile u32 ehar_l; /* 0x00144 */
- volatile u32 micr; /* 0x00148 */
- volatile u32 midr_r; /* 0x0014c */
- volatile u32 midr_w; /* 0x00150 */
- volatile u32 pad1[(0x20000 - 0x00154) / 4];
-
- /* SuperIO Registers XXX */
- struct ioc3_sioregs sregs; /* 0x20000 */
- volatile u32 pad2[(0x40000 - 0x20180) / 4];
-
- /* SSRAM Diagnostic Access */
- volatile u32 ssram[(0x80000 - 0x40000) / 4];
-
- /* Bytebus device offsets
- 0x80000 - Access to the generic devices selected with DEV0
- 0x9FFFF bytebus DEV_SEL_0
- 0xA0000 - Access to the generic devices selected with DEV1
- 0xBFFFF bytebus DEV_SEL_1
- 0xC0000 - Access to the generic devices selected with DEV2
- 0xDFFFF bytebus DEV_SEL_2
- 0xE0000 - Access to the generic devices selected with DEV3
- 0xFFFFF bytebus DEV_SEL_3 */
-};
-
-/*
- * Ethernet RX Buffer
- */
-struct ioc3_erxbuf {
- u32 w0; /* first word (valid,bcnt,cksum) */
- u32 err; /* second word various errors */
- /* next comes n bytes of padding */
- /* then the received ethernet frame itself */
-};
-
-#define ERXBUF_IPCKSUM_MASK 0x0000ffff
-#define ERXBUF_BYTECNT_MASK 0x07ff0000
-#define ERXBUF_BYTECNT_SHIFT 16
-#define ERXBUF_V 0x80000000
-
-#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */
-#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */
-#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */
-#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */
-#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */
-#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */
-#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */
-#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */
-#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */
-#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */
-#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */
-#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */
-
-/*
- * Ethernet TX Descriptor
- */
-#define ETXD_DATALEN 104
-struct ioc3_etxd {
- u32 cmd; /* command field */
- u32 bufcnt; /* buffer counts field */
- u64 p1; /* buffer pointer 1 */
- u64 p2; /* buffer pointer 2 */
- u8 data[ETXD_DATALEN]; /* opt. tx data */
-};
-
-#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */
-#define ETXD_INTWHENDONE 0x00001000 /* intr when done */
-#define ETXD_D0V 0x00010000 /* data 0 valid */
-#define ETXD_B1V 0x00020000 /* buf 1 valid */
-#define ETXD_B2V 0x00040000 /* buf 2 valid */
-#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */
-#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */
-#define ETXD_CHKOFF_SHIFT 20
-
-#define ETXD_D0CNT_MASK 0x0000007f
-#define ETXD_B1CNT_MASK 0x0007ff00
-#define ETXD_B1CNT_SHIFT 8
-#define ETXD_B2CNT_MASK 0x7ff00000
-#define ETXD_B2CNT_SHIFT 20
-
-/*
- * Bytebus device space
- */
-#define IOC3_BYTEBUS_DEV0 0x80000L
-#define IOC3_BYTEBUS_DEV1 0xa0000L
-#define IOC3_BYTEBUS_DEV2 0xc0000L
-#define IOC3_BYTEBUS_DEV3 0xe0000L
-
-/* ------------------------------------------------------------------------- */
-
-/* Superio Registers (PIO Access) */
-#define IOC3_SIO_BASE 0x20000
-#define IOC3_SIO_UARTC (IOC3_SIO_BASE+0x141) /* UART Config */
-#define IOC3_SIO_KBDCG (IOC3_SIO_BASE+0x142) /* KBD Config */
-#define IOC3_SIO_PP_BASE (IOC3_SIO_BASE+PP_BASE) /* Parallel Port */
-#define IOC3_SIO_RTC_BASE (IOC3_SIO_BASE+0x168) /* Real Time Clock */
-#define IOC3_SIO_UB_BASE (IOC3_SIO_BASE+UARTB_BASE) /* UART B */
-#define IOC3_SIO_UA_BASE (IOC3_SIO_BASE+UARTA_BASE) /* UART A */
-
-/* SSRAM Diagnostic Access */
-#define IOC3_SSRAM IOC3_RAM_OFF /* base of SSRAM diagnostic access */
-#define IOC3_SSRAM_LEN 0x40000 /* 256kb (address space size, may not be fully populated) */
-#define IOC3_SSRAM_DM 0x0000ffff /* data mask */
-#define IOC3_SSRAM_PM 0x00010000 /* parity mask */
-
-/* bitmasks for PCI_SCR */
-#define PCI_SCR_PAR_RESP_EN 0x00000040 /* enb PCI parity checking */
-#define PCI_SCR_SERR_EN 0x00000100 /* enable the SERR# driver */
-#define PCI_SCR_DROP_MODE_EN 0x00008000 /* drop pios on parity err */
-#define PCI_SCR_RX_SERR (0x1 << 16)
-#define PCI_SCR_DROP_MODE (0x1 << 17)
-#define PCI_SCR_SIG_PAR_ERR (0x1 << 24)
-#define PCI_SCR_SIG_TAR_ABRT (0x1 << 27)
-#define PCI_SCR_RX_TAR_ABRT (0x1 << 28)
-#define PCI_SCR_SIG_MST_ABRT (0x1 << 29)
-#define PCI_SCR_SIG_SERR (0x1 << 30)
-#define PCI_SCR_PAR_ERR (0x1 << 31)
-
-/* bitmasks for IOC3_KM_CSR */
-#define KM_CSR_K_WRT_PEND 0x00000001 /* kbd port xmitting or resetting */
-#define KM_CSR_M_WRT_PEND 0x00000002 /* mouse port xmitting or resetting */
-#define KM_CSR_K_LCB 0x00000004 /* Line Cntrl Bit for last KBD write */
-#define KM_CSR_M_LCB 0x00000008 /* same for mouse */
-#define KM_CSR_K_DATA 0x00000010 /* state of kbd data line */
-#define KM_CSR_K_CLK 0x00000020 /* state of kbd clock line */
-#define KM_CSR_K_PULL_DATA 0x00000040 /* pull kbd data line low */
-#define KM_CSR_K_PULL_CLK 0x00000080 /* pull kbd clock line low */
-#define KM_CSR_M_DATA 0x00000100 /* state of ms data line */
-#define KM_CSR_M_CLK 0x00000200 /* state of ms clock line */
-#define KM_CSR_M_PULL_DATA 0x00000400 /* pull ms data line low */
-#define KM_CSR_M_PULL_CLK 0x00000800 /* pull ms clock line low */
-#define KM_CSR_EMM_MODE 0x00001000 /* emulation mode */
-#define KM_CSR_SIM_MODE 0x00002000 /* clock X8 */
-#define KM_CSR_K_SM_IDLE 0x00004000 /* Keyboard is idle */
-#define KM_CSR_M_SM_IDLE 0x00008000 /* Mouse is idle */
-#define KM_CSR_K_TO 0x00010000 /* Keyboard trying to send/receive */
-#define KM_CSR_M_TO 0x00020000 /* Mouse trying to send/receive */
-#define KM_CSR_K_TO_EN 0x00040000 /* KM_CSR_K_TO + KM_CSR_K_TO_EN = cause
- SIO_IR to assert */
-#define KM_CSR_M_TO_EN 0x00080000 /* KM_CSR_M_TO + KM_CSR_M_TO_EN = cause
- SIO_IR to assert */
-#define KM_CSR_K_CLAMP_ONE 0x00100000 /* Pull K_CLK low after rec. one char */
-#define KM_CSR_M_CLAMP_ONE 0x00200000 /* Pull M_CLK low after rec. one char */
-#define KM_CSR_K_CLAMP_THREE 0x00400000 /* Pull K_CLK low after rec. three chars */
-#define KM_CSR_M_CLAMP_THREE 0x00800000 /* Pull M_CLK low after rec. three char */
-
-/* bitmasks for IOC3_K_RD and IOC3_M_RD */
-#define KM_RD_DATA_2 0x000000ff /* 3rd char recvd since last read */
-#define KM_RD_DATA_2_SHIFT 0
-#define KM_RD_DATA_1 0x0000ff00 /* 2nd char recvd since last read */
-#define KM_RD_DATA_1_SHIFT 8
-#define KM_RD_DATA_0 0x00ff0000 /* 1st char recvd since last read */
-#define KM_RD_DATA_0_SHIFT 16
-#define KM_RD_FRAME_ERR_2 0x01000000 /* framing or parity error in byte 2 */
-#define KM_RD_FRAME_ERR_1 0x02000000 /* same for byte 1 */
-#define KM_RD_FRAME_ERR_0 0x04000000 /* same for byte 0 */
-
-#define KM_RD_KBD_MSE 0x08000000 /* 0 if from kbd, 1 if from mouse */
-#define KM_RD_OFLO 0x10000000 /* 4th char recvd before this read */
-#define KM_RD_VALID_2 0x20000000 /* DATA_2 valid */
-#define KM_RD_VALID_1 0x40000000 /* DATA_1 valid */
-#define KM_RD_VALID_0 0x80000000 /* DATA_0 valid */
-#define KM_RD_VALID_ALL (KM_RD_VALID_0|KM_RD_VALID_1|KM_RD_VALID_2)
-
-/* bitmasks for IOC3_K_WD & IOC3_M_WD */
-#define KM_WD_WRT_DATA 0x000000ff /* write to keyboard/mouse port */
-#define KM_WD_WRT_DATA_SHIFT 0
-
-/* bitmasks for serial RX status byte */
-#define RXSB_OVERRUN 0x01 /* char(s) lost */
-#define RXSB_PAR_ERR 0x02 /* parity error */
-#define RXSB_FRAME_ERR 0x04 /* framing error */
-#define RXSB_BREAK 0x08 /* break character */
-#define RXSB_CTS 0x10 /* state of CTS */
-#define RXSB_DCD 0x20 /* state of DCD */
-#define RXSB_MODEM_VALID 0x40 /* DCD, CTS and OVERRUN are valid */
-#define RXSB_DATA_VALID 0x80 /* data byte, FRAME_ERR PAR_ERR & BREAK valid */
-
-/* bitmasks for serial TX control byte */
-#define TXCB_INT_WHEN_DONE 0x20 /* interrupt after this byte is sent */
-#define TXCB_INVALID 0x00 /* byte is invalid */
-#define TXCB_VALID 0x40 /* byte is valid */
-#define TXCB_MCR 0x80 /* data<7:0> to modem control register */
-#define TXCB_DELAY 0xc0 /* delay data<7:0> mSec */
-
-/* bitmasks for IOC3_SBBR_L */
-#define SBBR_L_SIZE 0x00000001 /* 0 == 1KB rings, 1 == 4KB rings */
-#define SBBR_L_BASE 0xfffff000 /* lower serial ring base addr */
-
-/* bitmasks for IOC3_SSCR_<A:B> */
-#define SSCR_RX_THRESHOLD 0x000001ff /* hiwater mark */
-#define SSCR_TX_TIMER_BUSY 0x00010000 /* TX timer in progress */
-#define SSCR_HFC_EN 0x00020000 /* hardware flow control enabled */
-#define SSCR_RX_RING_DCD 0x00040000 /* post RX record on delta-DCD */
-#define SSCR_RX_RING_CTS 0x00080000 /* post RX record on delta-CTS */
-#define SSCR_HIGH_SPD 0x00100000 /* 4X speed */
-#define SSCR_DIAG 0x00200000 /* bypass clock divider for sim */
-#define SSCR_RX_DRAIN 0x08000000 /* drain RX buffer to memory */
-#define SSCR_DMA_EN 0x10000000 /* enable ring buffer DMA */
-#define SSCR_DMA_PAUSE 0x20000000 /* pause DMA */
-#define SSCR_PAUSE_STATE 0x40000000 /* sets when PAUSE takes effect */
-#define SSCR_RESET 0x80000000 /* reset DMA channels */
-
-/* all producer/comsumer pointers are the same bitfield */
-#define PROD_CONS_PTR_4K 0x00000ff8 /* for 4K buffers */
-#define PROD_CONS_PTR_1K 0x000003f8 /* for 1K buffers */
-#define PROD_CONS_PTR_OFF 3
-
-/* bitmasks for IOC3_SRCIR_<A:B> */
-#define SRCIR_ARM 0x80000000 /* arm RX timer */
-
-/* bitmasks for IOC3_SRPIR_<A:B> */
-#define SRPIR_BYTE_CNT 0x07000000 /* bytes in packer */
-#define SRPIR_BYTE_CNT_SHIFT 24
-
-/* bitmasks for IOC3_STCIR_<A:B> */
-#define STCIR_BYTE_CNT 0x0f000000 /* bytes in unpacker */
-#define STCIR_BYTE_CNT_SHIFT 24
-
-/* bitmasks for IOC3_SHADOW_<A:B> */
-#define SHADOW_DR 0x00000001 /* data ready */
-#define SHADOW_OE 0x00000002 /* overrun error */
-#define SHADOW_PE 0x00000004 /* parity error */
-#define SHADOW_FE 0x00000008 /* framing error */
-#define SHADOW_BI 0x00000010 /* break interrupt */
-#define SHADOW_THRE 0x00000020 /* transmit holding register empty */
-#define SHADOW_TEMT 0x00000040 /* transmit shift register empty */
-#define SHADOW_RFCE 0x00000080 /* char in RX fifo has an error */
-#define SHADOW_DCTS 0x00010000 /* delta clear to send */
-#define SHADOW_DDCD 0x00080000 /* delta data carrier detect */
-#define SHADOW_CTS 0x00100000 /* clear to send */
-#define SHADOW_DCD 0x00800000 /* data carrier detect */
-#define SHADOW_DTR 0x01000000 /* data terminal ready */
-#define SHADOW_RTS 0x02000000 /* request to send */
-#define SHADOW_OUT1 0x04000000 /* 16550 OUT1 bit */
-#define SHADOW_OUT2 0x08000000 /* 16550 OUT2 bit */
-#define SHADOW_LOOP 0x10000000 /* loopback enabled */
-
-/* bitmasks for IOC3_SRTR_<A:B> */
-#define SRTR_CNT 0x00000fff /* reload value for RX timer */
-#define SRTR_CNT_VAL 0x0fff0000 /* current value of RX timer */
-#define SRTR_CNT_VAL_SHIFT 16
-#define SRTR_HZ 16000 /* SRTR clock frequency */
-
-/* bitmasks for IOC3_SIO_IR, IOC3_SIO_IEC and IOC3_SIO_IES */
-#define SIO_IR_SA_TX_MT 0x00000001 /* Serial port A TX empty */
-#define SIO_IR_SA_RX_FULL 0x00000002 /* port A RX buf full */
-#define SIO_IR_SA_RX_HIGH 0x00000004 /* port A RX hiwat */
-#define SIO_IR_SA_RX_TIMER 0x00000008 /* port A RX timeout */
-#define SIO_IR_SA_DELTA_DCD 0x00000010 /* port A delta DCD */
-#define SIO_IR_SA_DELTA_CTS 0x00000020 /* port A delta CTS */
-#define SIO_IR_SA_INT 0x00000040 /* port A pass-thru intr */
-#define SIO_IR_SA_TX_EXPLICIT 0x00000080 /* port A explicit TX thru */
-#define SIO_IR_SA_MEMERR 0x00000100 /* port A PCI error */
-#define SIO_IR_SB_TX_MT 0x00000200 /* */
-#define SIO_IR_SB_RX_FULL 0x00000400 /* */
-#define SIO_IR_SB_RX_HIGH 0x00000800 /* */
-#define SIO_IR_SB_RX_TIMER 0x00001000 /* */
-#define SIO_IR_SB_DELTA_DCD 0x00002000 /* */
-#define SIO_IR_SB_DELTA_CTS 0x00004000 /* */
-#define SIO_IR_SB_INT 0x00008000 /* */
-#define SIO_IR_SB_TX_EXPLICIT 0x00010000 /* */
-#define SIO_IR_SB_MEMERR 0x00020000 /* */
-#define SIO_IR_PP_INT 0x00040000 /* P port pass-thru intr */
-#define SIO_IR_PP_INTA 0x00080000 /* PP context A thru */
-#define SIO_IR_PP_INTB 0x00100000 /* PP context B thru */
-#define SIO_IR_PP_MEMERR 0x00200000 /* PP PCI error */
-#define SIO_IR_KBD_INT 0x00400000 /* kbd/mouse intr */
-#define SIO_IR_RT_INT 0x08000000 /* RT output pulse */
-#define SIO_IR_GEN_INT1 0x10000000 /* RT input pulse */
-#define SIO_IR_GEN_INT_SHIFT 28
-
-/* per device interrupt masks */
-#define SIO_IR_SA (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL | \
- SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER | \
- SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS | \
- SIO_IR_SA_INT | SIO_IR_SA_TX_EXPLICIT | \
- SIO_IR_SA_MEMERR)
-#define SIO_IR_SB (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL | \
- SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER | \
- SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS | \
- SIO_IR_SB_INT | SIO_IR_SB_TX_EXPLICIT | \
- SIO_IR_SB_MEMERR)
-#define SIO_IR_PP (SIO_IR_PP_INT | SIO_IR_PP_INTA | \
- SIO_IR_PP_INTB | SIO_IR_PP_MEMERR)
-#define SIO_IR_RT (SIO_IR_RT_INT | SIO_IR_GEN_INT1)
-
-/* macro to load pending interrupts */
-#define IOC3_PENDING_INTRS(mem) (PCI_INW(&((mem)->sio_ir)) & \
- PCI_INW(&((mem)->sio_ies_ro)))
-
-/* bitmasks for SIO_CR */
-#define SIO_CR_SIO_RESET 0x00000001 /* reset the SIO */
-#define SIO_CR_SER_A_BASE 0x000000fe /* DMA poll addr port A */
-#define SIO_CR_SER_A_BASE_SHIFT 1
-#define SIO_CR_SER_B_BASE 0x00007f00 /* DMA poll addr port B */
-#define SIO_CR_SER_B_BASE_SHIFT 8
-#define SIO_SR_CMD_PULSE 0x00078000 /* byte bus strobe length */
-#define SIO_CR_CMD_PULSE_SHIFT 15
-#define SIO_CR_ARB_DIAG 0x00380000 /* cur !enet PCI requet (ro) */
-#define SIO_CR_ARB_DIAG_TXA 0x00000000
-#define SIO_CR_ARB_DIAG_RXA 0x00080000
-#define SIO_CR_ARB_DIAG_TXB 0x00100000
-#define SIO_CR_ARB_DIAG_RXB 0x00180000
-#define SIO_CR_ARB_DIAG_PP 0x00200000
-#define SIO_CR_ARB_DIAG_IDLE 0x00400000 /* 0 -> active request (ro) */
-
-/* bitmasks for INT_OUT */
-#define INT_OUT_COUNT 0x0000ffff /* pulse interval timer */
-#define INT_OUT_MODE 0x00070000 /* mode mask */
-#define INT_OUT_MODE_0 0x00000000 /* set output to 0 */
-#define INT_OUT_MODE_1 0x00040000 /* set output to 1 */
-#define INT_OUT_MODE_1PULSE 0x00050000 /* send 1 pulse */
-#define INT_OUT_MODE_PULSES 0x00060000 /* send 1 pulse every interval */
-#define INT_OUT_MODE_SQW 0x00070000 /* toggle output every interval */
-#define INT_OUT_DIAG 0x40000000 /* diag mode */
-#define INT_OUT_INT_OUT 0x80000000 /* current state of INT_OUT */
-
-/* time constants for INT_OUT */
-#define INT_OUT_NS_PER_TICK (30 * 260) /* 30 ns PCI clock, divisor=260 */
-#define INT_OUT_TICKS_PER_PULSE 3 /* outgoing pulse lasts 3 ticks */
-#define INT_OUT_US_TO_COUNT(x) /* convert uS to a count value */ \
- (((x) * 10 + INT_OUT_NS_PER_TICK / 200) * \
- 100 / INT_OUT_NS_PER_TICK - 1)
-#define INT_OUT_COUNT_TO_US(x) /* convert count value to uS */ \
- (((x) + 1) * INT_OUT_NS_PER_TICK / 1000)
-#define INT_OUT_MIN_TICKS 3 /* min period is width of pulse in "ticks" */
-#define INT_OUT_MAX_TICKS INT_OUT_COUNT /* largest possible count */
-
-/* bitmasks for GPCR */
-#define GPCR_DIR 0x000000ff /* tristate pin input or output */
-#define GPCR_DIR_PIN(x) (1<<(x)) /* access one of the DIR bits */
-#define GPCR_EDGE 0x000f0000 /* extint edge or level sensitive */
-#define GPCR_EDGE_PIN(x) (1<<((x)+15)) /* access one of the EDGE bits */
-
-/* values for GPCR */
-#define GPCR_INT_OUT_EN 0x00100000 /* enable INT_OUT to pin 0 */
-#define GPCR_MLAN_EN 0x00200000 /* enable MCR to pin 8 */
-#define GPCR_DIR_SERA_XCVR 0x00000080 /* Port A Transceiver select enable */
-#define GPCR_DIR_SERB_XCVR 0x00000040 /* Port B Transceiver select enable */
-#define GPCR_DIR_PHY_RST 0x00000020 /* ethernet PHY reset enable */
-
-/* defs for some of the generic I/O pins */
-#define GPCR_PHY_RESET 0x20 /* pin is output to PHY reset */
-#define GPCR_UARTB_MODESEL 0x40 /* pin is output to port B mode sel */
-#define GPCR_UARTA_MODESEL 0x80 /* pin is output to port A mode sel */
-
-#define GPPR_PHY_RESET_PIN 5 /* GIO pin controlling phy reset */
-#define GPPR_UARTB_MODESEL_PIN 6 /* GIO pin controlling uart b mode select */
-#define GPPR_UARTA_MODESEL_PIN 7 /* GIO pin controlling uart a mode select */
-
-#define EMCR_DUPLEX 0x00000001
-#define EMCR_PROMISC 0x00000002
-#define EMCR_PADEN 0x00000004
-#define EMCR_RXOFF_MASK 0x000001f8
-#define EMCR_RXOFF_SHIFT 3
-#define EMCR_RAMPAR 0x00000200
-#define EMCR_BADPAR 0x00000800
-#define EMCR_BUFSIZ 0x00001000
-#define EMCR_TXDMAEN 0x00002000
-#define EMCR_TXEN 0x00004000
-#define EMCR_RXDMAEN 0x00008000
-#define EMCR_RXEN 0x00010000
-#define EMCR_LOOPBACK 0x00020000
-#define EMCR_ARB_DIAG 0x001c0000
-#define EMCR_ARB_DIAG_IDLE 0x00200000
-#define EMCR_RST 0x80000000
-
-#define EISR_RXTIMERINT 0x00000001
-#define EISR_RXTHRESHINT 0x00000002
-#define EISR_RXOFLO 0x00000004
-#define EISR_RXBUFOFLO 0x00000008
-#define EISR_RXMEMERR 0x00000010
-#define EISR_RXPARERR 0x00000020
-#define EISR_TXEMPTY 0x00010000
-#define EISR_TXRTRY 0x00020000
-#define EISR_TXEXDEF 0x00040000
-#define EISR_TXLCOL 0x00080000
-#define EISR_TXGIANT 0x00100000
-#define EISR_TXBUFUFLO 0x00200000
-#define EISR_TXEXPLICIT 0x00400000
-#define EISR_TXCOLLWRAP 0x00800000
-#define EISR_TXDEFERWRAP 0x01000000
-#define EISR_TXMEMERR 0x02000000
-#define EISR_TXPARERR 0x04000000
-
-#define ERCSR_THRESH_MASK 0x000001ff /* enet RX threshold */
-#define ERCSR_RX_TMR 0x40000000 /* simulation only */
-#define ERCSR_DIAG_OFLO 0x80000000 /* simulation only */
-
-#define ERBR_ALIGNMENT 4096
-#define ERBR_L_RXRINGBASE_MASK 0xfffff000
-
-#define ERBAR_BARRIER_BIT 0x0100
-#define ERBAR_RXBARR_MASK 0xffff0000
-#define ERBAR_RXBARR_SHIFT 16
-
-#define ERCIR_RXCONSUME_MASK 0x00000fff
-
-#define ERPIR_RXPRODUCE_MASK 0x00000fff
-#define ERPIR_ARM 0x80000000
-
-#define ERTR_CNT_MASK 0x000007ff
-
-#define ETCSR_IPGT_MASK 0x0000007f
-#define ETCSR_IPGR1_MASK 0x00007f00
-#define ETCSR_IPGR1_SHIFT 8
-#define ETCSR_IPGR2_MASK 0x007f0000
-#define ETCSR_IPGR2_SHIFT 16
-#define ETCSR_NOTXCLK 0x80000000
-
-#define ETCDC_COLLCNT_MASK 0x0000ffff
-#define ETCDC_DEFERCNT_MASK 0xffff0000
-#define ETCDC_DEFERCNT_SHIFT 16
-
-#define ETBR_ALIGNMENT (64*1024)
-#define ETBR_L_RINGSZ_MASK 0x00000001
-#define ETBR_L_RINGSZ128 0
-#define ETBR_L_RINGSZ512 1
-#define ETBR_L_TXRINGBASE_MASK 0xffffc000
-
-#define ETCIR_TXCONSUME_MASK 0x0000ffff
-#define ETCIR_IDLE 0x80000000
-
-#define ETPIR_TXPRODUCE_MASK 0x0000ffff
-
-#define EBIR_TXBUFPROD_MASK 0x0000001f
-#define EBIR_TXBUFCONS_MASK 0x00001f00
-#define EBIR_TXBUFCONS_SHIFT 8
-#define EBIR_RXBUFPROD_MASK 0x007fc000
-#define EBIR_RXBUFPROD_SHIFT 14
-#define EBIR_RXBUFCONS_MASK 0xff800000
-#define EBIR_RXBUFCONS_SHIFT 23
-
-#define MICR_REGADDR_MASK 0x0000001f
-#define MICR_PHYADDR_MASK 0x000003e0
-#define MICR_PHYADDR_SHIFT 5
-#define MICR_READTRIG 0x00000400
-#define MICR_BUSY 0x00000800
-
-#define MIDR_DATA_MASK 0x0000ffff
-
-#define ERXBUF_IPCKSUM_MASK 0x0000ffff
-#define ERXBUF_BYTECNT_MASK 0x07ff0000
-#define ERXBUF_BYTECNT_SHIFT 16
-#define ERXBUF_V 0x80000000
-
-#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */
-#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */
-#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */
-#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */
-#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */
-#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */
-#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */
-#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */
-#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */
-#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */
-#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */
-#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */
-
-#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */
-#define ETXD_INTWHENDONE 0x00001000 /* intr when done */
-#define ETXD_D0V 0x00010000 /* data 0 valid */
-#define ETXD_B1V 0x00020000 /* buf 1 valid */
-#define ETXD_B2V 0x00040000 /* buf 2 valid */
-#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */
-#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */
-#define ETXD_CHKOFF_SHIFT 20
-
-#define ETXD_D0CNT_MASK 0x0000007f
-#define ETXD_B1CNT_MASK 0x0007ff00
-#define ETXD_B1CNT_SHIFT 8
-#define ETXD_B2CNT_MASK 0x7ff00000
-#define ETXD_B2CNT_SHIFT 20
-
-typedef enum ioc3_subdevs_e {
- ioc3_subdev_ether,
- ioc3_subdev_generic,
- ioc3_subdev_nic,
- ioc3_subdev_kbms,
- ioc3_subdev_ttya,
- ioc3_subdev_ttyb,
- ioc3_subdev_ecpp,
- ioc3_subdev_rt,
- ioc3_nsubdevs
-} ioc3_subdev_t;
-
-/* subdevice disable bits,
- * from the standard INFO_LBL_SUBDEVS
- */
-#define IOC3_SDB_ETHER (1<<ioc3_subdev_ether)
-#define IOC3_SDB_GENERIC (1<<ioc3_subdev_generic)
-#define IOC3_SDB_NIC (1<<ioc3_subdev_nic)
-#define IOC3_SDB_KBMS (1<<ioc3_subdev_kbms)
-#define IOC3_SDB_TTYA (1<<ioc3_subdev_ttya)
-#define IOC3_SDB_TTYB (1<<ioc3_subdev_ttyb)
-#define IOC3_SDB_ECPP (1<<ioc3_subdev_ecpp)
-#define IOC3_SDB_RT (1<<ioc3_subdev_rt)
-
-#define IOC3_ALL_SUBDEVS ((1<<ioc3_nsubdevs)-1)
-
-#define IOC3_SDB_SERIAL (IOC3_SDB_TTYA|IOC3_SDB_TTYB)
-
-#define IOC3_STD_SUBDEVS IOC3_ALL_SUBDEVS
-
-#define IOC3_INTA_SUBDEVS IOC3_SDB_ETHER
-#define IOC3_INTB_SUBDEVS (IOC3_SDB_GENERIC|IOC3_SDB_KBMS|IOC3_SDB_SERIAL|IOC3_SDB_ECPP|IOC3_SDB_RT)
-
-/*
- * PCI Configuration Space Register Address Map, use offset from IOC3 PCI
- * configuration base such that this can be used for multiple IOC3s
- */
-#define IOC3_PCI_ID 0x0 /* ID */
-
-#define IOC3_VENDOR_ID_NUM 0x10A9
-#define IOC3_DEVICE_ID_NUM 0x0003
-
-#endif /* _ASM_IA64_SN_IOC3_H */
diff --git a/include/asm-ia64/sn/klclock.h b/include/asm-ia64/sn/klclock.h
deleted file mode 100644
index a288d7fd0bb7..000000000000
--- a/include/asm-ia64/sn/klclock.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996, 2001-2003 Silicon Graphics, Inc. All rights reserved.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#ifndef _ASM_IA64_SN_KLCLOCK_H
-#define _ASM_IA64_SN_KLCLOCK_H
-
-#include <asm/sn/ioc3.h>
-#include <asm/sn/ioc4.h>
-
-#define RTC_BASE_ADDR (unsigned char *)(nvram_base)
-
-/* Defines for the SGS-Thomson M48T35 clock */
-#define RTC_SGS_WRITE_ENABLE 0x80
-#define RTC_SGS_READ_PROTECT 0x40
-#define RTC_SGS_YEAR_ADDR (RTC_BASE_ADDR + 0x7fffL)
-#define RTC_SGS_MONTH_ADDR (RTC_BASE_ADDR + 0x7ffeL)
-#define RTC_SGS_DATE_ADDR (RTC_BASE_ADDR + 0x7ffdL)
-#define RTC_SGS_DAY_ADDR (RTC_BASE_ADDR + 0x7ffcL)
-#define RTC_SGS_HOUR_ADDR (RTC_BASE_ADDR + 0x7ffbL)
-#define RTC_SGS_MIN_ADDR (RTC_BASE_ADDR + 0x7ffaL)
-#define RTC_SGS_SEC_ADDR (RTC_BASE_ADDR + 0x7ff9L)
-#define RTC_SGS_CONTROL_ADDR (RTC_BASE_ADDR + 0x7ff8L)
-
-/* Defines for the Dallas DS1386 */
-#define RTC_DAL_UPDATE_ENABLE 0x80
-#define RTC_DAL_UPDATE_DISABLE 0x00
-#define RTC_DAL_YEAR_ADDR (RTC_BASE_ADDR + 0xaL)
-#define RTC_DAL_MONTH_ADDR (RTC_BASE_ADDR + 0x9L)
-#define RTC_DAL_DATE_ADDR (RTC_BASE_ADDR + 0x8L)
-#define RTC_DAL_DAY_ADDR (RTC_BASE_ADDR + 0x6L)
-#define RTC_DAL_HOUR_ADDR (RTC_BASE_ADDR + 0x4L)
-#define RTC_DAL_MIN_ADDR (RTC_BASE_ADDR + 0x2L)
-#define RTC_DAL_SEC_ADDR (RTC_BASE_ADDR + 0x1L)
-#define RTC_DAL_CONTROL_ADDR (RTC_BASE_ADDR + 0xbL)
-#define RTC_DAL_USER_ADDR (RTC_BASE_ADDR + 0xeL)
-
-/* Defines for the Dallas DS1742 */
-#define RTC_DS1742_WRITE_ENABLE 0x80
-#define RTC_DS1742_READ_ENABLE 0x40
-#define RTC_DS1742_UPDATE_DISABLE 0x00
-#define RTC_DS1742_YEAR_ADDR (RTC_BASE_ADDR + 0x7ffL)
-#define RTC_DS1742_MONTH_ADDR (RTC_BASE_ADDR + 0x7feL)
-#define RTC_DS1742_DATE_ADDR (RTC_BASE_ADDR + 0x7fdL)
-#define RTC_DS1742_DAY_ADDR (RTC_BASE_ADDR + 0x7fcL)
-#define RTC_DS1742_HOUR_ADDR (RTC_BASE_ADDR + 0x7fbL)
-#define RTC_DS1742_MIN_ADDR (RTC_BASE_ADDR + 0x7faL)
-#define RTC_DS1742_SEC_ADDR (RTC_BASE_ADDR + 0x7f9L)
-#define RTC_DS1742_CONTROL_ADDR (RTC_BASE_ADDR + 0x7f8L)
-#define RTC_DS1742_USER_ADDR (RTC_BASE_ADDR + 0x0L)
-
-#define BCD_TO_INT(x) (((x>>4) * 10) + (x & 0xf))
-#define INT_TO_BCD(x) (((x / 10)<<4) + (x % 10))
-
-#define YRREF 1970
-
-#endif /* _ASM_IA64_SN_KLCLOCK_H */
diff --git a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
index 857cd37c7dc2..b2ed848afa38 100644
--- a/include/asm-ia64/sn/nodepda.h
+++ b/include/asm-ia64/sn/nodepda.h
@@ -87,7 +87,7 @@ struct irqpda_s {
char irq_flags[NR_IRQS];
struct pci_dev *device_dev[NR_IRQS];
char share_count[NR_IRQS];
- struct pci_dev *current;
+ struct pci_dev *curr;
};
typedef struct irqpda_s irqpda_t;
diff --git a/include/asm-ia64/sn/pci/pciio.h b/include/asm-ia64/sn/pci/pciio.h
index bb03dc1a6ace..a1cd558e3fcb 100644
--- a/include/asm-ia64/sn/pci/pciio.h
+++ b/include/asm-ia64/sn/pci/pciio.h
@@ -695,5 +695,39 @@ extern int pciio_info_type1_get(pciio_info_t);
extern int pciio_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
extern int pciio_dma_enabled(vertex_hdl_t);
+/**
+ * sn_pci_set_vchan - Set the requested Virtual Channel bits into the mapped DMA
+ * address.
+ * @pci_dev: pci device pointer
+ * @addr: mapped dma address
+ * @vchan: Virtual Channel to use 0 or 1.
+ *
+ * Set the Virtual Channel bit in the mapped dma address.
+ */
+
+static inline int
+sn_pci_set_vchan(struct pci_dev *pci_dev,
+ dma_addr_t *addr,
+ int vchan)
+{
+ if (vchan > 1) {
+ return -1;
+ }
+
+ if (!(*addr >> 32)) /* Using a mask here would be cleaner */
+ return 0; /* but this generates better code */
+
+ if (vchan == 1) {
+ /* Set Bit 57 */
+ *addr |= (1UL << 57);
+ }
+ else {
+ /* Clear Bit 57 */
+ *addr &= ~(1UL << 57);
+ }
+
+ return 0;
+}
+
#endif /* C or C++ */
#endif /* _ASM_SN_PCI_PCIIO_H */
diff --git a/include/asm-ia64/sn/sn2/intr.h b/include/asm-ia64/sn/sn2/intr.h
index d021292d9bf1..adb87093a670 100644
--- a/include/asm-ia64/sn/sn2/intr.h
+++ b/include/asm-ia64/sn/sn2/intr.h
@@ -17,10 +17,11 @@
#define SGI_II_ERROR (0x31)
#define SGI_XBOW_ERROR (0x32)
#define SGI_PCIBR_ERROR (0x33)
+#define SGI_ACPI_SCI_INT (0x34)
#define SGI_XPC_NOTIFY (0xe7)
#define IA64_SN2_FIRST_DEVICE_VECTOR (0x34)
-#define IA64_SN2_LAST_DEVICE_VECTOR (0xe6)
+#define IA64_SN2_LAST_DEVICE_VECTOR (0xe7)
#define SN2_IRQ_RESERVED (0x1)
#define SN2_IRQ_CONNECTED (0x2)
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index 3a5f08f4c6f2..6ab675570740 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -24,6 +24,7 @@ typedef struct {
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
#define spin_lock_init(x) ((x)->lock = 0)
+#ifdef ASM_SUPPORTED
/*
* Try to get the lock. If we fail to get the lock, make a non-standard call to
* ia64_spinlock_contention(). We do not use a normal call because that would force all
@@ -85,6 +86,21 @@ _raw_spin_lock (spinlock_t *lock)
# endif /* CONFIG_MCKINLEY */
#endif
}
+#else /* !ASM_SUPPORTED */
+# define _raw_spin_lock(x) \
+do { \
+ __u32 *ia64_spinlock_ptr = (__u32 *) (x); \
+ __u64 ia64_spinlock_val; \
+ ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \
+ if (unlikely(ia64_spinlock_val)) { \
+ do { \
+ while (*ia64_spinlock_ptr) \
+ ia64_barrier(); \
+ ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0); \
+ } while (ia64_spinlock_val); \
+ } \
+} while (0)
+#endif /* !ASM_SUPPORTED */
#define spin_is_locked(x) ((x)->lock != 0)
#define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
@@ -117,22 +133,19 @@ do { \
ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \
} while (0)
+#ifdef ASM_SUPPORTED
#define _raw_write_lock(rw) \
do { \
__asm__ __volatile__ ( \
"mov ar.ccv = r0\n" \
- "dep r29 = -1, r0, 31, 1\n" \
- ";;\n" \
+ "dep r29 = -1, r0, 31, 1;;\n" \
"1:\n" \
- "ld4 r2 = [%0]\n" \
- ";;\n" \
+ "ld4 r2 = [%0];;\n" \
"cmp4.eq p0,p7 = r0,r2\n" \
"(p7) br.cond.spnt.few 1b \n" \
- "cmpxchg4.acq r2 = [%0], r29, ar.ccv\n" \
- ";;\n" \
+ "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \
"cmp4.eq p0,p7 = r0, r2\n" \
- "(p7) br.cond.spnt.few 1b\n" \
- ";;\n" \
+ "(p7) br.cond.spnt.few 1b;;\n" \
:: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
} while(0)
@@ -142,13 +155,35 @@ do { \
\
__asm__ __volatile__ ( \
"mov ar.ccv = r0\n" \
- "dep r29 = -1, r0, 31, 1\n" \
- ";;\n" \
+ "dep r29 = -1, r0, 31, 1;;\n" \
"cmpxchg4.acq %0 = [%1], r29, ar.ccv\n" \
: "=r"(result) : "r"(rw) : "ar.ccv", "r29", "memory"); \
(result == 0); \
})
+#else /* !ASM_SUPPORTED */
+
+#define _raw_write_lock(l) \
+({ \
+ __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
+ __u32 ia64_write_lock_ptr = (__u32 *) (l); \
+ do { \
+ while (*ia64_write_lock_ptr) \
+ ia64_barrier(); \
+ ia64_val = ia64_cmpxchg4_acq(ia64_write_lock_ptr, ia64_set_val, 0); \
+ } while (ia64_val); \
+})
+
+#define _raw_write_trylock(rw) \
+({ \
+ __u64 ia64_val; \
+ __u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1); \
+ ia64_val = ia64_cmpxchg4_acq((__u32 *)(rw), ia64_set_val, 0); \
+ (ia64_val == 0); \
+})
+
+#endif /* !ASM_SUPPORTED */
+
#define _raw_write_unlock(x) \
({ \
smp_mb__before_clear_bit(); /* need barrier before releasing lock... */ \
diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
index 80fd04aa5e5a..bd0a7c26a0ac 100644
--- a/include/asm-ia64/uaccess.h
+++ b/include/asm-ia64/uaccess.h
@@ -33,6 +33,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
+#include <asm/intrinsics.h>
#include <asm/pgtable.h>
/*
@@ -86,6 +87,8 @@ verify_area (int type, const void *addr, unsigned long size)
#define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#ifdef ASM_SUPPORTED
+
extern void __get_user_unknown (void);
#define __get_user_nocheck(x,ptr,size) \
@@ -217,6 +220,90 @@ extern void __put_user_unknown (void);
"[1:]" \
: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
+#else /* !ASM_SUPPORTED */
+
+#define RELOC_TYPE 2 /* ip-rel */
+
+#define __put_user_xx(val, addr, size, err) \
+ __st_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE, (unsigned long) (val)); \
+ (err) = ia64_getreg(_IA64_REG_R8);
+
+#define __get_user_xx(val, addr, size, err) \
+ __ld_user("__ex_table", (unsigned long) addr, size, RELOC_TYPE); \
+ (err) = ia64_getreg(_IA64_REG_R8); \
+ (val) = ia64_getreg(_IA64_REG_R9);
+
+extern void __get_user_unknown (void);
+
+#define __get_user_nocheck(x, ptr, size) \
+({ \
+ register long __gu_err = 0; \
+ register long __gu_val = 0; \
+ const __typeof__(*(ptr)) *__gu_addr = (ptr); \
+ switch (size) { \
+ case 1: case 2: case 4: case 8: \
+ __get_user_xx(__gu_val, __gu_addr, size, __gu_err); \
+ break; \
+ default: \
+ __get_user_unknown(); \
+ break; \
+ } \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
+ __gu_err; \
+})
+
+#define __get_user_check(x,ptr,size,segment) \
+({ \
+ register long __gu_err = -EFAULT; \
+ register long __gu_val = 0; \
+ const __typeof__(*(ptr)) *__gu_addr = (ptr); \
+ if (__access_ok((long) __gu_addr, size, segment)) { \
+ switch (size) { \
+ case 1: case 2: case 4: case 8: \
+ __get_user_xx(__gu_val, __gu_addr, size, __gu_err); \
+ break; \
+ default: \
+ __get_user_unknown(); break; \
+ } \
+ } \
+ (x) = (__typeof__(*(ptr))) __gu_val; \
+ __gu_err; \
+})
+
+extern void __put_user_unknown (void);
+
+#define __put_user_nocheck(x, ptr, size) \
+({ \
+ int __pu_err = 0; \
+ __typeof__(*(ptr)) *__pu_addr = (ptr); \
+ switch (size) { \
+ case 1: case 2: case 4: case 8: \
+ __put_user_xx(x, __pu_addr, size, __pu_err); \
+ break; \
+ default: \
+ __put_user_unknown(); break; \
+ } \
+ __pu_err; \
+})
+
+#define __put_user_check(x,ptr,size,segment) \
+({ \
+ register long __pu_err = -EFAULT; \
+ __typeof__(*(ptr)) *__pu_addr = (ptr); \
+ if (__access_ok((long)__pu_addr,size,segment)) { \
+ switch (size) { \
+ case 1: case 2: case 4: case 8: \
+ __put_user_xx(x,__pu_addr, size, __pu_err); \
+ break; \
+ default: \
+ __put_user_unknown(); break; \
+ } \
+ } \
+ __pu_err; \
+})
+
+#endif /* !ASM_SUPPORTED */
+
/*
* Complex access routines
*/
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 509df0678c98..f65623c70fb1 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -248,7 +248,6 @@
#define __NR_sys_clock_nanosleep 1256
#define __NR_sys_fstatfs64 1257
#define __NR_sys_statfs64 1258
-#define __NR_fadvises64_64 1259
#ifdef __KERNEL__
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index f747117285f4..d2403e44ff07 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -290,7 +290,7 @@ enum {
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
extern struct cpufreq_governor cpufreq_gov_performance;
#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
-#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
extern struct cpufreq_governor cpufreq_gov_userspace;
#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
#endif
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index f89acbe8183a..1ece9f119220 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -48,9 +48,10 @@ struct file;
/* Kernel space functions implementing the user space "epoll" API */
asmlinkage long sys_epoll_create(int size);
-asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
- int timeout);
+asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
+ struct epoll_event __user *event);
+asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
+ int maxevents, int timeout);
#ifdef CONFIG_EPOLL
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 13df4750a271..e0d0e74ba4c2 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -65,5 +65,8 @@ int seq_path(struct seq_file *, struct vfsmount *, struct dentry *, char *);
int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
int single_release(struct inode *, struct file *);
int seq_release_private(struct inode *, struct file *);
+
+#define SEQ_START_TOKEN ((void *)1)
+
#endif
#endif
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 5bb8b174ca68..8e09c20be413 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -67,6 +67,12 @@
#define PORT_PC9861 45
#define PORT_PC9801_101 46
+/* DZ */
+#define PORT_DZ 47
+
+/* Parisc type numbers. */
+#define PORT_MUX 48
+
/* Macintosh Zilog type numbers */
#define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */
#define PORT_PMAC_ZILOG 51
@@ -319,8 +325,8 @@ int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
/*
* Power Management
*/
-int uart_suspend_port(struct uart_driver *reg, struct uart_port *port, u32 level);
-int uart_resume_port(struct uart_driver *reg, struct uart_port *port, u32 level);
+int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
+int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index cb7d5d6a75b0..373e58fee2d4 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -80,8 +80,8 @@ extern int dirty_expire_centisecs;
struct ctl_table;
struct file;
-int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
- void *, size_t *);
+int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
+ void __user *, size_t *);
void page_writeback_init(void);
void balance_dirty_pages(struct address_space *mapping);
diff --git a/include/rxrpc/call.h b/include/rxrpc/call.h
index 5afe044b3f46..6ac1df7012e9 100644
--- a/include/rxrpc/call.h
+++ b/include/rxrpc/call.h
@@ -67,8 +67,8 @@ struct rxrpc_call
wait_queue_head_t waitq; /* wait queue for events to happen */
struct list_head link; /* general internal list link */
struct list_head call_link; /* master call list link */
- u32 chan_ix; /* connection channel index (net order) */
- u32 call_id; /* call ID on connection (net order) */
+ uint32_t chan_ix; /* connection channel index (net order) */
+ uint32_t call_id; /* call ID on connection (net order) */
unsigned long cjif; /* jiffies at call creation */
unsigned long flags; /* control flags */
#define RXRPC_CALL_ACKS_TIMO 0x00000001 /* ACKS timeout reached */
@@ -103,7 +103,7 @@ struct rxrpc_call
char ackr_dfr_perm; /* request for deferred ACKs permitted */
rxrpc_seq_t ackr_dfr_seq; /* seqno for deferred ACK */
struct rxrpc_ackpacket ackr; /* pending normal ACK packet */
- u8 ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
+ uint8_t ackr_array[RXRPC_CALL_ACK_WINDOW_SIZE]; /* ACK records */
/* presentation layer */
char app_last_rcv; /* T if received last packet from remote end */
@@ -131,14 +131,14 @@ struct rxrpc_call
struct list_head app_attn_link; /* application attention list linkage */
size_t app_mark; /* trigger callback when app_ready_qty>=app_mark */
char app_async_read; /* T if in async-read mode */
- u8 *app_read_buf; /* application async read buffer (app_mark size) */
- u8 *app_scr_alloc; /* application scratch allocation pointer */
+ uint8_t *app_read_buf; /* application async read buffer (app_mark size) */
+ uint8_t *app_scr_alloc; /* application scratch allocation pointer */
void *app_scr_ptr; /* application pointer into scratch buffer */
#define RXRPC_APP_MARK_EOF 0xFFFFFFFFU /* mark at end of input */
/* application scratch buffer */
- u8 app_scratch[0] __attribute__((aligned(sizeof(long))));
+ uint8_t app_scratch[0] __attribute__((aligned(sizeof(long))));
};
#define RXRPC_CALL_SCRATCH_SIZE (PAGE_SIZE - sizeof(struct rxrpc_call))
@@ -206,7 +206,7 @@ extern int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t si
extern int rxrpc_call_write_data(struct rxrpc_call *call,
size_t sioc,
struct iovec siov[],
- u8 rxhdr_flags,
+ uint8_t rxhdr_flags,
int alloc_flags,
int dup_data,
size_t *size_sent);
diff --git a/include/rxrpc/connection.h b/include/rxrpc/connection.h
index fc10fed01b21..14de354724f9 100644
--- a/include/rxrpc/connection.h
+++ b/include/rxrpc/connection.h
@@ -34,6 +34,7 @@ struct rxrpc_connection
struct list_head link; /* link in peer's list */
struct list_head proc_link; /* link in proc list */
struct list_head err_link; /* link in ICMP error processing list */
+ struct list_head id_link; /* link in ID grant list */
struct sockaddr_in addr; /* remote address */
struct rxrpc_call *channels[4]; /* channels (active calls) */
wait_queue_head_t chanwait; /* wait for channel to become available */
@@ -44,19 +45,19 @@ struct rxrpc_connection
rxrpc_serial_t serial_counter; /* packet serial number counter */
/* the following should all be in net order */
- u32 in_epoch; /* peer's epoch */
- u32 out_epoch; /* my epoch */
- u32 conn_id; /* connection ID, appropriately shifted */
- u16 service_id; /* service ID */
- u8 security_ix; /* security ID */
- u8 in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
- u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
+ uint32_t in_epoch; /* peer's epoch */
+ uint32_t out_epoch; /* my epoch */
+ uint32_t conn_id; /* connection ID, appropriately shifted */
+ uint16_t service_id; /* service ID */
+ uint8_t security_ix; /* security ID */
+ uint8_t in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
+ uint8_t out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
};
extern int rxrpc_create_connection(struct rxrpc_transport *trans,
- u16 port,
- u32 addr,
- unsigned short service_id,
+ uint16_t port,
+ uint32_t addr,
+ uint16_t service_id,
void *security,
struct rxrpc_connection **_conn);
diff --git a/include/rxrpc/message.h b/include/rxrpc/message.h
index 2e43c03c6857..9be208ab079e 100644
--- a/include/rxrpc/message.h
+++ b/include/rxrpc/message.h
@@ -9,8 +9,8 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
-#define _H_3AD3363A_3A9C_11D6_83D8_0002B3163499
+#ifndef _LINUX_RXRPC_MESSAGE_H
+#define _LINUX_RXRPC_MESSAGE_H
#include <rxrpc/packet.h>
@@ -61,7 +61,7 @@ static inline void rxrpc_put_message(struct rxrpc_message *msg)
extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
struct rxrpc_call *call,
- u8 type,
+ uint8_t type,
int count,
struct iovec diov[],
int alloc_flags,
@@ -69,4 +69,4 @@ extern int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
extern int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg);
-#endif /* _H_3AD3363A_3A9C_11D6_83D8_0002B3163499 */
+#endif /* _LINUX_RXRPC_MESSAGE_H */
diff --git a/include/rxrpc/packet.h b/include/rxrpc/packet.h
index 78999077f5b8..068813d65345 100644
--- a/include/rxrpc/packet.h
+++ b/include/rxrpc/packet.h
@@ -27,21 +27,21 @@ extern size_t RXRPC_MAX_PACKET_SIZE;
*/
struct rxrpc_header
{
- u32 epoch; /* client boot timestamp */
+ uint32_t epoch; /* client boot timestamp */
- u32 cid; /* connection and channel ID */
+ uint32_t cid; /* connection and channel ID */
#define RXRPC_MAXCALLS 4 /* max active calls per conn */
#define RXRPC_CHANNELMASK (RXRPC_MAXCALLS-1) /* mask for channel ID */
#define RXRPC_CIDMASK (~RXRPC_CHANNELMASK) /* mask for connection ID */
#define RXRPC_CIDSHIFT 2 /* shift for connection ID */
- u32 callNumber; /* call ID (0 for connection-level packets) */
+ uint32_t callNumber; /* call ID (0 for connection-level packets) */
#define RXRPC_PROCESS_MAXCALLS (1<<2) /* maximum number of active calls per conn (power of 2) */
- u32 seq; /* sequence number of pkt in call stream */
- u32 serial; /* serial number of pkt sent to network */
+ uint32_t seq; /* sequence number of pkt in call stream */
+ uint32_t serial; /* serial number of pkt sent to network */
- u8 type; /* packet type */
+ uint8_t type; /* packet type */
#define RXRPC_PACKET_TYPE_DATA 1 /* data */
#define RXRPC_PACKET_TYPE_ACK 2 /* ACK */
#define RXRPC_PACKET_TYPE_BUSY 3 /* call reject */
@@ -52,7 +52,7 @@ struct rxrpc_header
#define RXRPC_PACKET_TYPE_DEBUG 8 /* debug info request */
#define RXRPC_N_PACKET_TYPES 9 /* number of packet types (incl type 0) */
- u8 flags; /* packet flags */
+ uint8_t flags; /* packet flags */
#define RXRPC_CLIENT_INITIATED 0x01 /* signifies a packet generated by a client */
#define RXRPC_REQUEST_ACK 0x02 /* request an unconditional ACK of this packet */
#define RXRPC_LAST_PACKET 0x04 /* the last packet from this side for this call */
@@ -60,10 +60,10 @@ struct rxrpc_header
#define RXRPC_JUMBO_PACKET 0x20 /* [DATA] this is a jumbo packet */
#define RXRPC_SLOW_START_OK 0x20 /* [ACK] slow start supported */
- u8 userStatus; /* app-layer defined status */
- u8 securityIndex; /* security protocol ID */
- u16 _rsvd; /* reserved (used by kerberos security as cksum) */
- u16 serviceId; /* service ID */
+ uint8_t userStatus; /* app-layer defined status */
+ uint8_t securityIndex; /* security protocol ID */
+ uint16_t _rsvd; /* reserved (used by kerberos security as cksum) */
+ uint16_t serviceId; /* service ID */
} __attribute__((packed));
@@ -83,9 +83,9 @@ extern const char *rxrpc_pkts[];
*/
struct rxrpc_jumbo_header
{
- u8 flags; /* packet flags (as per rxrpc_header) */
- u8 pad;
- u16 _rsvd; /* reserved (used by kerberos security as cksum) */
+ uint8_t flags; /* packet flags (as per rxrpc_header) */
+ uint8_t pad;
+ uint16_t _rsvd; /* reserved (used by kerberos security as cksum) */
};
#define RXRPC_JUMBO_DATALEN 1412 /* non-terminal jumbo packet data length */
@@ -97,13 +97,14 @@ struct rxrpc_jumbo_header
*/
struct rxrpc_ackpacket
{
- u16 bufferSpace; /* number of packet buffers available */
- u16 maxSkew; /* diff between serno being ACK'd and highest serial no received */
- u32 firstPacket; /* sequence no of first ACK'd packet in attached list */
- u32 previousPacket; /* sequence no of previous packet received */
- u32 serial; /* serial no of packet that prompted this ACK */
-
- u8 reason; /* reason for ACK */
+ uint16_t bufferSpace; /* number of packet buffers available */
+ uint16_t maxSkew; /* diff between serno being ACK'd and highest serial no
+ * received */
+ uint32_t firstPacket; /* sequence no of first ACK'd packet in attached list */
+ uint32_t previousPacket; /* sequence no of previous packet received */
+ uint32_t serial; /* serial no of packet that prompted this ACK */
+
+ uint8_t reason; /* reason for ACK */
#define RXRPC_ACK_REQUESTED 1 /* ACK was requested on packet */
#define RXRPC_ACK_DUPLICATE 2 /* duplicate packet received */
#define RXRPC_ACK_OUT_OF_SEQUENCE 3 /* out of sequence packet received */
@@ -114,10 +115,10 @@ struct rxrpc_ackpacket
#define RXRPC_ACK_DELAY 8 /* nothing happened since received packet */
#define RXRPC_ACK_IDLE 9 /* ACK due to fully received ACK window */
- u8 nAcks; /* number of ACKs */
+ uint8_t nAcks; /* number of ACKs */
#define RXRPC_MAXACKS 255
- u8 acks[0]; /* list of ACK/NAKs */
+ uint8_t acks[0]; /* list of ACK/NAKs */
#define RXRPC_ACK_TYPE_NACK 0
#define RXRPC_ACK_TYPE_ACK 1
diff --git a/include/rxrpc/peer.h b/include/rxrpc/peer.h
index 0ab2730541ed..07e3a51b60b6 100644
--- a/include/rxrpc/peer.h
+++ b/include/rxrpc/peer.h
@@ -42,7 +42,10 @@ struct rxrpc_peer
struct rxrpc_timer timeout; /* timeout for grave destruction */
struct list_head link; /* link in transport's peer list */
struct list_head proc_link; /* link in /proc list */
- rwlock_t conn_lock; /* lock for connections */
+ rwlock_t conn_idlock; /* lock for connection IDs */
+ struct list_head conn_idlist; /* list of connections granted IDs */
+ uint32_t conn_idcounter; /* connection ID counter */
+ rwlock_t conn_lock; /* lock for active/dead connections */
struct list_head conn_active; /* active connections to/from this peer */
struct list_head conn_graveyard; /* graveyard for inactive connections */
spinlock_t conn_gylock; /* lock for conn_graveyard */
diff --git a/include/rxrpc/rxrpc.h b/include/rxrpc/rxrpc.h
index 454d59933675..df6595c32c37 100644
--- a/include/rxrpc/rxrpc.h
+++ b/include/rxrpc/rxrpc.h
@@ -14,7 +14,7 @@
#ifdef __KERNEL__
-extern u32 rxrpc_epoch;
+extern uint32_t rxrpc_epoch;
extern int rxrpc_ktrace;
extern int rxrpc_kdebug;
diff --git a/include/rxrpc/transport.h b/include/rxrpc/transport.h
index b9c225533158..92fb49c7d4b9 100644
--- a/include/rxrpc/transport.h
+++ b/include/rxrpc/transport.h
@@ -85,10 +85,11 @@ extern int rxrpc_create_transport(unsigned short port,
static inline void rxrpc_get_transport(struct rxrpc_transport *trans)
{
- if (atomic_read(&trans->usage)<=0)
+ if (atomic_read(&trans->usage) <= 0)
BUG();
atomic_inc(&trans->usage);
- //printk("rxrpc_get_transport(%p{u=%d})\n",trans,atomic_read(&trans->usage));
+ //printk("rxrpc_get_transport(%p{u=%d})\n",
+ // trans, atomic_read(&trans->usage));
}
extern void rxrpc_put_transport(struct rxrpc_transport *trans);
@@ -99,11 +100,6 @@ extern int rxrpc_add_service(struct rxrpc_transport *trans,
extern void rxrpc_del_service(struct rxrpc_transport *trans,
struct rxrpc_service *srv);
-#if 0
-extern int rxrpc_trans_add_connection(struct rxrpc_transport *trans,
- struct rxrpc_connection *conn);
-#endif
-
extern void rxrpc_trans_receive_packet(struct rxrpc_transport *trans);
extern int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
diff --git a/include/rxrpc/types.h b/include/rxrpc/types.h
index 40700bc61a6f..2f37ad8bb582 100644
--- a/include/rxrpc/types.h
+++ b/include/rxrpc/types.h
@@ -19,8 +19,8 @@
#include <linux/spinlock.h>
#include <asm/atomic.h>
-typedef unsigned rxrpc_seq_t; /* Rx message sequence number */
-typedef unsigned rxrpc_serial_t; /* Rx message serial number */
+typedef uint32_t rxrpc_seq_t; /* Rx message sequence number */
+typedef uint32_t rxrpc_serial_t; /* Rx message serial number */
struct rxrpc_call;
struct rxrpc_connection;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3180fa00d248..7648c165a86d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -643,7 +643,7 @@ static ctl_table vm_table[] = {
.data = &dirty_writeback_centisecs,
.maxlen = sizeof(dirty_writeback_centisecs),
.mode = 0644,
- .proc_handler = dirty_writeback_centisecs_handler,
+ .proc_handler = &dirty_writeback_centisecs_handler,
},
{
.ctl_name = VM_DIRTY_EXPIRE_CS,
diff --git a/net/core/dev.c b/net/core/dev.c
index 2cf887cee6d7..427100bd7f82 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -841,7 +841,11 @@ int dev_close(struct net_device *dev)
* engine, but this requires more changes in devices. */
smp_mb__after_clear_bit(); /* Commit netif_running(). */
- netif_poll_disable(dev);
+ while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+ /* No hurry. */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
/*
* Call the device specific close. This cannot fail.
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile
index 01ff446eae18..6efcb6f162a0 100644
--- a/net/rxrpc/Makefile
+++ b/net/rxrpc/Makefile
@@ -2,7 +2,9 @@
# Makefile for Linux kernel Rx RPC
#
-rxrpc-y := \
+#CFLAGS += -finstrument-functions
+
+rxrpc-objs := \
call.o \
connection.o \
krxiod.o \
@@ -13,7 +15,11 @@ rxrpc-y := \
rxrpc_syms.o \
transport.o
-rxrpc-$(CONFIG_PROC_FS) += proc.o
-rxrpc-$(CONFIG_SYSCTL) += sysctl.o
+ifeq ($(CONFIG_PROC_FS),y)
+rxrpc-objs += proc.o
+endif
+ifeq ($(CONFIG_SYSCTL),y)
+rxrpc-objs += sysctl.o
+endif
obj-$(CONFIG_RXRPC) := rxrpc.o
diff --git a/net/rxrpc/call.c b/net/rxrpc/call.c
index a0e81b58191d..0b8193629153 100644
--- a/net/rxrpc/call.c
+++ b/net/rxrpc/call.c
@@ -53,20 +53,25 @@ const char *rxrpc_call_error_states[] = {
};
const char *rxrpc_pkts[] = {
- "?00", "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
+ "?00",
+ "data", "ack", "busy", "abort", "ackall", "chall", "resp", "debug",
"?09", "?10", "?11", "?12", "?13", "?14", "?15"
};
const char *rxrpc_acks[] = {
- "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL", "-?-"
+ "---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL",
+ "-?-"
};
static const char _acktype[] = "NA-";
static void rxrpc_call_receive_packet(struct rxrpc_call *call);
-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg);
-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t higest);
+static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
+ struct rxrpc_message *msg);
+static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
+ struct rxrpc_message *msg);
+static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
+ rxrpc_seq_t higest);
static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest);
static int __rxrpc_call_read_data(struct rxrpc_call *call);
@@ -75,7 +80,7 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
rxrpc_seq_t seq,
size_t count);
#define _state(call) \
- _debug("[[[ state %s ]]]",rxrpc_call_states[call->app_call_state]);
+ _debug("[[[ state %s ]]]", rxrpc_call_states[call->app_call_state]);
static void rxrpc_call_default_attn_func(struct rxrpc_call *call)
{
@@ -103,7 +108,7 @@ static void __rxrpc_call_acks_timeout(unsigned long _call)
{
struct rxrpc_call *call = (struct rxrpc_call *) _call;
- _debug("ACKS TIMEOUT %05lu",jiffies - call->cjif);
+ _debug("ACKS TIMEOUT %05lu", jiffies - call->cjif);
call->flags |= RXRPC_CALL_ACKS_TIMO;
rxrpc_krxiod_queue_call(call);
@@ -113,7 +118,7 @@ static void __rxrpc_call_rcv_timeout(unsigned long _call)
{
struct rxrpc_call *call = (struct rxrpc_call *) _call;
- _debug("RCV TIMEOUT %05lu",jiffies - call->cjif);
+ _debug("RCV TIMEOUT %05lu", jiffies - call->cjif);
call->flags |= RXRPC_CALL_RCV_TIMO;
rxrpc_krxiod_queue_call(call);
@@ -133,15 +138,18 @@ static void __rxrpc_call_ackr_timeout(unsigned long _call)
/*
* calculate a timeout based on an RTT value
*/
-static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call, unsigned long val)
+static inline unsigned long __rxrpc_rtt_based_timeout(struct rxrpc_call *call,
+ unsigned long val)
{
- unsigned long expiry = call->conn->peer->rtt / (1000000/HZ);
+ unsigned long expiry = call->conn->peer->rtt / (1000000 / HZ);
expiry += 10;
- if (expiry<HZ/25) expiry = HZ/25;
- if (expiry>HZ) expiry = HZ;
+ if (expiry < HZ / 25)
+ expiry = HZ / 25;
+ if (expiry > HZ)
+ expiry = HZ;
- _leave(" = %lu jiffies",expiry);
+ _leave(" = %lu jiffies", expiry);
return jiffies + expiry;
} /* end __rxrpc_rtt_based_timeout() */
@@ -154,7 +162,7 @@ static inline int __rxrpc_create_call(struct rxrpc_connection *conn,
{
struct rxrpc_call *call;
- _enter("%p",conn);
+ _enter("%p", conn);
/* allocate and initialise a call record */
call = (struct rxrpc_call *) get_zeroed_page(GFP_KERNEL);
@@ -163,7 +171,7 @@ static inline int __rxrpc_create_call(struct rxrpc_connection *conn,
return -ENOMEM;
}
- atomic_set(&call->usage,1);
+ atomic_set(&call->usage, 1);
init_waitqueue_head(&call->waitq);
spin_lock_init(&call->lock);
@@ -200,7 +208,7 @@ static inline int __rxrpc_create_call(struct rxrpc_connection *conn,
call->cjif = jiffies;
- _leave(" = 0 (%p)",call);
+ _leave(" = 0 (%p)", call);
*_call = call;
@@ -217,34 +225,37 @@ int rxrpc_create_call(struct rxrpc_connection *conn,
rxrpc_call_aemap_func_t aemap,
struct rxrpc_call **_call)
{
- DECLARE_WAITQUEUE(myself,current);
+ DECLARE_WAITQUEUE(myself, current);
struct rxrpc_call *call;
int ret, cix, loop;
- _enter("%p",conn);
+ _enter("%p", conn);
/* allocate and initialise a call record */
- ret = __rxrpc_create_call(conn,&call);
- if (ret<0) {
- _leave(" = %d",ret);
+ ret = __rxrpc_create_call(conn, &call);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ret;
}
call->app_call_state = RXRPC_CSTATE_CLNT_SND_ARGS;
- if (attn) call->app_attn_func = attn;
- if (error) call->app_error_func = error;
- if (aemap) call->app_aemap_func = aemap;
+ if (attn)
+ call->app_attn_func = attn;
+ if (error)
+ call->app_error_func = error;
+ if (aemap)
+ call->app_aemap_func = aemap;
_state(call);
spin_lock(&conn->lock);
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&conn->chanwait,&myself);
+ add_wait_queue(&conn->chanwait, &myself);
try_again:
/* try to find an unused channel */
- for (cix=0; cix<4; cix++)
+ for (cix = 0; cix < 4; cix++)
if (!conn->channels[cix])
goto obtained_chan;
@@ -263,14 +274,15 @@ int rxrpc_create_call(struct rxrpc_connection *conn,
/* got a channel - now attach to the connection */
obtained_chan:
- remove_wait_queue(&conn->chanwait,&myself);
+ remove_wait_queue(&conn->chanwait, &myself);
set_current_state(TASK_RUNNING);
/* concoct a unique call number */
next_callid:
call->call_id = htonl(++conn->call_counter);
- for (loop=0; loop<4; loop++)
- if (conn->channels[loop] && conn->channels[loop]->call_id==call->call_id)
+ for (loop = 0; loop < 4; loop++)
+ if (conn->channels[loop] &&
+ conn->channels[loop]->call_id == call->call_id)
goto next_callid;
rxrpc_get_connection(conn);
@@ -281,24 +293,23 @@ int rxrpc_create_call(struct rxrpc_connection *conn,
spin_unlock(&conn->lock);
down_write(&rxrpc_calls_sem);
- list_add_tail(&call->call_link,&rxrpc_calls);
+ list_add_tail(&call->call_link, &rxrpc_calls);
up_write(&rxrpc_calls_sem);
__RXACCT(atomic_inc(&rxrpc_call_count));
*_call = call;
- _leave(" = 0 (call=%p cix=%u)",call,cix);
+ _leave(" = 0 (call=%p cix=%u)", call, cix);
return 0;
error_unwait:
- remove_wait_queue(&conn->chanwait,&myself);
+ remove_wait_queue(&conn->chanwait, &myself);
set_current_state(TASK_RUNNING);
spin_unlock(&conn->lock);
- free_page((unsigned long)call);
- _leave(" = %d",ret);
+ free_page((unsigned long) call);
+ _leave(" = %d", ret);
return ret;
-
} /* end rxrpc_create_call() */
/*****************************************************************************/
@@ -315,18 +326,18 @@ int rxrpc_incoming_call(struct rxrpc_connection *conn,
cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
- _enter("%p,%u,%u",conn,ntohl(msg->hdr.callNumber),cix);
+ _enter("%p,%u,%u", conn, ntohl(msg->hdr.callNumber), cix);
/* allocate and initialise a call record */
- ret = __rxrpc_create_call(conn,&call);
- if (ret<0) {
- _leave(" = %d",ret);
+ ret = __rxrpc_create_call(conn, &call);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ret;
}
call->pkt_rcv_count = 1;
call->app_call_state = RXRPC_CSTATE_SRVR_RCV_OPID;
- call->app_mark = sizeof(u32);
+ call->app_mark = sizeof(uint32_t);
_state(call);
@@ -348,20 +359,20 @@ int rxrpc_incoming_call(struct rxrpc_connection *conn,
spin_unlock(&conn->lock);
- if (ret<0) {
- free_page((unsigned long)call);
+ if (ret < 0) {
+ free_page((unsigned long) call);
call = NULL;
}
- if (ret==0) {
+ if (ret == 0) {
down_write(&rxrpc_calls_sem);
- list_add_tail(&call->call_link,&rxrpc_calls);
+ list_add_tail(&call->call_link, &rxrpc_calls);
up_write(&rxrpc_calls_sem);
__RXACCT(atomic_inc(&rxrpc_call_count));
*_call = call;
}
- _leave(" = %d [%p]",ret,call);
+ _leave(" = %d [%p]", ret, call);
return ret;
} /* end rxrpc_incoming_call() */
@@ -377,10 +388,11 @@ void rxrpc_put_call(struct rxrpc_call *call)
_enter("%p{u=%d}",call,atomic_read(&call->usage));
/* sanity check */
- if (atomic_read(&call->usage)<=0)
+ if (atomic_read(&call->usage) <= 0)
BUG();
- /* to prevent a race, the decrement and the de-list must be effectively atomic */
+ /* to prevent a race, the decrement and the de-list must be effectively
+ * atomic */
spin_lock(&conn->lock);
if (likely(!atomic_dec_and_test(&call->usage))) {
spin_unlock(&conn->lock);
@@ -388,7 +400,7 @@ void rxrpc_put_call(struct rxrpc_call *call)
return;
}
- if (conn->channels[ntohl(call->chan_ix)]==call)
+ if (conn->channels[ntohl(call->chan_ix)] == call)
conn->channels[ntohl(call->chan_ix)] = NULL;
spin_unlock(&conn->lock);
@@ -412,25 +424,29 @@ void rxrpc_put_call(struct rxrpc_call *call)
rxrpc_put_message(call->snd_ping);
while (!list_empty(&call->acks_pendq)) {
- msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
+ msg = list_entry(call->acks_pendq.next,
+ struct rxrpc_message, link);
list_del(&msg->link);
rxrpc_put_message(msg);
}
while (!list_empty(&call->rcv_receiveq)) {
- msg = list_entry(call->rcv_receiveq.next,struct rxrpc_message,link);
+ msg = list_entry(call->rcv_receiveq.next,
+ struct rxrpc_message, link);
list_del(&msg->link);
rxrpc_put_message(msg);
}
while (!list_empty(&call->app_readyq)) {
- msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
+ msg = list_entry(call->app_readyq.next,
+ struct rxrpc_message, link);
list_del(&msg->link);
rxrpc_put_message(msg);
}
while (!list_empty(&call->app_unreadyq)) {
- msg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
+ msg = list_entry(call->app_unreadyq.next,
+ struct rxrpc_message, link);
list_del(&msg->link);
rxrpc_put_message(msg);
}
@@ -442,7 +458,7 @@ void rxrpc_put_call(struct rxrpc_call *call)
up_write(&rxrpc_calls_sem);
__RXACCT(atomic_dec(&rxrpc_call_count));
- free_page((unsigned long)call);
+ free_page((unsigned long) call);
_leave(" [destroyed]");
} /* end rxrpc_put_call() */
@@ -451,7 +467,8 @@ void rxrpc_put_call(struct rxrpc_call *call)
/*
* actually generate a normal ACK
*/
-static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call, rxrpc_seq_t seq)
+static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call,
+ rxrpc_seq_t seq)
{
struct rxrpc_message *msg;
struct iovec diov[3];
@@ -478,35 +495,36 @@ static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call, rxrpc_seq
diov[0].iov_len = sizeof(struct rxrpc_ackpacket);
diov[0].iov_base = &call->ackr;
- diov[1].iov_len = (call->ackr_pend_cnt+3);
+ diov[1].iov_len = call->ackr_pend_cnt + 3;
diov[1].iov_base = call->ackr_array;
diov[2].iov_len = sizeof(aux);
diov[2].iov_base = &aux;
/* build and send the message */
- ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,3,diov,GFP_KERNEL,&msg);
- if (ret<0)
+ ret = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
+ 3, diov, GFP_KERNEL, &msg);
+ if (ret < 0)
goto out;
msg->seq = seq;
msg->hdr.seq = htonl(seq);
msg->hdr.flags |= RXRPC_SLOW_START_OK;
- ret = rxrpc_conn_sendmsg(call->conn,msg);
+ ret = rxrpc_conn_sendmsg(call->conn, msg);
rxrpc_put_message(msg);
- if (ret<0)
+ if (ret < 0)
goto out;
call->pkt_snd_count++;
/* count how many actual ACKs there were at the front */
- for (delta=0; delta<call->ackr_pend_cnt; delta++)
- if (call->ackr_array[delta]!=RXRPC_ACK_TYPE_ACK)
+ for (delta = 0; delta < call->ackr_pend_cnt; delta++)
+ if (call->ackr_array[delta] != RXRPC_ACK_TYPE_ACK)
break;
call->ackr_pend_cnt -= delta; /* all ACK'd to this point */
/* crank the ACK window around */
- if (delta==0) {
+ if (delta == 0) {
/* un-ACK'd window */
}
else if (delta < RXRPC_CALL_ACK_WINDOW_SIZE) {
@@ -528,22 +546,26 @@ static inline int __rxrpc_call_gen_normal_ACK(struct rxrpc_call *call, rxrpc_seq
/* fully ACK'd window
* - just clear the whole thing
*/
- memset(&call->ackr_array,RXRPC_ACK_TYPE_NACK,sizeof(call->ackr_array));
+ memset(&call->ackr_array,
+ RXRPC_ACK_TYPE_NACK,
+ sizeof(call->ackr_array));
}
/* clear this ACK */
- memset(&call->ackr,0,sizeof(call->ackr));
+ memset(&call->ackr, 0, sizeof(call->ackr));
out:
- if (!call->app_call_state) printk("___ STATE 0 ___\n");
+ if (!call->app_call_state)
+ printk("___ STATE 0 ___\n");
return ret;
} /* end __rxrpc_call_gen_normal_ACK() */
/*****************************************************************************/
/*
- * note the reception of a packet in the call's ACK records and generate an appropriate ACK packet
- * if necessary
- * - returns 0 if packet should be processed, 1 if packet should be ignored and -ve on an error
+ * note the reception of a packet in the call's ACK records and generate an
+ * appropriate ACK packet if necessary
+ * - returns 0 if packet should be processed, 1 if packet should be ignored
+ * and -ve on an error
*/
static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
struct rxrpc_header *hdr,
@@ -555,19 +577,20 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
int ret = 0, err;
u8 special_ACK, do_ACK, force;
- _enter("%p,%p { seq=%d tp=%d fl=%02x }",call,hdr,ntohl(hdr->seq),hdr->type,hdr->flags);
+ _enter("%p,%p { seq=%d tp=%d fl=%02x }",
+ call, hdr, ntohl(hdr->seq), hdr->type, hdr->flags);
seq = ntohl(hdr->seq);
offset = seq - call->ackr_win_bot;
do_ACK = RXRPC_ACK_DELAY;
special_ACK = 0;
- force = (seq==1);
+ force = (seq == 1);
if (call->ackr_high_seq < seq)
call->ackr_high_seq = seq;
/* deal with generation of obvious special ACKs first */
- if (ack && ack->reason==RXRPC_ACK_PING) {
+ if (ack && ack->reason == RXRPC_ACK_PING) {
special_ACK = RXRPC_ACK_PING_RESPONSE;
ret = 1;
goto gen_ACK;
@@ -594,9 +617,9 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
/* okay... it's a normal data packet inside the ACK window */
call->ackr_array[offset] = RXRPC_ACK_TYPE_ACK;
- if (offset<call->ackr_pend_cnt) {
+ if (offset < call->ackr_pend_cnt) {
}
- else if (offset>call->ackr_pend_cnt) {
+ else if (offset > call->ackr_pend_cnt) {
do_ACK = RXRPC_ACK_OUT_OF_SEQUENCE;
call->ackr_pend_cnt = offset;
goto gen_ACK;
@@ -616,8 +639,8 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
}
/* re-ACK packets previously received out-of-order */
- for (offset++; offset<RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
- if (call->ackr_array[offset]!=RXRPC_ACK_TYPE_ACK)
+ for (offset++; offset < RXRPC_CALL_ACK_WINDOW_SIZE; offset++)
+ if (call->ackr_array[offset] != RXRPC_ACK_TYPE_ACK)
break;
call->ackr_pend_cnt = offset;
@@ -629,55 +652,61 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
gen_ACK:
_debug("%05lu ACKs pend=%u norm=%s special=%s%s",
jiffies - call->cjif,
- call->ackr_pend_cnt,rxrpc_acks[do_ACK],rxrpc_acks[special_ACK],
+ call->ackr_pend_cnt,
+ rxrpc_acks[do_ACK],
+ rxrpc_acks[special_ACK],
force ? " immediate" :
- do_ACK==RXRPC_ACK_REQUESTED ? " merge-req" :
+ do_ACK == RXRPC_ACK_REQUESTED ? " merge-req" :
hdr->flags & RXRPC_LAST_PACKET ? " finalise" :
" defer"
);
/* send any pending normal ACKs if need be */
- if (call->ackr_pend_cnt>0) {
+ if (call->ackr_pend_cnt > 0) {
/* fill out the appropriate form */
- call->ackr.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
- call->ackr.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
- call->ackr.firstPacket = htonl(call->ackr_win_bot);
- call->ackr.previousPacket = call->ackr_prev_seq;
- call->ackr.serial = hdr->serial;
- call->ackr.nAcks = call->ackr_pend_cnt;
-
- if (do_ACK==RXRPC_ACK_REQUESTED)
+ call->ackr.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+ call->ackr.maxSkew = htons(min(call->ackr_high_seq - seq,
+ 65535U));
+ call->ackr.firstPacket = htonl(call->ackr_win_bot);
+ call->ackr.previousPacket = call->ackr_prev_seq;
+ call->ackr.serial = hdr->serial;
+ call->ackr.nAcks = call->ackr_pend_cnt;
+
+ if (do_ACK == RXRPC_ACK_REQUESTED)
call->ackr.reason = do_ACK;
/* generate the ACK immediately if necessary */
if (special_ACK || force) {
- err = __rxrpc_call_gen_normal_ACK(call,do_ACK==RXRPC_ACK_DELAY ? 0 : seq);
- if (err<0) {
+ err = __rxrpc_call_gen_normal_ACK(
+ call, do_ACK == RXRPC_ACK_DELAY ? 0 : seq);
+ if (err < 0) {
ret = err;
goto out;
}
}
}
- if (call->ackr.reason==RXRPC_ACK_REQUESTED)
+ if (call->ackr.reason == RXRPC_ACK_REQUESTED)
call->ackr_dfr_seq = seq;
- /* start the ACK timer if not running if there are any pending deferred ACKs */
- if (call->ackr_pend_cnt>0 &&
- call->ackr.reason!=RXRPC_ACK_REQUESTED &&
+ /* start the ACK timer if not running if there are any pending deferred
+ * ACKs */
+ if (call->ackr_pend_cnt > 0 &&
+ call->ackr.reason != RXRPC_ACK_REQUESTED &&
!timer_pending(&call->ackr_dfr_timo)
) {
unsigned long timo;
timo = rxrpc_call_dfr_ack_timeout + jiffies;
- _debug("START ACKR TIMER for cj=%lu",timo-call->cjif);
+ _debug("START ACKR TIMER for cj=%lu", timo-call->cjif);
spin_lock(&call->lock);
- mod_timer(&call->ackr_dfr_timo,timo);
+ mod_timer(&call->ackr_dfr_timo, timo);
spin_unlock(&call->lock);
}
- else if ((call->ackr_pend_cnt==0 || call->ackr.reason==RXRPC_ACK_REQUESTED) &&
+ else if ((call->ackr_pend_cnt == 0 ||
+ call->ackr.reason == RXRPC_ACK_REQUESTED) &&
timer_pending(&call->ackr_dfr_timo)
) {
/* stop timer if no pending ACKs */
@@ -689,21 +718,25 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
if (special_ACK) {
struct rxrpc_ackpacket ack;
struct iovec diov[2];
- u8 acks[1] = { RXRPC_ACK_TYPE_ACK };
+ uint8_t acks[1] = { RXRPC_ACK_TYPE_ACK };
/* fill out the appropriate form */
- ack.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
- ack.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
- ack.firstPacket = htonl(call->ackr_win_bot);
- ack.previousPacket = call->ackr_prev_seq;
- ack.serial = hdr->serial;
- ack.reason = special_ACK;
- ack.nAcks = 0;
- //ack.nAcks = special_ACK==RXRPC_ACK_OUT_OF_SEQUENCE ? 0 : hdr->seq ? 1 : 0;
-
- _proto("Rx Sending s-ACK { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
- ntohs(ack.maxSkew),ntohl(ack.firstPacket),ntohl(ack.previousPacket),
- ntohl(ack.serial),rxrpc_acks[ack.reason],ack.nAcks);
+ ack.bufferSpace = htons(RXRPC_CALL_ACK_WINDOW_SIZE);
+ ack.maxSkew = htons(min(call->ackr_high_seq - seq,65535U));
+ ack.firstPacket = htonl(call->ackr_win_bot);
+ ack.previousPacket = call->ackr_prev_seq;
+ ack.serial = hdr->serial;
+ ack.reason = special_ACK;
+ ack.nAcks = 0;
+
+ _proto("Rx Sending s-ACK"
+ " { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
+ ntohs(ack.maxSkew),
+ ntohl(ack.firstPacket),
+ ntohl(ack.previousPacket),
+ ntohl(ack.serial),
+ rxrpc_acks[ack.reason],
+ ack.nAcks);
diov[0].iov_len = sizeof(struct rxrpc_ackpacket);
diov[0].iov_base = &ack;
@@ -711,11 +744,11 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
diov[1].iov_base = acks;
/* build and send the message */
- err = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_ACK,
- hdr->seq ? 2 : 1,diov,
+ err = rxrpc_conn_newmsg(call->conn,call, RXRPC_PACKET_TYPE_ACK,
+ hdr->seq ? 2 : 1, diov,
GFP_KERNEL,
&msg);
- if (err<0) {
+ if (err < 0) {
ret = err;
goto out;
}
@@ -724,9 +757,9 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
msg->hdr.seq = htonl(seq);
msg->hdr.flags |= RXRPC_SLOW_START_OK;
- err = rxrpc_conn_sendmsg(call->conn,msg);
+ err = rxrpc_conn_sendmsg(call->conn, msg);
rxrpc_put_message(msg);
- if (err<0) {
+ if (err < 0) {
ret = err;
goto out;
}
@@ -737,7 +770,7 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
if (hdr->seq)
call->ackr_prev_seq = hdr->seq;
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_call_generate_ACK() */
@@ -748,7 +781,7 @@ static int rxrpc_call_generate_ACK(struct rxrpc_call *call,
*/
void rxrpc_call_do_stuff(struct rxrpc_call *call)
{
- _enter("%p{flags=%lx}",call,call->flags);
+ _enter("%p{flags=%lx}", call, call->flags);
/* handle packet reception */
if (call->flags & RXRPC_CALL_RCV_PKT) {
@@ -761,19 +794,19 @@ void rxrpc_call_do_stuff(struct rxrpc_call *call)
if (call->flags & RXRPC_CALL_ACKS_TIMO) {
_debug("- overdue ACK timeout");
call->flags &= ~RXRPC_CALL_ACKS_TIMO;
- rxrpc_call_resend(call,call->snd_seq_count);
+ rxrpc_call_resend(call, call->snd_seq_count);
}
/* handle lack of reception */
if (call->flags & RXRPC_CALL_RCV_TIMO) {
_debug("- reception timeout");
call->flags &= ~RXRPC_CALL_RCV_TIMO;
- rxrpc_call_abort(call,-EIO);
+ rxrpc_call_abort(call, -EIO);
}
/* handle deferred ACKs */
if (call->flags & RXRPC_CALL_ACKR_TIMO ||
- (call->ackr.nAcks>0 && call->ackr.reason==RXRPC_ACK_REQUESTED)
+ (call->ackr.nAcks > 0 && call->ackr.reason == RXRPC_ACK_REQUESTED)
) {
_debug("- deferred ACK timeout: cj=%05lu r=%s n=%u",
jiffies - call->cjif,
@@ -782,9 +815,10 @@ void rxrpc_call_do_stuff(struct rxrpc_call *call)
call->flags &= ~RXRPC_CALL_ACKR_TIMO;
- if (call->ackr.nAcks>0 && call->app_call_state!=RXRPC_CSTATE_ERROR) {
+ if (call->ackr.nAcks > 0 &&
+ call->app_call_state != RXRPC_CSTATE_ERROR) {
/* generate ACK */
- __rxrpc_call_gen_normal_ACK(call,call->ackr_dfr_seq);
+ __rxrpc_call_gen_normal_ACK(call, call->ackr_dfr_seq);
call->ackr_dfr_seq = 0;
}
}
@@ -807,10 +841,11 @@ static int __rxrpc_call_abort(struct rxrpc_call *call, int errno)
int ret;
u32 _error;
- _enter("%p{%08x},%p{%d},%d",conn,ntohl(conn->conn_id),call,ntohl(call->call_id),errno);
+ _enter("%p{%08x},%p{%d},%d",
+ conn, ntohl(conn->conn_id), call, ntohl(call->call_id), errno);
/* if this call is already aborted, then just wake up any waiters */
- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
+ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
spin_unlock(&call->lock);
call->app_error_func(call);
_leave(" = 0");
@@ -820,12 +855,12 @@ static int __rxrpc_call_abort(struct rxrpc_call *call, int errno)
rxrpc_get_call(call);
/* change the state _with_ the lock still held */
- call->app_call_state = RXRPC_CSTATE_ERROR;
- call->app_err_state = RXRPC_ESTATE_LOCAL_ABORT;
- call->app_errno = errno;
- call->app_mark = RXRPC_APP_MARK_EOF;
- call->app_read_buf = NULL;
- call->app_async_read = 0;
+ call->app_call_state = RXRPC_CSTATE_ERROR;
+ call->app_err_state = RXRPC_ESTATE_LOCAL_ABORT;
+ call->app_errno = errno;
+ call->app_mark = RXRPC_APP_MARK_EOF;
+ call->app_read_buf = NULL;
+ call->app_async_read = 0;
_state(call);
@@ -840,22 +875,25 @@ static int __rxrpc_call_abort(struct rxrpc_call *call, int errno)
del_timer_sync(&call->ackr_dfr_timo);
if (rxrpc_call_is_ack_pending(call))
- __rxrpc_call_gen_normal_ACK(call,0);
+ __rxrpc_call_gen_normal_ACK(call, 0);
- /* send the abort packet only if we actually traded some other packets */
+ /* send the abort packet only if we actually traded some other
+ * packets */
ret = 0;
if (call->pkt_snd_count || call->pkt_rcv_count) {
/* actually send the abort */
- _proto("Rx Sending Call ABORT { data=%d }",call->app_abort_code);
+ _proto("Rx Sending Call ABORT { data=%d }",
+ call->app_abort_code);
_error = htonl(call->app_abort_code);
diov[0].iov_len = sizeof(_error);
diov[0].iov_base = &_error;
- ret = rxrpc_conn_newmsg(conn,call,RXRPC_PACKET_TYPE_ABORT,1,diov,GFP_KERNEL,&msg);
- if (ret==0) {
- ret = rxrpc_conn_sendmsg(conn,msg);
+ ret = rxrpc_conn_newmsg(conn, call, RXRPC_PACKET_TYPE_ABORT,
+ 1, diov, GFP_KERNEL, &msg);
+ if (ret == 0) {
+ ret = rxrpc_conn_sendmsg(conn, msg);
rxrpc_put_message(msg);
}
}
@@ -865,8 +903,7 @@ static int __rxrpc_call_abort(struct rxrpc_call *call, int errno)
rxrpc_put_call(call);
- _leave(" = %d",ret);
-
+ _leave(" = %d", ret);
return ret;
} /* end __rxrpc_call_abort() */
@@ -879,7 +916,7 @@ int rxrpc_call_abort(struct rxrpc_call *call, int error)
{
spin_lock(&call->lock);
- return __rxrpc_call_abort(call,error);
+ return __rxrpc_call_abort(call, error);
} /* end rxrpc_call_abort() */
@@ -891,11 +928,12 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
{
struct rxrpc_message *msg;
struct list_head *_p;
- u32 data32;
+ uint32_t data32;
- _enter("%p",call);
+ _enter("%p", call);
- rxrpc_get_call(call); /* must not go away too soon if aborted by app-layer */
+ rxrpc_get_call(call); /* must not go away too soon if aborted by
+ * app-layer */
while (!list_empty(&call->rcv_receiveq)) {
/* try to get next packet */
@@ -907,9 +945,10 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
}
spin_unlock(&call->lock);
- if (!_p) break;
+ if (!_p)
+ break;
- msg = list_entry(_p,struct rxrpc_message,link);
+ msg = list_entry(_p, struct rxrpc_message, link);
_proto("Rx %05lu Received %s packet (%%%u,#%u,%c%c%c%c%c)",
jiffies - call->cjif,
@@ -927,9 +966,10 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
/* deal with data packets */
case RXRPC_PACKET_TYPE_DATA:
/* ACK the packet if necessary */
- switch (rxrpc_call_generate_ACK(call,&msg->hdr,NULL)) {
+ switch (rxrpc_call_generate_ACK(call, &msg->hdr,
+ NULL)) {
case 0: /* useful packet */
- rxrpc_call_receive_data_packet(call,msg);
+ rxrpc_call_receive_data_packet(call, msg);
break;
case 1: /* duplicate or out-of-window packet */
break;
@@ -941,29 +981,30 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
/* deal with ACK packets */
case RXRPC_PACKET_TYPE_ACK:
- rxrpc_call_receive_ack_packet(call,msg);
+ rxrpc_call_receive_ack_packet(call, msg);
break;
/* deal with abort packets */
case RXRPC_PACKET_TYPE_ABORT:
data32 = 0;
- if (skb_copy_bits(msg->pkt,msg->offset,&data32,sizeof(data32))<0) {
+ if (skb_copy_bits(msg->pkt, msg->offset,
+ &data32, sizeof(data32)) < 0) {
printk("Rx Received short ABORT packet\n");
}
else {
data32 = ntohl(data32);
}
- _proto("Rx Received Call ABORT { data=%d }",data32);
+ _proto("Rx Received Call ABORT { data=%d }", data32);
spin_lock(&call->lock);
- call->app_call_state = RXRPC_CSTATE_ERROR;
- call->app_err_state = RXRPC_ESTATE_PEER_ABORT;
- call->app_abort_code = data32;
- call->app_errno = -ECONNABORTED;
- call->app_mark = RXRPC_APP_MARK_EOF;
- call->app_read_buf = NULL;
- call->app_async_read = 0;
+ call->app_call_state = RXRPC_CSTATE_ERROR;
+ call->app_err_state = RXRPC_ESTATE_PEER_ABORT;
+ call->app_abort_code = data32;
+ call->app_errno = -ECONNABORTED;
+ call->app_mark = RXRPC_APP_MARK_EOF;
+ call->app_read_buf = NULL;
+ call->app_async_read = 0;
/* ask the app to translate the error code */
call->app_aemap_func(call);
@@ -974,7 +1015,8 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
default:
/* deal with other packet types */
- _proto("Rx Unsupported packet type %u (#%u)",msg->hdr.type,msg->seq);
+ _proto("Rx Unsupported packet type %u (#%u)",
+ msg->hdr.type, msg->seq);
break;
}
@@ -990,14 +1032,18 @@ static void rxrpc_call_receive_packet(struct rxrpc_call *call)
/*
* process next data packet
* - as the next data packet arrives:
- * - it is queued on app_readyq _if_ it is the next one expected (app_ready_seq+1)
+ * - it is queued on app_readyq _if_ it is the next one expected
+ * (app_ready_seq+1)
* - it is queued on app_unreadyq _if_ it is not the next one expected
- * - if a packet placed on app_readyq completely fills a hole leading up to the first packet
- * on app_unreadyq, then packets now in sequence are tranferred to app_readyq
- * - the application layer can only see packets on app_readyq (app_ready_qty bytes)
+ * - if a packet placed on app_readyq completely fills a hole leading up to
+ * the first packet on app_unreadyq, then packets now in sequence are
+ * tranferred to app_readyq
+ * - the application layer can only see packets on app_readyq
+ * (app_ready_qty bytes)
* - the application layer is prodded every time a new packet arrives
*/
-static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
+static void rxrpc_call_receive_data_packet(struct rxrpc_call *call,
+ struct rxrpc_message *msg)
{
const struct rxrpc_operation *optbl, *op;
struct rxrpc_message *pmsg;
@@ -1005,22 +1051,23 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
int ret, lo, hi, rmtimo;
u32 opid;
- _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
+ _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
rxrpc_get_message(msg);
- /* add to the unready queue if we'd have to create a hole in the ready queue otherwise */
- if (msg->seq != call->app_ready_seq+1) {
- _debug("Call add packet %d to unreadyq",msg->seq);
+ /* add to the unready queue if we'd have to create a hole in the ready
+ * queue otherwise */
+ if (msg->seq != call->app_ready_seq + 1) {
+ _debug("Call add packet %d to unreadyq", msg->seq);
/* insert in seq order */
list_for_each(_p,&call->app_unreadyq) {
- pmsg = list_entry(_p,struct rxrpc_message,link);
- if (pmsg->seq>msg->seq)
+ pmsg = list_entry(_p, struct rxrpc_message, link);
+ if (pmsg->seq > msg->seq)
break;
}
- list_add_tail(&msg->link,_p);
+ list_add_tail(&msg->link, _p);
_leave(" [unreadyq]");
return;
@@ -1028,33 +1075,35 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
/* next in sequence - simply append into the call's ready queue */
_debug("Call add packet %d to readyq (+%Zd => %Zd bytes)",
- msg->seq,msg->dsize,call->app_ready_qty);
+ msg->seq, msg->dsize, call->app_ready_qty);
spin_lock(&call->lock);
call->app_ready_seq = msg->seq;
call->app_ready_qty += msg->dsize;
- list_add_tail(&msg->link,&call->app_readyq);
+ list_add_tail(&msg->link, &call->app_readyq);
/* move unready packets to the readyq if we got rid of a hole */
while (!list_empty(&call->app_unreadyq)) {
- pmsg = list_entry(call->app_unreadyq.next,struct rxrpc_message,link);
+ pmsg = list_entry(call->app_unreadyq.next,
+ struct rxrpc_message, link);
- if (pmsg->seq != call->app_ready_seq+1)
+ if (pmsg->seq != call->app_ready_seq + 1)
break;
/* next in sequence - just move list-to-list */
_debug("Call transfer packet %d to readyq (+%Zd => %Zd bytes)",
- pmsg->seq,pmsg->dsize,call->app_ready_qty);
+ pmsg->seq, pmsg->dsize, call->app_ready_qty);
call->app_ready_seq = pmsg->seq;
call->app_ready_qty += pmsg->dsize;
list_del_init(&pmsg->link);
- list_add_tail(&pmsg->link,&call->app_readyq);
+ list_add_tail(&pmsg->link, &call->app_readyq);
}
/* see if we've got the last packet yet */
if (!list_empty(&call->app_readyq)) {
- pmsg = list_entry(call->app_readyq.prev,struct rxrpc_message,link);
+ pmsg = list_entry(call->app_readyq.prev,
+ struct rxrpc_message, link);
if (pmsg->hdr.flags & RXRPC_LAST_PACKET) {
call->app_last_rcv = 1;
_debug("Last packet on readyq");
@@ -1068,25 +1117,27 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
_leave(" [error]");
return;
- /* extract the operation ID from an incoming call if that's not yet been done */
+ /* extract the operation ID from an incoming call if that's not
+ * yet been done */
case RXRPC_CSTATE_SRVR_RCV_OPID:
spin_unlock(&call->lock);
/* handle as yet insufficient data for the operation ID */
- if (call->app_ready_qty<4) {
+ if (call->app_ready_qty < 4) {
if (call->app_last_rcv)
- rxrpc_call_abort(call,-EINVAL); /* trouble - last packet seen */
+ /* trouble - last packet seen */
+ rxrpc_call_abort(call, -EINVAL);
_leave("");
return;
}
/* pull the operation ID out of the buffer */
- ret = rxrpc_call_read_data(call,&opid,sizeof(opid),0);
- if (ret<0) {
- printk("Unexpected error from read-data: %d\n",ret);
- if (call->app_call_state!=RXRPC_CSTATE_ERROR)
- rxrpc_call_abort(call,ret);
+ ret = rxrpc_call_read_data(call, &opid, sizeof(opid), 0);
+ if (ret < 0) {
+ printk("Unexpected error from read-data: %d\n", ret);
+ if (call->app_call_state != RXRPC_CSTATE_ERROR)
+ rxrpc_call_abort(call, ret);
_leave("");
return;
}
@@ -1097,38 +1148,42 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
lo = 0;
hi = call->conn->service->ops_end - optbl;
- while (lo<hi) {
- int mid = (hi+lo) / 2;
+ while (lo < hi) {
+ int mid = (hi + lo) / 2;
op = &optbl[mid];
- if (call->app_opcode==op->id)
+ if (call->app_opcode == op->id)
goto found_op;
- if (call->app_opcode>op->id)
- lo = mid+1;
+ if (call->app_opcode > op->id)
+ lo = mid + 1;
else
hi = mid;
}
/* search failed */
kproto("Rx Client requested operation %d from %s service",
- call->app_opcode,call->conn->service->name);
- rxrpc_call_abort(call,-EINVAL);
+ call->app_opcode, call->conn->service->name);
+ rxrpc_call_abort(call, -EINVAL);
_leave(" [inval]");
return;
found_op:
_proto("Rx Client requested operation %s from %s service",
- op->name,call->conn->service->name);
+ op->name, call->conn->service->name);
- /* we're now waiting for the argument block (unless the call was aborted) */
+ /* we're now waiting for the argument block (unless the call
+ * was aborted) */
spin_lock(&call->lock);
- if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_OPID ||
- call->app_call_state==RXRPC_CSTATE_SRVR_SND_REPLY) {
+ if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_OPID ||
+ call->app_call_state == RXRPC_CSTATE_SRVR_SND_REPLY) {
if (!call->app_last_rcv)
- call->app_call_state = RXRPC_CSTATE_SRVR_RCV_ARGS;
- else if (call->app_ready_qty>0)
- call->app_call_state = RXRPC_CSTATE_SRVR_GOT_ARGS;
+ call->app_call_state =
+ RXRPC_CSTATE_SRVR_RCV_ARGS;
+ else if (call->app_ready_qty > 0)
+ call->app_call_state =
+ RXRPC_CSTATE_SRVR_GOT_ARGS;
else
- call->app_call_state = RXRPC_CSTATE_SRVR_SND_REPLY;
+ call->app_call_state =
+ RXRPC_CSTATE_SRVR_SND_REPLY;
call->app_mark = op->asize;
call->app_user = op->user;
}
@@ -1166,20 +1221,21 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
default:
/* deal with data reception in an unexpected state */
- printk("Unexpected state [[[ %u ]]]\n",call->app_call_state);
- __rxrpc_call_abort(call,-EBADMSG);
+ printk("Unexpected state [[[ %u ]]]\n", call->app_call_state);
+ __rxrpc_call_abort(call, -EBADMSG);
_leave("");
return;
}
- if (call->app_call_state==RXRPC_CSTATE_CLNT_RCV_REPLY && call->app_last_rcv)
+ if (call->app_call_state == RXRPC_CSTATE_CLNT_RCV_REPLY &&
+ call->app_last_rcv)
BUG();
/* otherwise just invoke the data function whenever we can satisfy its desire for more
* data
*/
_proto("Rx Received Op Data: st=%u qty=%Zu mk=%Zu%s",
- call->app_call_state,call->app_ready_qty,call->app_mark,
+ call->app_call_state, call->app_ready_qty, call->app_mark,
call->app_last_rcv ? " last-rcvd" : "");
spin_lock(&call->lock);
@@ -1196,8 +1252,8 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
case -ECONNABORTED:
spin_unlock(&call->lock);
break;
- default:
- __rxrpc_call_abort(call,ret);
+ default:
+ __rxrpc_call_abort(call, ret);
break;
}
@@ -1211,17 +1267,18 @@ static void rxrpc_call_receive_data_packet(struct rxrpc_call *call, struct rxrpc
/*
* received an ACK packet
*/
-static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_message *msg)
+static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call,
+ struct rxrpc_message *msg)
{
struct rxrpc_ackpacket ack;
rxrpc_serial_t serial;
rxrpc_seq_t seq;
int ret;
- _enter("%p{%u},%p{%u}",call,ntohl(call->call_id),msg,msg->seq);
+ _enter("%p{%u},%p{%u}", call, ntohl(call->call_id), msg, msg->seq);
/* extract the basic ACK record */
- if (skb_copy_bits(msg->pkt,msg->offset,&ack,sizeof(ack))<0) {
+ if (skb_copy_bits(msg->pkt, msg->offset, &ack, sizeof(ack)) < 0) {
printk("Rx Received short ACK packet\n");
return;
}
@@ -1241,10 +1298,14 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
call->ackr.nAcks
);
- /* check the other side isn't ACK'ing a sequence number I haven't sent yet */
- if (ack.nAcks>0 && (seq > call->snd_seq_count || seq+ack.nAcks-1 > call->snd_seq_count)) {
- printk("Received ACK (#%u-#%u) for unsent packet\n",seq,seq+ack.nAcks-1);
- rxrpc_call_abort(call,-EINVAL);
+ /* check the other side isn't ACK'ing a sequence number I haven't sent
+ * yet */
+ if (ack.nAcks > 0 &&
+ (seq > call->snd_seq_count ||
+ seq + ack.nAcks - 1 > call->snd_seq_count)) {
+ printk("Received ACK (#%u-#%u) for unsent packet\n",
+ seq, seq + ack.nAcks - 1);
+ rxrpc_call_abort(call, -EINVAL);
_leave("");
return;
}
@@ -1255,7 +1316,7 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
/* find the prompting packet */
spin_lock(&call->lock);
- if (call->snd_ping && call->snd_ping->hdr.serial==serial) {
+ if (call->snd_ping && call->snd_ping->hdr.serial == serial) {
/* it was a ping packet */
rttmsg = call->snd_ping;
call->snd_ping = NULL;
@@ -1263,22 +1324,28 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
if (rttmsg) {
rttmsg->rttdone = 1;
- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
+ rxrpc_peer_calculate_rtt(call->conn->peer,
+ rttmsg, msg);
rxrpc_put_message(rttmsg);
}
}
else {
struct list_head *_p;
- /* it ought to be a data packet - look in the pending ACK list */
- list_for_each(_p,&call->acks_pendq) {
- rttmsg = list_entry(_p,struct rxrpc_message,link);
- if (rttmsg->hdr.serial==serial) {
+ /* it ought to be a data packet - look in the pending
+ * ACK list */
+ list_for_each(_p, &call->acks_pendq) {
+ rttmsg = list_entry(_p, struct rxrpc_message,
+ link);
+ if (rttmsg->hdr.serial == serial) {
if (rttmsg->rttdone)
- break; /* never do RTT twice without resending */
+ /* never do RTT twice without
+ * resending */
+ break;
rttmsg->rttdone = 1;
- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
+ rxrpc_peer_calculate_rtt(
+ call->conn->peer, rttmsg, msg);
break;
}
}
@@ -1287,24 +1354,25 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
}
switch (ack.reason) {
- /* deal with negative/positive acknowledgement of data packets */
+ /* deal with negative/positive acknowledgement of data
+ * packets */
case RXRPC_ACK_REQUESTED:
case RXRPC_ACK_DELAY:
case RXRPC_ACK_IDLE:
- rxrpc_call_definitively_ACK(call,seq-1);
+ rxrpc_call_definitively_ACK(call, seq - 1);
case RXRPC_ACK_DUPLICATE:
case RXRPC_ACK_OUT_OF_SEQUENCE:
case RXRPC_ACK_EXCEEDS_WINDOW:
call->snd_resend_cnt = 0;
- ret = rxrpc_call_record_ACK(call,msg,seq,ack.nAcks);
- if (ret<0)
- rxrpc_call_abort(call,ret);
+ ret = rxrpc_call_record_ACK(call, msg, seq, ack.nAcks);
+ if (ret < 0)
+ rxrpc_call_abort(call, ret);
break;
/* respond to ping packets immediately */
case RXRPC_ACK_PING:
- rxrpc_call_generate_ACK(call,&msg->hdr,&ack);
+ rxrpc_call_generate_ACK(call, &msg->hdr, &ack);
break;
/* only record RTT on ping response packets */
@@ -1312,10 +1380,12 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
if (call->snd_ping) {
struct rxrpc_message *rttmsg;
- /* only do RTT stuff if the response matches the retained ping */
+ /* only do RTT stuff if the response matches the
+ * retained ping */
rttmsg = NULL;
spin_lock(&call->lock);
- if (call->snd_ping && call->snd_ping->hdr.serial==ack.serial) {
+ if (call->snd_ping &&
+ call->snd_ping->hdr.serial == ack.serial) {
rttmsg = call->snd_ping;
call->snd_ping = NULL;
}
@@ -1323,14 +1393,15 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
if (rttmsg) {
rttmsg->rttdone = 1;
- rxrpc_peer_calculate_rtt(call->conn->peer,rttmsg,msg);
+ rxrpc_peer_calculate_rtt(call->conn->peer,
+ rttmsg, msg);
rxrpc_put_message(rttmsg);
}
}
break;
default:
- printk("Unsupported ACK reason %u\n",ack.reason);
+ printk("Unsupported ACK reason %u\n", ack.reason);
break;
}
@@ -1339,38 +1410,44 @@ static void rxrpc_call_receive_ack_packet(struct rxrpc_call *call, struct rxrpc_
/*****************************************************************************/
/*
- * record definitive ACKs for all messages up to and including the one with the 'highest' seq
+ * record definitive ACKs for all messages up to and including the one with the
+ * 'highest' seq
*/
-static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t highest)
+static void rxrpc_call_definitively_ACK(struct rxrpc_call *call,
+ rxrpc_seq_t highest)
{
struct rxrpc_message *msg;
int now_complete;
- _enter("%p{ads=%u},%u",call,call->acks_dftv_seq,highest);
+ _enter("%p{ads=%u},%u", call, call->acks_dftv_seq, highest);
- while (call->acks_dftv_seq<highest) {
+ while (call->acks_dftv_seq < highest) {
call->acks_dftv_seq++;
- _proto("Definitive ACK on packet #%u",call->acks_dftv_seq);
+ _proto("Definitive ACK on packet #%u", call->acks_dftv_seq);
- /* discard those at front of queue until message with highest ACK is found */
+ /* discard those at front of queue until message with highest
+ * ACK is found */
spin_lock(&call->lock);
msg = NULL;
if (!list_empty(&call->acks_pendq)) {
- msg = list_entry(call->acks_pendq.next,struct rxrpc_message,link);
+ msg = list_entry(call->acks_pendq.next,
+ struct rxrpc_message, link);
list_del_init(&msg->link); /* dequeue */
- if (msg->state==RXRPC_MSG_SENT)
+ if (msg->state == RXRPC_MSG_SENT)
call->acks_pend_cnt--;
}
spin_unlock(&call->lock);
/* insanity check */
if (!msg)
- panic("%s(): acks_pendq unexpectedly empty\n",__FUNCTION__);
+ panic("%s(): acks_pendq unexpectedly empty\n",
+ __FUNCTION__);
- if (msg->seq!=call->acks_dftv_seq)
- panic("%s(): Packet #%u expected at front of acks_pendq (#%u found)\n",
- __FUNCTION__,call->acks_dftv_seq,msg->seq);
+ if (msg->seq != call->acks_dftv_seq)
+ panic("%s(): Packet #%u expected at front of acks_pendq"
+ " (#%u found)\n",
+ __FUNCTION__, call->acks_dftv_seq, msg->seq);
/* discard the message */
msg->state = RXRPC_MSG_DONE;
@@ -1380,8 +1457,8 @@ static void rxrpc_call_definitively_ACK(struct rxrpc_call *call, rxrpc_seq_t hig
/* if all sent packets are definitively ACK'd then prod any sleepers just in case */
now_complete = 0;
spin_lock(&call->lock);
- if (call->acks_dftv_seq==call->snd_seq_count) {
- if (call->app_call_state!=RXRPC_CSTATE_COMPLETE) {
+ if (call->acks_dftv_seq == call->snd_seq_count) {
+ if (call->app_call_state != RXRPC_CSTATE_COMPLETE) {
call->app_call_state = RXRPC_CSTATE_COMPLETE;
_state(call);
now_complete = 1;
@@ -1417,13 +1494,15 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
u8 acks[16];
_enter("%p{apc=%u ads=%u},%p,%u,%Zu",
- call,call->acks_pend_cnt,call->acks_dftv_seq,msg,seq,count);
+ call, call->acks_pend_cnt, call->acks_dftv_seq,
+ msg, seq, count);
- /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order ACKs) */
- if (seq<=call->acks_dftv_seq) {
+ /* handle re-ACK'ing of definitively ACK'd packets (may be out-of-order
+ * ACKs) */
+ if (seq <= call->acks_dftv_seq) {
unsigned delta = call->acks_dftv_seq - seq;
- if (count<=delta) {
+ if (count <= delta) {
_leave(" = 0 [all definitively ACK'd]");
return 0;
}
@@ -1435,14 +1514,14 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
highest = seq + count - 1;
resend = 0;
- while (count>0) {
+ while (count > 0) {
/* extract up to 16 ACK slots at a time */
- chunk = min(count,sizeof(acks));
+ chunk = min(count, sizeof(acks));
count -= chunk;
- memset(acks,2,sizeof(acks));
+ memset(acks, 2, sizeof(acks));
- if (skb_copy_bits(msg->pkt,msg->offset,&acks,chunk)<0) {
+ if (skb_copy_bits(msg->pkt, msg->offset, &acks, chunk) < 0) {
printk("Rx Received short ACK packet\n");
_leave(" = -EINVAL");
return -EINVAL;
@@ -1450,7 +1529,7 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
msg->offset += chunk;
/* check that the ACK set is valid */
- for (ix=0; ix<chunk; ix++) {
+ for (ix = 0; ix < chunk; ix++) {
switch (acks[ix]) {
case RXRPC_ACK_TYPE_ACK:
break;
@@ -1458,14 +1537,16 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
resend = 1;
break;
default:
- printk("Rx Received unsupported ACK state %u\n",acks[ix]);
+ printk("Rx Received unsupported ACK state"
+ " %u\n", acks[ix]);
_leave(" = -EINVAL");
return -EINVAL;
}
}
- _proto("Rx ACK of packets #%u-#%u [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
- seq,(unsigned)(seq+chunk-1),
+ _proto("Rx ACK of packets #%u-#%u "
+ "[%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c] (pend=%u)",
+ seq, (unsigned) (seq + chunk - 1),
_acktype[acks[0x0]],
_acktype[acks[0x1]],
_acktype[acks[0x2]],
@@ -1485,53 +1566,60 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
call->acks_pend_cnt
);
- /* mark the packets in the ACK queue as being provisionally ACK'd */
+ /* mark the packets in the ACK queue as being provisionally
+ * ACK'd */
ix = 0;
spin_lock(&call->lock);
/* find the first packet ACK'd/NAK'd here */
- list_for_each(_p,&call->acks_pendq) {
- dmsg = list_entry(_p,struct rxrpc_message,link);
- if (dmsg->seq==seq)
+ list_for_each(_p, &call->acks_pendq) {
+ dmsg = list_entry(_p, struct rxrpc_message, link);
+ if (dmsg->seq == seq)
goto found_first;
- _debug("- %u: skipping #%u",ix,dmsg->seq);
+ _debug("- %u: skipping #%u", ix, dmsg->seq);
}
goto bad_queue;
found_first:
do {
_debug("- %u: processing #%u (%c) apc=%u",
- ix,dmsg->seq,_acktype[acks[ix]],call->acks_pend_cnt);
+ ix, dmsg->seq, _acktype[acks[ix]],
+ call->acks_pend_cnt);
- if (acks[ix]==RXRPC_ACK_TYPE_ACK) {
- if (dmsg->state==RXRPC_MSG_SENT) call->acks_pend_cnt--;
+ if (acks[ix] == RXRPC_ACK_TYPE_ACK) {
+ if (dmsg->state == RXRPC_MSG_SENT)
+ call->acks_pend_cnt--;
dmsg->state = RXRPC_MSG_ACKED;
}
else {
- if (dmsg->state==RXRPC_MSG_ACKED) call->acks_pend_cnt++;
+ if (dmsg->state == RXRPC_MSG_ACKED)
+ call->acks_pend_cnt++;
dmsg->state = RXRPC_MSG_SENT;
}
ix++;
seq++;
_p = dmsg->link.next;
- dmsg = list_entry(_p,struct rxrpc_message,link);
- } while(ix<chunk && _p!=&call->acks_pendq && dmsg->seq==seq);
+ dmsg = list_entry(_p, struct rxrpc_message, link);
+ } while(ix < chunk &&
+ _p != &call->acks_pendq &&
+ dmsg->seq == seq);
- if (ix<chunk)
+ if (ix < chunk)
goto bad_queue;
spin_unlock(&call->lock);
}
if (resend)
- rxrpc_call_resend(call,highest);
+ rxrpc_call_resend(call, highest);
- /* if all packets are provisionally ACK'd, then wake up anyone who's waiting for that */
+ /* if all packets are provisionally ACK'd, then wake up anyone who's
+ * waiting for that */
now_complete = 0;
spin_lock(&call->lock);
- if (call->acks_pend_cnt==0) {
- if (call->app_call_state==RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
+ if (call->acks_pend_cnt == 0) {
+ if (call->app_call_state == RXRPC_CSTATE_SRVR_RCV_FINAL_ACK) {
call->app_call_state = RXRPC_CSTATE_COMPLETE;
_state(call);
}
@@ -1547,19 +1635,21 @@ static int rxrpc_call_record_ACK(struct rxrpc_call *call,
call->app_attn_func(call);
}
- _leave(" = 0 (apc=%u)",call->acks_pend_cnt);
+ _leave(" = 0 (apc=%u)", call->acks_pend_cnt);
return 0;
bad_queue:
- panic("%s(): acks_pendq in bad state (packet #%u absent)\n",__FUNCTION__,seq);
+ panic("%s(): acks_pendq in bad state (packet #%u absent)\n",
+ __FUNCTION__, seq);
} /* end rxrpc_call_record_ACK() */
/*****************************************************************************/
/*
* transfer data from the ready packet queue to the asynchronous read buffer
- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
- * a lock to modify or access them, only to modify the queue pointers
+ * - since this func is the only one going to look at packets queued on
+ * app_readyq, we don't need a lock to modify or access them, only to modify
+ * the queue pointers
* - called with call->lock held
* - the buffer must be in kernel space
* - returns:
@@ -1575,16 +1665,20 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
int ret;
_enter("%p{as=%d buf=%p qty=%Zu/%Zu}",
- call,call->app_async_read,call->app_read_buf,call->app_ready_qty,call->app_mark);
+ call,
+ call->app_async_read, call->app_read_buf,
+ call->app_ready_qty, call->app_mark);
/* check the state */
switch (call->app_call_state) {
case RXRPC_CSTATE_SRVR_RCV_ARGS:
case RXRPC_CSTATE_CLNT_RCV_REPLY:
if (call->app_last_rcv) {
- printk("%s(%p,%p,%Zd): Inconsistent call state (%s, last pkt)",
- __FUNCTION__,call,call->app_read_buf,call->app_mark,
- rxrpc_call_states[call->app_call_state]);
+ printk("%s(%p,%p,%Zd):"
+ " Inconsistent call state (%s, last pkt)",
+ __FUNCTION__,
+ call, call->app_read_buf, call->app_mark,
+ rxrpc_call_states[call->app_call_state]);
BUG();
}
break;
@@ -1596,9 +1690,11 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
case RXRPC_CSTATE_SRVR_SND_REPLY:
if (!call->app_last_rcv) {
- printk("%s(%p,%p,%Zd): Inconsistent call state (%s, not last pkt)",
- __FUNCTION__,call,call->app_read_buf,call->app_mark,
- rxrpc_call_states[call->app_call_state]);
+ printk("%s(%p,%p,%Zd):"
+ " Inconsistent call state (%s, not last pkt)",
+ __FUNCTION__,
+ call, call->app_read_buf, call->app_mark,
+ rxrpc_call_states[call->app_call_state]);
BUG();
}
_debug("Trying to read data from call in SND_REPLY state");
@@ -1609,13 +1705,14 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
return -ECONNABORTED;
default:
- printk("reading in unexpected state [[[ %u ]]]\n",call->app_call_state);
+ printk("reading in unexpected state [[[ %u ]]]\n",
+ call->app_call_state);
BUG();
}
/* handle the case of not having an async buffer */
if (!call->app_async_read) {
- if (call->app_mark==RXRPC_APP_MARK_EOF) {
+ if (call->app_mark == RXRPC_APP_MARK_EOF) {
ret = call->app_last_rcv ? 0 : -EAGAIN;
}
else {
@@ -1628,28 +1725,33 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
}
}
- _leave(" = %d [no buf]",ret);
+ _leave(" = %d [no buf]", ret);
return 0;
}
- while (!list_empty(&call->app_readyq) && call->app_mark>0) {
- msg = list_entry(call->app_readyq.next,struct rxrpc_message,link);
+ while (!list_empty(&call->app_readyq) && call->app_mark > 0) {
+ msg = list_entry(call->app_readyq.next,
+ struct rxrpc_message, link);
/* drag as much data as we need out of this packet */
- qty = min(call->app_mark,msg->dsize);
+ qty = min(call->app_mark, msg->dsize);
- _debug("reading %Zu from skb=%p off=%lu",qty,msg->pkt,msg->offset);
+ _debug("reading %Zu from skb=%p off=%lu",
+ qty, msg->pkt, msg->offset);
if (call->app_read_buf)
- if (skb_copy_bits(msg->pkt,msg->offset,call->app_read_buf,qty)<0)
- panic("%s: Failed to copy data from packet: (%p,%p,%Zd)",
- __FUNCTION__,call,call->app_read_buf,qty);
+ if (skb_copy_bits(msg->pkt, msg->offset,
+ call->app_read_buf, qty) < 0)
+ panic("%s: Failed to copy data from packet:"
+ " (%p,%p,%Zd)",
+ __FUNCTION__,
+ call, call->app_read_buf, qty);
/* if that packet is now empty, discard it */
call->app_ready_qty -= qty;
msg->dsize -= qty;
- if (msg->dsize==0) {
+ if (msg->dsize == 0) {
list_del_init(&msg->link);
rxrpc_put_message(msg);
}
@@ -1658,10 +1760,11 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
}
call->app_mark -= qty;
- if (call->app_read_buf) call->app_read_buf += qty;
+ if (call->app_read_buf)
+ call->app_read_buf += qty;
}
- if (call->app_mark==0) {
+ if (call->app_mark == 0) {
call->app_async_read = 0;
call->app_mark = RXRPC_APP_MARK_EOF;
call->app_read_buf = NULL;
@@ -1695,7 +1798,8 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
}
if (call->app_last_rcv) {
- _debug("Insufficient data (%Zu/%Zu)",call->app_ready_qty,call->app_mark);
+ _debug("Insufficient data (%Zu/%Zu)",
+ call->app_ready_qty, call->app_mark);
call->app_async_read = 0;
call->app_mark = RXRPC_APP_MARK_EOF;
call->app_read_buf = NULL;
@@ -1710,22 +1814,26 @@ static int __rxrpc_call_read_data(struct rxrpc_call *call)
/*****************************************************************************/
/*
- * attempt to read the specified amount of data from the call's ready queue into the buffer
- * provided
- * - since this func is the only one going to look at packets queued on app_readyq, we don't need
- * a lock to modify or access them, only to modify the queue pointers
+ * attempt to read the specified amount of data from the call's ready queue
+ * into the buffer provided
+ * - since this func is the only one going to look at packets queued on
+ * app_readyq, we don't need a lock to modify or access them, only to modify
+ * the queue pointers
* - if the buffer pointer is NULL, then data is merely drained, not copied
- * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is enough data or an
- * error will be generated
- * - note that the caller must have added the calling task to the call's wait queue beforehand
- * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this function doesn't read
- * all available data
+ * - if flags&RXRPC_CALL_READ_BLOCK, then the function will wait until there is
+ * enough data or an error will be generated
+ * - note that the caller must have added the calling task to the call's wait
+ * queue beforehand
+ * - if flags&RXRPC_CALL_READ_ALL, then an error will be generated if this
+ * function doesn't read all available data
*/
-int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int flags)
+int rxrpc_call_read_data(struct rxrpc_call *call,
+ void *buffer, size_t size, int flags)
{
int ret;
- _enter("%p{arq=%Zu},%p,%Zd,%x",call,call->app_ready_qty,buffer,size,flags);
+ _enter("%p{arq=%Zu},%p,%Zd,%x",
+ call, call->app_ready_qty, buffer, size, flags);
spin_lock(&call->lock);
@@ -1744,9 +1852,10 @@ int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int
ret = __rxrpc_call_read_data(call);
switch (ret) {
case 0:
- if (flags&RXRPC_CALL_READ_ALL && (!call->app_last_rcv || call->app_ready_qty>0)) {
+ if (flags & RXRPC_CALL_READ_ALL &&
+ (!call->app_last_rcv || call->app_ready_qty > 0)) {
_leave(" = -EBADMSG");
- __rxrpc_call_abort(call,-EBADMSG);
+ __rxrpc_call_abort(call, -EBADMSG);
return -EBADMSG;
}
@@ -1757,18 +1866,18 @@ int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int
case -ECONNABORTED:
spin_unlock(&call->lock);
- _leave(" = %d [aborted]",ret);
+ _leave(" = %d [aborted]", ret);
return ret;
- default:
- __rxrpc_call_abort(call,ret);
- _leave(" = %d",ret);
+ default:
+ __rxrpc_call_abort(call, ret);
+ _leave(" = %d", ret);
return ret;
case -EAGAIN:
spin_unlock(&call->lock);
- if (!(flags&RXRPC_CALL_READ_BLOCK)) {
+ if (!(flags & RXRPC_CALL_READ_BLOCK)) {
_leave(" = -EAGAIN");
return -EAGAIN;
}
@@ -1789,7 +1898,7 @@ int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int
return -EINTR;
}
- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
+ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
_leave(" = -ECONNABORTED");
return -ECONNABORTED;
}
@@ -1804,8 +1913,8 @@ int rxrpc_call_read_data(struct rxrpc_call *call, void *buffer, size_t size, int
/*
* write data to a call
* - the data may not be sent immediately if it doesn't fill a buffer
- * - if we can't queue all the data for buffering now, siov[] will have been adjusted to take
- * account of what has been sent
+ * - if we can't queue all the data for buffering now, siov[] will have been
+ * adjusted to take account of what has been sent
*/
int rxrpc_call_write_data(struct rxrpc_call *call,
size_t sioc,
@@ -1821,7 +1930,9 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
char *buf;
int ret;
- _enter("%p,%Zu,%p,%02x,%x,%d,%p",call,sioc,siov,rxhdr_flags,alloc_flags,dup_data,size_sent);
+ _enter("%p,%Zu,%p,%02x,%x,%d,%p",
+ call, sioc, siov, rxhdr_flags, alloc_flags, dup_data,
+ size_sent);
*size_sent = 0;
size = 0;
@@ -1840,8 +1951,9 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
/* calculate how much data we've been given */
sptr = siov;
- for (; sioc>0; sptr++, sioc--) {
- if (!sptr->iov_len) continue;
+ for (; sioc > 0; sptr++, sioc--) {
+ if (!sptr->iov_len)
+ continue;
if (!sptr->iov_base)
goto out;
@@ -1849,27 +1961,30 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
size += sptr->iov_len;
}
- _debug("- size=%Zu mtu=%Zu",size,call->conn->mtu_size);
+ _debug("- size=%Zu mtu=%Zu", size, call->conn->mtu_size);
do {
/* make sure there's a message under construction */
if (!call->snd_nextmsg) {
/* no - allocate a message with no data yet attached */
- ret = rxrpc_conn_newmsg(call->conn,call,RXRPC_PACKET_TYPE_DATA,
- 0,NULL,alloc_flags,&call->snd_nextmsg);
- if (ret<0)
+ ret = rxrpc_conn_newmsg(call->conn, call,
+ RXRPC_PACKET_TYPE_DATA,
+ 0, NULL, alloc_flags,
+ &call->snd_nextmsg);
+ if (ret < 0)
goto out;
- _debug("- allocated new message [ds=%Zu]",call->snd_nextmsg->dsize);
+ _debug("- allocated new message [ds=%Zu]",
+ call->snd_nextmsg->dsize);
}
msg = call->snd_nextmsg;
msg->hdr.flags |= rxhdr_flags;
/* deal with zero-length terminal packet */
- if (size==0) {
+ if (size == 0) {
if (rxhdr_flags & RXRPC_LAST_PACKET) {
ret = rxrpc_call_flush(call);
- if (ret<0)
+ if (ret < 0)
goto out;
}
break;
@@ -1877,24 +1992,27 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
/* work out how much space current packet has available */
space = call->conn->mtu_size - msg->dsize;
- chunk = min(space,size);
+ chunk = min(space, size);
- _debug("- [before] space=%Zu chunk=%Zu",space,chunk);
+ _debug("- [before] space=%Zu chunk=%Zu", space, chunk);
while (!siov->iov_len)
siov++;
- /* if we are going to have to duplicate the data then coalesce it too */
+ /* if we are going to have to duplicate the data then coalesce
+ * it too */
if (dup_data) {
/* don't allocate more that 1 page at a time */
- if (chunk>PAGE_SIZE)
+ if (chunk > PAGE_SIZE)
chunk = PAGE_SIZE;
/* allocate a data buffer and attach to the message */
- buf = kmalloc(chunk,alloc_flags);
+ buf = kmalloc(chunk, alloc_flags);
if (unlikely(!buf)) {
- if (msg->dsize==sizeof(struct rxrpc_header)) {
- /* discard an empty msg and wind back the seq counter */
+ if (msg->dsize ==
+ sizeof(struct rxrpc_header)) {
+ /* discard an empty msg and wind back
+ * the seq counter */
rxrpc_put_message(msg);
call->snd_nextmsg = NULL;
call->snd_seq_count--;
@@ -1905,7 +2023,7 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
}
tmp = msg->dcount++;
- set_bit(tmp,&msg->dfree);
+ set_bit(tmp, &msg->dfree);
msg->data[tmp].iov_base = buf;
msg->data[tmp].iov_len = chunk;
msg->dsize += chunk;
@@ -1913,9 +2031,9 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
size -= chunk;
/* load the buffer with data */
- while (chunk>0) {
- tmp = min(chunk,siov->iov_len);
- memcpy(buf,siov->iov_base,tmp);
+ while (chunk > 0) {
+ tmp = min(chunk, siov->iov_len);
+ memcpy(buf, siov->iov_base, tmp);
buf += tmp;
siov->iov_base += tmp;
siov->iov_len -= tmp;
@@ -1926,7 +2044,8 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
}
else {
/* we want to attach the supplied buffers directly */
- while (chunk>0 && msg->dcount<RXRPC_MSG_MAX_IOCS) {
+ while (chunk > 0 &&
+ msg->dcount < RXRPC_MSG_MAX_IOCS) {
tmp = msg->dcount++;
msg->data[tmp].iov_base = siov->iov_base;
msg->data[tmp].iov_len = siov->iov_len;
@@ -1938,20 +2057,20 @@ int rxrpc_call_write_data(struct rxrpc_call *call,
}
}
- _debug("- [loaded] chunk=%Zu size=%Zu",chunk,size);
+ _debug("- [loaded] chunk=%Zu size=%Zu", chunk, size);
/* dispatch the message when full, final or requesting ACK */
- if (msg->dsize>=call->conn->mtu_size || rxhdr_flags) {
+ if (msg->dsize >= call->conn->mtu_size || rxhdr_flags) {
ret = rxrpc_call_flush(call);
- if (ret<0)
+ if (ret < 0)
goto out;
}
- } while(size>0);
+ } while(size > 0);
ret = 0;
out:
- _leave(" = %d (%Zd queued, %Zd rem)",ret,*size_sent,size);
+ _leave(" = %d (%Zd queued, %Zd rem)", ret, *size_sent, size);
return ret;
} /* end rxrpc_call_write_data() */
@@ -1965,7 +2084,7 @@ int rxrpc_call_flush(struct rxrpc_call *call)
struct rxrpc_message *msg;
int ret = 0;
- _enter("%p",call);
+ _enter("%p", call);
rxrpc_get_call(call);
@@ -1983,25 +2102,28 @@ int rxrpc_call_flush(struct rxrpc_call *call)
}
_proto("Sending DATA message { ds=%Zu dc=%u df=%02lu }",
- msg->dsize,msg->dcount,msg->dfree);
+ msg->dsize, msg->dcount, msg->dfree);
/* queue and adjust call state */
spin_lock(&call->lock);
- list_add_tail(&msg->link,&call->acks_pendq);
+ list_add_tail(&msg->link, &call->acks_pendq);
- /* decide what to do depending on current state and if this is the last packet */
+ /* decide what to do depending on current state and if this is
+ * the last packet */
ret = -EINVAL;
switch (call->app_call_state) {
case RXRPC_CSTATE_SRVR_SND_REPLY:
if (msg->hdr.flags & RXRPC_LAST_PACKET) {
- call->app_call_state = RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
+ call->app_call_state =
+ RXRPC_CSTATE_SRVR_RCV_FINAL_ACK;
_state(call);
}
break;
case RXRPC_CSTATE_CLNT_SND_ARGS:
if (msg->hdr.flags & RXRPC_LAST_PACKET) {
- call->app_call_state = RXRPC_CSTATE_CLNT_RCV_REPLY;
+ call->app_call_state =
+ RXRPC_CSTATE_CLNT_RCV_REPLY;
_state(call);
}
break;
@@ -2016,19 +2138,20 @@ int rxrpc_call_flush(struct rxrpc_call *call)
call->acks_pend_cnt++;
mod_timer(&call->acks_timeout,
- __rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
+ __rxrpc_rtt_based_timeout(call,
+ rxrpc_call_acks_timeout));
spin_unlock(&call->lock);
- ret = rxrpc_conn_sendmsg(call->conn,msg);
- if (ret==0)
+ ret = rxrpc_conn_sendmsg(call->conn, msg);
+ if (ret == 0)
call->pkt_snd_count++;
}
out:
rxrpc_put_call(call);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_call_flush() */
@@ -2043,14 +2166,16 @@ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest)
struct list_head *_p;
rxrpc_seq_t seq = 0;
- _enter("%p,%u",call,highest);
+ _enter("%p,%u", call, highest);
_proto("Rx Resend required");
/* handle too many resends */
- if (call->snd_resend_cnt>=rxrpc_call_max_resend) {
- _debug("Aborting due to too many resends (rcv=%d)",call->pkt_rcv_count);
- rxrpc_call_abort(call,call->pkt_rcv_count>0?-EIO:-ETIMEDOUT);
+ if (call->snd_resend_cnt >= rxrpc_call_max_resend) {
+ _debug("Aborting due to too many resends (rcv=%d)",
+ call->pkt_rcv_count);
+ rxrpc_call_abort(call,
+ call->pkt_rcv_count > 0 ? -EIO : -ETIMEDOUT);
_leave("");
return;
}
@@ -2059,35 +2184,38 @@ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest)
call->snd_resend_cnt++;
for (;;) {
/* determine which the next packet we might need to ACK is */
- if (seq<=call->acks_dftv_seq)
+ if (seq <= call->acks_dftv_seq)
seq = call->acks_dftv_seq;
seq++;
- if (seq>highest)
+ if (seq > highest)
break;
/* look for the packet in the pending-ACK queue */
- list_for_each(_p,&call->acks_pendq) {
- msg = list_entry(_p,struct rxrpc_message,link);
- if (msg->seq==seq)
+ list_for_each(_p, &call->acks_pendq) {
+ msg = list_entry(_p, struct rxrpc_message, link);
+ if (msg->seq == seq)
goto found_msg;
}
- panic("%s(%p,%d): Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
- __FUNCTION__,call,highest,call->acks_dftv_seq,call->snd_seq_count,seq);
+ panic("%s(%p,%d):"
+ " Inconsistent pending-ACK queue (ds=%u sc=%u sq=%u)\n",
+ __FUNCTION__, call, highest,
+ call->acks_dftv_seq, call->snd_seq_count, seq);
found_msg:
- if (msg->state!=RXRPC_MSG_SENT)
+ if (msg->state != RXRPC_MSG_SENT)
continue; /* only un-ACK'd packets */
rxrpc_get_message(msg);
spin_unlock(&call->lock);
- /* send each message again (and ignore any errors we might incur) */
+ /* send each message again (and ignore any errors we might
+ * incur) */
_proto("Resending DATA message { ds=%Zu dc=%u df=%02lu }",
- msg->dsize,msg->dcount,msg->dfree);
+ msg->dsize, msg->dcount, msg->dfree);
- if (rxrpc_conn_sendmsg(call->conn,msg)==0)
+ if (rxrpc_conn_sendmsg(call->conn, msg) == 0)
call->pkt_snd_count++;
rxrpc_put_message(msg);
@@ -2096,7 +2224,8 @@ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest)
}
/* reset the timeout */
- mod_timer(&call->acks_timeout,__rxrpc_rtt_based_timeout(call,rxrpc_call_acks_timeout));
+ mod_timer(&call->acks_timeout,
+ __rxrpc_rtt_based_timeout(call, rxrpc_call_acks_timeout));
spin_unlock(&call->lock);
@@ -2109,10 +2238,10 @@ static void rxrpc_call_resend(struct rxrpc_call *call, rxrpc_seq_t highest)
*/
void rxrpc_call_handle_error(struct rxrpc_call *call, int local, int errno)
{
- _enter("%p{%u},%d",call,ntohl(call->call_id),errno);
+ _enter("%p{%u},%d", call, ntohl(call->call_id), errno);
/* if this call is already aborted, then just wake up any waiters */
- if (call->app_call_state==RXRPC_CSTATE_ERROR) {
+ if (call->app_call_state == RXRPC_CSTATE_ERROR) {
call->app_error_func(call);
}
else {
@@ -2124,10 +2253,10 @@ void rxrpc_call_handle_error(struct rxrpc_call *call, int local, int errno)
call->app_err_state = RXRPC_ESTATE_LOCAL_ERROR;
else
call->app_err_state = RXRPC_ESTATE_REMOTE_ERROR;
- call->app_errno = errno;
- call->app_mark = RXRPC_APP_MARK_EOF;
- call->app_read_buf = NULL;
- call->app_async_read = 0;
+ call->app_errno = errno;
+ call->app_mark = RXRPC_APP_MARK_EOF;
+ call->app_read_buf = NULL;
+ call->app_async_read = 0;
/* map the error */
call->app_aemap_func(call);
diff --git a/net/rxrpc/connection.c b/net/rxrpc/connection.c
index a60412d9f7bf..172c63127784 100644
--- a/net/rxrpc/connection.c
+++ b/net/rxrpc/connection.c
@@ -28,18 +28,20 @@ __RXACCT_DECL(atomic_t rxrpc_connection_count);
LIST_HEAD(rxrpc_conns);
DECLARE_RWSEM(rxrpc_conns_sem);
+unsigned long rxrpc_conn_timeout = 60 * 60;
static void __rxrpc_conn_timeout(rxrpc_timer_t *timer)
{
- struct rxrpc_connection *conn = list_entry(timer,struct rxrpc_connection,timeout);
+ struct rxrpc_connection *conn =
+ list_entry(timer, struct rxrpc_connection, timeout);
- _debug("Rx CONN TIMEOUT [%p{u=%d}]",conn,atomic_read(&conn->usage));
+ _debug("Rx CONN TIMEOUT [%p{u=%d}]", conn, atomic_read(&conn->usage));
rxrpc_conn_do_timeout(conn);
}
static const struct rxrpc_timer_ops rxrpc_conn_timer_ops = {
- .timed_out = __rxrpc_conn_timeout,
+ timed_out: __rxrpc_conn_timeout,
};
/*****************************************************************************/
@@ -54,19 +56,20 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer,
_enter("%p",peer);
/* allocate and initialise a connection record */
- conn = kmalloc(sizeof(struct rxrpc_connection),GFP_KERNEL);
+ conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL);
if (!conn) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
- memset(conn,0,sizeof(struct rxrpc_connection));
- atomic_set(&conn->usage,1);
+ memset(conn, 0, sizeof(struct rxrpc_connection));
+ atomic_set(&conn->usage, 1);
INIT_LIST_HEAD(&conn->link);
+ INIT_LIST_HEAD(&conn->id_link);
init_waitqueue_head(&conn->chanwait);
spin_lock_init(&conn->lock);
- rxrpc_timer_init(&conn->timeout,&rxrpc_conn_timer_ops);
+ rxrpc_timer_init(&conn->timeout, &rxrpc_conn_timer_ops);
do_gettimeofday(&conn->atime);
conn->mtu_size = 1024;
@@ -75,7 +78,7 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer,
__RXACCT(atomic_inc(&rxrpc_connection_count));
*_conn = conn;
- _leave(" = 0 (%p)",conn);
+ _leave(" = 0 (%p)", conn);
return 0;
} /* end __rxrpc_create_connection() */
@@ -85,61 +88,123 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer,
* create a new connection record for outgoing connections
*/
int rxrpc_create_connection(struct rxrpc_transport *trans,
- u16 port,
- u32 addr,
- unsigned short service_id,
+ uint16_t port,
+ uint32_t addr,
+ uint16_t service_id,
void *security,
struct rxrpc_connection **_conn)
{
- struct rxrpc_connection *conn;
+ struct rxrpc_connection *candidate, *conn;
struct rxrpc_peer *peer;
+ struct list_head *_p;
+ uint32_t connid;
int ret;
- _enter("%p{%hu},%u,%hu",trans,trans->port,ntohs(port),service_id);
+ _enter("%p{%hu},%u,%hu", trans, trans->port, ntohs(port), service_id);
/* get a peer record */
- ret = rxrpc_peer_lookup(trans,addr,&peer);
- if (ret<0) {
- _leave(" = %d",ret);
+ ret = rxrpc_peer_lookup(trans, addr, &peer);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ret;
}
/* allocate and initialise a connection record */
- ret = __rxrpc_create_connection(peer,&conn);
- if (ret<0) {
+ ret = __rxrpc_create_connection(peer, &candidate);
+ if (ret < 0) {
rxrpc_put_peer(peer);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
}
/* fill in the specific bits */
- conn->addr.sin_family = AF_INET;
- conn->addr.sin_port = port;
- conn->addr.sin_addr.s_addr = addr;
+ candidate->addr.sin_family = AF_INET;
+ candidate->addr.sin_port = port;
+ candidate->addr.sin_addr.s_addr = addr;
+
+ candidate->in_epoch = rxrpc_epoch;
+ candidate->out_epoch = rxrpc_epoch;
+ candidate->in_clientflag = 0;
+ candidate->out_clientflag = RXRPC_CLIENT_INITIATED;
+ candidate->service_id = htons(service_id);
+
+ /* invent a unique connection ID */
+ write_lock(&peer->conn_idlock);
+
+ try_next_id:
+ connid = htonl(peer->conn_idcounter & RXRPC_CIDMASK);
+ peer->conn_idcounter += RXRPC_MAXCALLS;
+
+ list_for_each(_p, &peer->conn_idlist) {
+ conn = list_entry(_p, struct rxrpc_connection, id_link);
+ if (connid == conn->conn_id)
+ goto try_next_id;
+ if (connid > conn->conn_id)
+ break;
+ }
+
+ _debug("selected candidate conn ID %x.%u",
+ ntohl(peer->addr.s_addr), ntohl(connid));
+
+ candidate->conn_id = connid;
+ list_add_tail(&candidate->id_link, _p);
- conn->in_epoch = rxrpc_epoch;
- conn->out_epoch = rxrpc_epoch;
- conn->in_clientflag = 0;
- conn->out_clientflag = RXRPC_CLIENT_INITIATED;
- conn->conn_id = htonl((unsigned long) conn & RXRPC_CIDMASK);
- conn->service_id = htons(service_id);
+ write_unlock(&peer->conn_idlock);
/* attach to peer */
- conn->peer = peer;
+ candidate->peer = peer;
write_lock(&peer->conn_lock);
- list_add_tail(&conn->link,&peer->conn_active);
+
+ /* search the peer's transport graveyard list */
+ spin_lock(&peer->conn_gylock);
+ list_for_each(_p, &peer->conn_graveyard) {
+ conn = list_entry(_p, struct rxrpc_connection, link);
+ if (conn->addr.sin_port == candidate->addr.sin_port &&
+ conn->security_ix == candidate->security_ix &&
+ conn->service_id == candidate->service_id &&
+ conn->in_clientflag == 0)
+ goto found_in_graveyard;
+ }
+ spin_unlock(&peer->conn_gylock);
+
+ /* pick the new candidate */
+ _debug("created connection: {%08x} [out]", htonl(candidate->conn_id));
atomic_inc(&peer->conn_count);
+ conn = candidate;
+ candidate = NULL;
+
+ make_active:
+ list_add_tail(&conn->link, &peer->conn_active);
write_unlock(&peer->conn_lock);
- down_write(&rxrpc_conns_sem);
- list_add_tail(&conn->proc_link,&rxrpc_conns);
- up_write(&rxrpc_conns_sem);
+ if (candidate) {
+ write_lock(&peer->conn_idlock);
+ list_del(&candidate->id_link);
+ write_unlock(&peer->conn_idlock);
+
+ __RXACCT(atomic_dec(&rxrpc_connection_count));
+ kfree(candidate);
+ }
+ else {
+ down_write(&rxrpc_conns_sem);
+ list_add_tail(&conn->proc_link, &rxrpc_conns);
+ up_write(&rxrpc_conns_sem);
+ }
*_conn = conn;
- _leave(" = 0 (%p)",conn);
+ _leave(" = 0 (%p)", conn);
return 0;
+
+ /* handle resurrecting a connection from the graveyard */
+ found_in_graveyard:
+ _debug("resurrecting connection: {%08x} [out]", htonl(conn->conn_id));
+ rxrpc_get_connection(conn);
+ rxrpc_krxtimod_del_timer(&conn->timeout);
+ list_del_init(&conn->link);
+ spin_unlock(&peer->conn_gylock);
+ goto make_active;
} /* end rxrpc_create_connection() */
/*****************************************************************************/
@@ -159,7 +224,10 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
u8 x_clflag;
_enter("%p{{%hu}},%u,%hu",
- peer,peer->trans->port,ntohs(msg->pkt->h.uh->source),ntohs(msg->hdr.serviceId));
+ peer,
+ peer->trans->port,
+ ntohs(msg->pkt->h.uh->source),
+ ntohs(msg->hdr.serviceId));
x_port = msg->pkt->h.uh->source;
x_epoch = msg->hdr.epoch;
@@ -170,8 +238,8 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
/* [common case] search the transport's active list first */
read_lock(&peer->conn_lock);
- list_for_each(_p,&peer->conn_active) {
- conn = list_entry(_p,struct rxrpc_connection,link);
+ list_for_each(_p, &peer->conn_active) {
+ conn = list_entry(_p, struct rxrpc_connection, link);
if (conn->addr.sin_port == x_port &&
conn->in_epoch == x_epoch &&
conn->conn_id == x_connid &&
@@ -187,9 +255,9 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
* - only examine the graveyard for an outbound connection
*/
if (x_clflag) {
- ret = __rxrpc_create_connection(peer,&candidate);
- if (ret<0) {
- _leave(" = %d",ret);
+ ret = __rxrpc_create_connection(peer, &candidate);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ret;
}
@@ -206,10 +274,11 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
candidate->security_ix = x_secix;
}
- /* search the active list again, just in case it appeared whilst we were busy */
+ /* search the active list again, just in case it appeared whilst we
+ * were busy */
write_lock(&peer->conn_lock);
- list_for_each(_p,&peer->conn_active) {
- conn = list_entry(_p,struct rxrpc_connection,link);
+ list_for_each(_p, &peer->conn_active) {
+ conn = list_entry(_p, struct rxrpc_connection, link);
if (conn->addr.sin_port == x_port &&
conn->in_epoch == x_epoch &&
conn->conn_id == x_connid &&
@@ -221,8 +290,8 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
/* search the transport's graveyard list */
spin_lock(&peer->conn_gylock);
- list_for_each(_p,&peer->conn_graveyard) {
- conn = list_entry(_p,struct rxrpc_connection,link);
+ list_for_each(_p, &peer->conn_graveyard) {
+ conn = list_entry(_p, struct rxrpc_connection, link);
if (conn->addr.sin_port == x_port &&
conn->in_epoch == x_epoch &&
conn->conn_id == x_connid &&
@@ -241,6 +310,7 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
}
/* we can now add the new candidate to the list */
+ _debug("created connection: {%08x} [in]", htonl(candidate->conn_id));
rxrpc_get_peer(peer);
conn = candidate;
candidate = NULL;
@@ -248,25 +318,29 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
fresh = 1;
make_active:
- list_add_tail(&conn->link,&peer->conn_active);
+ list_add_tail(&conn->link, &peer->conn_active);
success_uwfree:
write_unlock(&peer->conn_lock);
if (candidate) {
+ write_lock(&peer->conn_idlock);
+ list_del(&candidate->id_link);
+ write_unlock(&peer->conn_idlock);
+
__RXACCT(atomic_dec(&rxrpc_connection_count));
kfree(candidate);
}
if (fresh) {
down_write(&rxrpc_conns_sem);
- list_add_tail(&conn->proc_link,&rxrpc_conns);
+ list_add_tail(&conn->proc_link, &rxrpc_conns);
up_write(&rxrpc_conns_sem);
}
success:
*_conn = conn;
- _leave(" = 0 (%p)",conn);
+ _leave(" = 0 (%p)", conn);
return 0;
/* handle the connection being found in the active list straight off */
@@ -277,6 +351,7 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
/* handle resurrecting a connection from the graveyard */
found_in_graveyard:
+ _debug("resurrecting connection: {%08x} [in]", htonl(conn->conn_id));
rxrpc_get_peer(peer);
rxrpc_get_connection(conn);
rxrpc_krxtimod_del_timer(&conn->timeout);
@@ -284,7 +359,8 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
spin_unlock(&peer->conn_gylock);
goto make_active;
- /* handle finding the connection on the second time through the active list */
+ /* handle finding the connection on the second time through the active
+ * list */
found_active_second_chance:
rxrpc_get_connection(conn);
goto success_uwfree;
@@ -294,19 +370,26 @@ int rxrpc_connection_lookup(struct rxrpc_peer *peer,
/*****************************************************************************/
/*
* finish using a connection record
- * - it will be transferred to the peer's connection graveyard when refcount reaches 0
+ * - it will be transferred to the peer's connection graveyard when refcount
+ * reaches 0
*/
void rxrpc_put_connection(struct rxrpc_connection *conn)
{
- struct rxrpc_peer *peer = conn->peer;
+ struct rxrpc_peer *peer;
+
+ if (!conn)
+ return;
+
+ _enter("%p{u=%d p=%hu}",
+ conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
- _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
+ peer = conn->peer;
+ spin_lock(&peer->conn_gylock);
/* sanity check */
- if (atomic_read(&conn->usage)<=0)
+ if (atomic_read(&conn->usage) <= 0)
BUG();
- spin_lock(&peer->conn_gylock);
if (likely(!atomic_dec_and_test(&conn->usage))) {
spin_unlock(&peer->conn_gylock);
_leave("");
@@ -314,11 +397,11 @@ void rxrpc_put_connection(struct rxrpc_connection *conn)
}
/* move to graveyard queue */
+ _debug("burying connection: {%08x}", htonl(conn->conn_id));
list_del(&conn->link);
- list_add_tail(&conn->link,&peer->conn_graveyard);
+ list_add_tail(&conn->link, &peer->conn_graveyard);
- /* discard in 100 secs */
- rxrpc_krxtimod_add_timer(&conn->timeout,20*HZ);
+ rxrpc_krxtimod_add_timer(&conn->timeout, rxrpc_conn_timeout * HZ);
spin_unlock(&peer->conn_gylock);
@@ -335,16 +418,17 @@ void rxrpc_conn_do_timeout(struct rxrpc_connection *conn)
{
struct rxrpc_peer *peer;
- _enter("%p{u=%d p=%hu}",conn,atomic_read(&conn->usage),ntohs(conn->addr.sin_port));
+ _enter("%p{u=%d p=%hu}",
+ conn, atomic_read(&conn->usage), ntohs(conn->addr.sin_port));
peer = conn->peer;
- if (atomic_read(&conn->usage)<0)
+ if (atomic_read(&conn->usage) < 0)
BUG();
/* remove from graveyard if still dead */
spin_lock(&peer->conn_gylock);
- if (atomic_read(&conn->usage)==0) {
+ if (atomic_read(&conn->usage) == 0) {
list_del_init(&conn->link);
}
else {
@@ -357,12 +441,17 @@ void rxrpc_conn_do_timeout(struct rxrpc_connection *conn)
return; /* resurrected */
}
- _debug("--- Destroying Connection %p ---",conn);
+ _debug("--- Destroying Connection %p{%08x} ---",
+ conn, htonl(conn->conn_id));
down_write(&rxrpc_conns_sem);
list_del(&conn->proc_link);
up_write(&rxrpc_conns_sem);
+ write_lock(&peer->conn_idlock);
+ list_del(&conn->id_link);
+ write_unlock(&peer->conn_idlock);
+
__RXACCT(atomic_dec(&rxrpc_connection_count));
kfree(conn);
@@ -379,12 +468,12 @@ void rxrpc_conn_do_timeout(struct rxrpc_connection *conn)
*/
void rxrpc_conn_clearall(struct rxrpc_peer *peer)
{
- DECLARE_WAITQUEUE(myself,current);
+ DECLARE_WAITQUEUE(myself, current);
struct rxrpc_connection *conn;
int err;
- _enter("%p",peer);
+ _enter("%p", peer);
/* there shouldn't be any active conns remaining */
if (!list_empty(&peer->conn_active))
@@ -393,11 +482,12 @@ void rxrpc_conn_clearall(struct rxrpc_peer *peer)
/* manually timeout all conns in the graveyard */
spin_lock(&peer->conn_gylock);
while (!list_empty(&peer->conn_graveyard)) {
- conn = list_entry(peer->conn_graveyard.next,struct rxrpc_connection,link);
+ conn = list_entry(peer->conn_graveyard.next,
+ struct rxrpc_connection, link);
err = rxrpc_krxtimod_del_timer(&conn->timeout);
spin_unlock(&peer->conn_gylock);
- if (err==0)
+ if (err == 0)
rxrpc_conn_do_timeout(conn);
spin_lock(&peer->conn_gylock);
@@ -406,27 +496,27 @@ void rxrpc_conn_clearall(struct rxrpc_peer *peer)
/* wait for the the conn graveyard to be completely cleared */
set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&peer->conn_gy_waitq,&myself);
+ add_wait_queue(&peer->conn_gy_waitq, &myself);
- while (atomic_read(&peer->conn_count)!=0) {
+ while (atomic_read(&peer->conn_count) != 0) {
schedule();
set_current_state(TASK_UNINTERRUPTIBLE);
}
- remove_wait_queue(&peer->conn_gy_waitq,&myself);
+ remove_wait_queue(&peer->conn_gy_waitq, &myself);
set_current_state(TASK_RUNNING);
_leave("");
-
} /* end rxrpc_conn_clearall() */
/*****************************************************************************/
/*
- * allocate and prepare a message for sending out through the transport endpoint
+ * allocate and prepare a message for sending out through the transport
+ * endpoint
*/
int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
struct rxrpc_call *call,
- u8 type,
+ uint8_t type,
int dcount,
struct iovec diov[],
int alloc_flags,
@@ -435,21 +525,21 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
struct rxrpc_message *msg;
int loop;
- _enter("%p{%d},%p,%u",conn,ntohs(conn->addr.sin_port),call,type);
+ _enter("%p{%d},%p,%u", conn, ntohs(conn->addr.sin_port), call, type);
- if (dcount>3) {
+ if (dcount > 3) {
_leave(" = -EINVAL");
return -EINVAL;
}
- msg = kmalloc(sizeof(struct rxrpc_message),alloc_flags);
+ msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags);
if (!msg) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
- memset(msg,0,sizeof(*msg));
- atomic_set(&msg->usage,1);
+ memset(msg, 0, sizeof(*msg));
+ atomic_set(&msg->usage, 1);
INIT_LIST_HEAD(&msg->link);
@@ -471,7 +561,8 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
msg->hdr.seq = htonl(msg->seq);
break;
case RXRPC_PACKET_TYPE_ACK:
- /* ACK sequence numbers are complicated. The following may be wrong:
+ /* ACK sequence numbers are complicated. The following
+ * may be wrong:
* - jumbo packet ACKs should have a seq number
* - normal ACKs should not
*/
@@ -485,7 +576,7 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
msg->data[0].iov_len = sizeof(msg->hdr);
msg->data[0].iov_base = &msg->hdr;
- for (loop=0; loop<dcount; loop++) {
+ for (loop=0; loop < dcount; loop++) {
msg->dsize += diov[loop].iov_len;
msg->data[loop+1].iov_len = diov[loop].iov_len;
msg->data[loop+1].iov_base = diov[loop].iov_base;
@@ -493,7 +584,7 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
__RXACCT(atomic_inc(&rxrpc_message_count));
*_msg = msg;
- _leave(" = 0 (%p) #%d",msg,atomic_read(&rxrpc_message_count));
+ _leave(" = 0 (%p) #%d", msg, atomic_read(&rxrpc_message_count));
return 0;
} /* end rxrpc_conn_newmsg() */
@@ -505,13 +596,14 @@ void __rxrpc_put_message(struct rxrpc_message *msg)
{
int loop;
- _enter("%p #%d",msg,atomic_read(&rxrpc_message_count));
+ _enter("%p #%d", msg, atomic_read(&rxrpc_message_count));
- if (msg->pkt) kfree_skb(msg->pkt);
- if (msg->conn) rxrpc_put_connection(msg->conn);
+ if (msg->pkt)
+ kfree_skb(msg->pkt);
+ rxrpc_put_connection(msg->conn);
- for (loop=0; loop<8; loop++)
- if (test_bit(loop,&msg->dfree))
+ for (loop = 0; loop < 8; loop++)
+ if (test_bit(loop, &msg->dfree))
kfree(msg->data[loop].iov_base);
__RXACCT(atomic_dec(&rxrpc_message_count));
@@ -524,13 +616,14 @@ void __rxrpc_put_message(struct rxrpc_message *msg)
/*
* send a message out through the transport endpoint
*/
-int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
+int rxrpc_conn_sendmsg(struct rxrpc_connection *conn,
+ struct rxrpc_message *msg)
{
struct msghdr msghdr;
mm_segment_t oldfs;
int ret;
- _enter("%p{%d}",conn,ntohs(conn->addr.sin_port));
+ _enter("%p{%d}", conn, ntohs(conn->addr.sin_port));
/* fill in some fields in the header */
spin_lock(&conn->lock);
@@ -545,7 +638,7 @@ int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
msghdr.msg_iovlen = msg->dcount;
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
- msghdr.msg_flags = MSG_CONFIRM|MSG_DONTWAIT;
+ msghdr.msg_flags = MSG_CONFIRM | MSG_DONTWAIT;
_net("Sending message type %d of %Zd bytes to %08x:%d",
msg->hdr.type,
@@ -556,10 +649,10 @@ int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
/* send the message */
oldfs = get_fs();
set_fs(KERNEL_DS);
- ret = sock_sendmsg(conn->trans->socket,&msghdr,msg->dsize);
+ ret = sock_sendmsg(conn->trans->socket, &msghdr, msg->dsize);
set_fs(oldfs);
- if (ret<0) {
+ if (ret < 0) {
msg->state = RXRPC_MSG_ERROR;
}
else {
@@ -572,7 +665,7 @@ int rxrpc_conn_sendmsg(struct rxrpc_connection *conn, struct rxrpc_message *msg)
spin_unlock(&conn->lock);
}
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_conn_sendmsg() */
@@ -590,7 +683,7 @@ int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
unsigned cix, seq;
int ret = 0;
- _enter("%p,%p,%p",conn,call,msg);
+ _enter("%p,%p,%p", conn, call, msg);
if (!call) {
cix = ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK;
@@ -600,7 +693,7 @@ int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
if (!call || call->call_id != msg->hdr.callNumber) {
spin_unlock(&conn->lock);
- rxrpc_trans_immediate_abort(conn->trans,msg,-ENOENT);
+ rxrpc_trans_immediate_abort(conn->trans, msg, -ENOENT);
goto out;
}
else {
@@ -622,19 +715,21 @@ int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
call->pkt_rcv_count++;
if (msg->pkt->dst && msg->pkt->dst->dev)
- conn->peer->if_mtu = msg->pkt->dst->dev->mtu - msg->pkt->dst->dev->hard_header_len;
+ conn->peer->if_mtu =
+ msg->pkt->dst->dev->mtu -
+ msg->pkt->dst->dev->hard_header_len;
/* queue on the call in seq order */
rxrpc_get_message(msg);
seq = msg->seq;
spin_lock(&call->lock);
- list_for_each(_p,&call->rcv_receiveq) {
- pmsg = list_entry(_p,struct rxrpc_message,link);
- if (pmsg->seq>seq)
+ list_for_each(_p, &call->rcv_receiveq) {
+ pmsg = list_entry(_p, struct rxrpc_message, link);
+ if (pmsg->seq > seq)
break;
}
- list_add_tail(&msg->link,_p);
+ list_add_tail(&msg->link, _p);
/* reset the activity timeout */
call->flags |= RXRPC_CALL_RCV_PKT;
@@ -646,8 +741,7 @@ int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
rxrpc_put_call(call);
out:
- _leave(" = %d",ret);
-
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_conn_receive_call_packet() */
@@ -655,18 +749,19 @@ int rxrpc_conn_receive_call_packet(struct rxrpc_connection *conn,
/*
* handle an ICMP error being applied to a connection
*/
-void rxrpc_conn_handle_error(struct rxrpc_connection *conn, int local, int errno)
+void rxrpc_conn_handle_error(struct rxrpc_connection *conn,
+ int local, int errno)
{
struct rxrpc_call *calls[4];
int loop;
- _enter("%p{%d},%d",conn,ntohs(conn->addr.sin_port),errno);
+ _enter("%p{%d},%d", conn, ntohs(conn->addr.sin_port), errno);
/* get a ref to all my calls in one go */
- memset(calls,0,sizeof(calls));
+ memset(calls, 0, sizeof(calls));
spin_lock(&conn->lock);
- for (loop=3; loop>=0; loop--) {
+ for (loop = 3; loop >= 0; loop--) {
if (conn->channels[loop]) {
calls[loop] = conn->channels[loop];
rxrpc_get_call(calls[loop]);
@@ -676,9 +771,9 @@ void rxrpc_conn_handle_error(struct rxrpc_connection *conn, int local, int errno
spin_unlock(&conn->lock);
/* now kick them all */
- for (loop=3; loop>=0; loop--) {
+ for (loop = 3; loop >= 0; loop--) {
if (calls[loop]) {
- rxrpc_call_handle_error(calls[loop],local,errno);
+ rxrpc_call_handle_error(calls[loop], local, errno);
rxrpc_put_call(calls[loop]);
}
}
diff --git a/net/rxrpc/internal.h b/net/rxrpc/internal.h
index f76d48c4cf3d..752b6d71d017 100644
--- a/net/rxrpc/internal.h
+++ b/net/rxrpc/internal.h
@@ -55,7 +55,7 @@ static inline void rxrpc_discard_my_signals(void)
siginfo_t sinfo;
spin_lock_irq(&current->sighand->siglock);
- dequeue_signal(current,&current->blocked,&sinfo);
+ dequeue_signal(current, &current->blocked, &sinfo);
spin_unlock_irq(&current->sighand->siglock);
}
}
@@ -71,6 +71,7 @@ extern struct rw_semaphore rxrpc_calls_sem;
*/
extern struct list_head rxrpc_conns;
extern struct rw_semaphore rxrpc_conns_sem;
+extern unsigned long rxrpc_conn_timeout;
extern void rxrpc_conn_do_timeout(struct rxrpc_connection *conn);
extern void rxrpc_conn_clearall(struct rxrpc_peer *peer);
@@ -80,6 +81,7 @@ extern void rxrpc_conn_clearall(struct rxrpc_peer *peer);
*/
extern struct list_head rxrpc_peers;
extern struct rw_semaphore rxrpc_peers_sem;
+extern unsigned long rxrpc_peer_timeout;
extern void rxrpc_peer_calculate_rtt(struct rxrpc_peer *peer,
struct rxrpc_message *msg,
diff --git a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
index dfaf47994e8e..051ae4b397d6 100644
--- a/net/rxrpc/krxiod.c
+++ b/net/rxrpc/krxiod.c
@@ -44,6 +44,12 @@ static int rxrpc_krxiod(void *arg)
daemonize("krxiod");
+ /* only certain signals are of interest */
+ spin_lock_irq(&current->sighand->siglock);
+ siginitsetinv(&current->blocked, 0);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
/* loop around waiting for work to do */
do {
/* wait for work or to be told to exit */
@@ -51,7 +57,7 @@ static int rxrpc_krxiod(void *arg)
if (!atomic_read(&rxrpc_krxiod_qcount)) {
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
+ add_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -63,7 +69,7 @@ static int rxrpc_krxiod(void *arg)
schedule();
}
- remove_wait_queue(&rxrpc_krxiod_sleepq,&krxiod);
+ remove_wait_queue(&rxrpc_krxiod_sleepq, &krxiod);
set_current_state(TASK_RUNNING);
}
_debug("### End Wait");
@@ -78,12 +84,16 @@ static int rxrpc_krxiod(void *arg)
spin_lock_irq(&rxrpc_krxiod_transportq_lock);
if (!list_empty(&rxrpc_krxiod_transportq)) {
- trans = list_entry(rxrpc_krxiod_transportq.next,
- struct rxrpc_transport,krxiodq_link);
+ trans = list_entry(
+ rxrpc_krxiod_transportq.next,
+ struct rxrpc_transport,
+ krxiodq_link);
+
list_del_init(&trans->krxiodq_link);
atomic_dec(&rxrpc_krxiod_qcount);
- /* make sure it hasn't gone away and doesn't go away */
+ /* make sure it hasn't gone away and doesn't go
+ * away */
if (atomic_read(&trans->usage)>0)
rxrpc_get_transport(trans);
else
@@ -106,13 +116,16 @@ static int rxrpc_krxiod(void *arg)
if (!list_empty(&rxrpc_krxiod_callq)) {
call = list_entry(rxrpc_krxiod_callq.next,
- struct rxrpc_call,rcv_krxiodq_lk);
+ struct rxrpc_call,
+ rcv_krxiodq_lk);
list_del_init(&call->rcv_krxiodq_lk);
atomic_dec(&rxrpc_krxiod_qcount);
- /* make sure it hasn't gone away and doesn't go away */
- if (atomic_read(&call->usage)>0) {
- _debug("@@@ KRXIOD Begin Attend Call %p",call);
+ /* make sure it hasn't gone away and doesn't go
+ * away */
+ if (atomic_read(&call->usage) > 0) {
+ _debug("@@@ KRXIOD"
+ " Begin Attend Call %p",call);
rxrpc_get_call(call);
}
else {
@@ -125,7 +138,7 @@ static int rxrpc_krxiod(void *arg)
if (call) {
rxrpc_call_do_stuff(call);
rxrpc_put_call(call);
- _debug("@@@ KRXIOD End Attend Call %p",call);
+ _debug("@@@ KRXIOD End Attend Call %p", call);
}
}
@@ -137,7 +150,7 @@ static int rxrpc_krxiod(void *arg)
} while (!rxrpc_krxiod_die);
/* and that's all */
- complete_and_exit(&rxrpc_krxiod_dead,0);
+ complete_and_exit(&rxrpc_krxiod_dead, 0);
} /* end rxrpc_krxiod() */
@@ -147,7 +160,7 @@ static int rxrpc_krxiod(void *arg)
*/
int __init rxrpc_krxiod_init(void)
{
- return kernel_thread(rxrpc_krxiod,NULL,0);
+ return kernel_thread(rxrpc_krxiod, NULL, 0);
} /* end rxrpc_krxiod_init() */
@@ -174,16 +187,17 @@ void rxrpc_krxiod_queue_transport(struct rxrpc_transport *trans)
_enter("");
if (list_empty(&trans->krxiodq_link)) {
- spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
+ spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
if (list_empty(&trans->krxiodq_link)) {
- if (atomic_read(&trans->usage)>0) {
- list_add_tail(&trans->krxiodq_link,&rxrpc_krxiod_transportq);
+ if (atomic_read(&trans->usage) > 0) {
+ list_add_tail(&trans->krxiodq_link,
+ &rxrpc_krxiod_transportq);
atomic_inc(&rxrpc_krxiod_qcount);
}
}
- spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
+ spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
wake_up_all(&rxrpc_krxiod_sleepq);
}
@@ -201,12 +215,12 @@ void rxrpc_krxiod_dequeue_transport(struct rxrpc_transport *trans)
_enter("");
- spin_lock_irqsave(&rxrpc_krxiod_transportq_lock,flags);
+ spin_lock_irqsave(&rxrpc_krxiod_transportq_lock, flags);
if (!list_empty(&trans->krxiodq_link)) {
list_del_init(&trans->krxiodq_link);
atomic_dec(&rxrpc_krxiod_qcount);
}
- spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock,flags);
+ spin_unlock_irqrestore(&rxrpc_krxiod_transportq_lock, flags);
_leave("");
@@ -221,15 +235,16 @@ void rxrpc_krxiod_queue_call(struct rxrpc_call *call)
unsigned long flags;
if (list_empty(&call->rcv_krxiodq_lk)) {
- spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
- if (atomic_read(&call->usage)>0) {
- list_add_tail(&call->rcv_krxiodq_lk,&rxrpc_krxiod_callq);
+ spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
+ if (atomic_read(&call->usage) > 0) {
+ list_add_tail(&call->rcv_krxiodq_lk,
+ &rxrpc_krxiod_callq);
atomic_inc(&rxrpc_krxiod_qcount);
}
- spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
+ spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
}
wake_up_all(&rxrpc_krxiod_sleepq);
-
+
} /* end rxrpc_krxiod_queue_call() */
/*****************************************************************************/
@@ -240,11 +255,11 @@ void rxrpc_krxiod_dequeue_call(struct rxrpc_call *call)
{
unsigned long flags;
- spin_lock_irqsave(&rxrpc_krxiod_callq_lock,flags);
+ spin_lock_irqsave(&rxrpc_krxiod_callq_lock, flags);
if (!list_empty(&call->rcv_krxiodq_lk)) {
list_del_init(&call->rcv_krxiodq_lk);
atomic_dec(&rxrpc_krxiod_qcount);
}
- spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock,flags);
+ spin_unlock_irqrestore(&rxrpc_krxiod_callq_lock, flags);
} /* end rxrpc_krxiod_dequeue_call() */
diff --git a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
index 02f0e2bd9055..81c0b73ab6f5 100644
--- a/net/rxrpc/krxsecd.c
+++ b/net/rxrpc/krxsecd.c
@@ -36,7 +36,8 @@ static volatile int rxrpc_krxsecd_die;
static atomic_t rxrpc_krxsecd_qcount;
-/* queue of unprocessed inbound messages with seqno #1 and RXRPC_CLIENT_INITIATED flag set */
+/* queue of unprocessed inbound messages with seqno #1 and
+ * RXRPC_CLIENT_INITIATED flag set */
static LIST_HEAD(rxrpc_krxsecd_initmsgq);
static spinlock_t rxrpc_krxsecd_initmsgq_lock = SPIN_LOCK_UNLOCKED;
@@ -48,14 +49,20 @@ static void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg);
*/
static int rxrpc_krxsecd(void *arg)
{
- DECLARE_WAITQUEUE(krxsecd,current);
+ DECLARE_WAITQUEUE(krxsecd, current);
int die;
- printk("Started krxsecd %d\n",current->pid);
+ printk("Started krxsecd %d\n", current->pid);
daemonize("krxsecd");
+ /* only certain signals are of interest */
+ spin_lock_irq(&current->sighand->siglock);
+ siginitsetinv(&current->blocked, 0);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
/* loop around waiting for work to do */
do {
/* wait for work or to be told to exit */
@@ -63,7 +70,7 @@ static int rxrpc_krxsecd(void *arg)
if (!atomic_read(&rxrpc_krxsecd_qcount)) {
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
+ add_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -75,7 +82,7 @@ static int rxrpc_krxsecd(void *arg)
schedule();
}
- remove_wait_queue(&rxrpc_krxsecd_sleepq,&krxsecd);
+ remove_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
set_current_state(TASK_RUNNING);
}
die = rxrpc_krxsecd_die;
@@ -91,7 +98,7 @@ static int rxrpc_krxsecd(void *arg)
if (!list_empty(&rxrpc_krxsecd_initmsgq)) {
msg = list_entry(rxrpc_krxsecd_initmsgq.next,
- struct rxrpc_message,link);
+ struct rxrpc_message, link);
list_del_init(&msg->link);
atomic_dec(&rxrpc_krxsecd_qcount);
}
@@ -112,7 +119,7 @@ static int rxrpc_krxsecd(void *arg)
} while (!die);
/* and that's all */
- complete_and_exit(&rxrpc_krxsecd_dead,0);
+ complete_and_exit(&rxrpc_krxsecd_dead, 0);
} /* end rxrpc_krxsecd() */
@@ -122,7 +129,7 @@ static int rxrpc_krxsecd(void *arg)
*/
int __init rxrpc_krxsecd_init(void)
{
- return kernel_thread(rxrpc_krxsecd,NULL,0);
+ return kernel_thread(rxrpc_krxsecd, NULL, 0);
} /* end rxrpc_krxsecd_init() */
@@ -154,11 +161,11 @@ void rxrpc_krxsecd_clear_transport(struct rxrpc_transport *trans)
/* move all the messages for this transport onto a temp list */
spin_lock(&rxrpc_krxsecd_initmsgq_lock);
- list_for_each_safe(_p,_n,&rxrpc_krxsecd_initmsgq) {
- msg = list_entry(_p,struct rxrpc_message,link);
- if (msg->trans==trans) {
+ list_for_each_safe(_p, _n, &rxrpc_krxsecd_initmsgq) {
+ msg = list_entry(_p, struct rxrpc_message, link);
+ if (msg->trans == trans) {
list_del(&msg->link);
- list_add_tail(&msg->link,&tmp);
+ list_add_tail(&msg->link, &tmp);
atomic_dec(&rxrpc_krxsecd_qcount);
}
}
@@ -167,7 +174,7 @@ void rxrpc_krxsecd_clear_transport(struct rxrpc_transport *trans)
/* zap all messages on the temp list */
while (!list_empty(&tmp)) {
- msg = list_entry(tmp.next,struct rxrpc_message,link);
+ msg = list_entry(tmp.next, struct rxrpc_message, link);
list_del_init(&msg->link);
rxrpc_put_message(msg);
}
@@ -181,14 +188,14 @@ void rxrpc_krxsecd_clear_transport(struct rxrpc_transport *trans)
*/
void rxrpc_krxsecd_queue_incoming_call(struct rxrpc_message *msg)
{
- _enter("%p",msg);
+ _enter("%p", msg);
/* queue for processing by krxsecd */
spin_lock(&rxrpc_krxsecd_initmsgq_lock);
if (!rxrpc_krxsecd_die) {
rxrpc_get_message(msg);
- list_add_tail(&msg->link,&rxrpc_krxsecd_initmsgq);
+ list_add_tail(&msg->link, &rxrpc_krxsecd_initmsgq);
atomic_inc(&rxrpc_krxsecd_qcount);
}
@@ -212,10 +219,10 @@ void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg)
unsigned short sid;
int ret;
- _enter("%p{tr=%p}",msg,trans);
+ _enter("%p{tr=%p}", msg, trans);
- ret = rxrpc_incoming_call(msg->conn,msg,&call);
- if (ret<0)
+ ret = rxrpc_incoming_call(msg->conn, msg, &call);
+ if (ret < 0)
goto out;
/* find the matching service on the transport */
@@ -223,11 +230,11 @@ void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg)
srv = NULL;
spin_lock(&trans->lock);
- list_for_each(_p,&trans->services) {
- srv = list_entry(_p,struct rxrpc_service,link);
- if (srv->service_id==sid && try_module_get(srv->owner)) {
+ list_for_each(_p, &trans->services) {
+ srv = list_entry(_p, struct rxrpc_service, link);
+ if (srv->service_id == sid && try_module_get(srv->owner)) {
/* found a match (made sure it won't vanish) */
- _debug("found service '%s'",srv->name);
+ _debug("found service '%s'", srv->name);
call->owner = srv->owner;
break;
}
@@ -238,7 +245,7 @@ void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg)
* - the func must inc the call's usage count to keep it
*/
ret = -ENOENT;
- if (_p!=&trans->services) {
+ if (_p != &trans->services) {
/* attempt to accept the call */
call->conn->service = srv;
call->app_attn_func = srv->attn_func;
@@ -248,19 +255,20 @@ void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg)
ret = srv->new_call(call);
/* send an abort if an error occurred */
- if (ret<0) {
- rxrpc_call_abort(call,ret);
+ if (ret < 0) {
+ rxrpc_call_abort(call, ret);
}
else {
/* formally receive and ACK the new packet */
- ret = rxrpc_conn_receive_call_packet(call->conn,call,msg);
+ ret = rxrpc_conn_receive_call_packet(call->conn,
+ call, msg);
}
}
rxrpc_put_call(call);
out:
- if (ret<0)
- rxrpc_trans_immediate_abort(trans,msg,ret);
+ if (ret < 0)
+ rxrpc_trans_immediate_abort(trans, msg, ret);
- _leave(" (%d)",ret);
+ _leave(" (%d)", ret);
} /* end rxrpc_krxsecd_process_incoming_call() */
diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
index e8e86446a156..68ea67bf9623 100644
--- a/net/rxrpc/krxtimod.c
+++ b/net/rxrpc/krxtimod.c
@@ -36,8 +36,8 @@ int rxrpc_krxtimod_start(void)
{
int ret;
- ret = kernel_thread(krxtimod,NULL,0);
- if (ret<0)
+ ret = kernel_thread(krxtimod, NULL, 0);
+ if (ret < 0)
return ret;
wait_for_completion(&krxtimod_alive);
@@ -64,30 +64,36 @@ void rxrpc_krxtimod_kill(void)
*/
static int krxtimod(void *arg)
{
- DECLARE_WAITQUEUE(myself,current);
+ DECLARE_WAITQUEUE(myself, current);
rxrpc_timer_t *timer;
- printk("Started krxtimod %d\n",current->pid);
+ printk("Started krxtimod %d\n", current->pid);
daemonize("krxtimod");
complete(&krxtimod_alive);
+ /* only certain signals are of interest */
+ spin_lock_irq(&current->sighand->siglock);
+ siginitsetinv(&current->blocked, 0);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
/* loop around looking for things to attend to */
loop:
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&krxtimod_sleepq,&myself);
+ add_wait_queue(&krxtimod_sleepq, &myself);
for (;;) {
unsigned long jif;
- unsigned long timeout;
+ signed long timeout;
/* deal with the server being asked to die */
if (krxtimod_die) {
- remove_wait_queue(&krxtimod_sleepq,&myself);
+ remove_wait_queue(&krxtimod_sleepq, &myself);
_leave("");
- complete_and_exit(&krxtimod_dead,0);
+ complete_and_exit(&krxtimod_dead, 0);
}
/* discard pending signals */
@@ -97,18 +103,19 @@ static int krxtimod(void *arg)
spin_lock(&krxtimod_lock);
if (list_empty(&krxtimod_list)) {
timeout = MAX_SCHEDULE_TIMEOUT;
- } else {
- unsigned long tmo;
-
+ }
+ else {
timer = list_entry(krxtimod_list.next,
rxrpc_timer_t, link);
- tmo = timer->timo_jif;
+ timeout = timer->timo_jif;
jif = jiffies;
- if (time_before_eq(tmo,jif))
+ if (time_before_eq((unsigned long) timeout, jif))
goto immediate;
- timeout = (long)tmo - (long)jiffies;
+ else {
+ timeout = (long) timeout - (long) jiffies;
+ }
}
spin_unlock(&krxtimod_lock);
@@ -118,13 +125,14 @@ static int krxtimod(void *arg)
}
/* the thing on the front of the queue needs processing
- * - we come here with the lock held and timer pointing to the expired entry
+ * - we come here with the lock held and timer pointing to the expired
+ * entry
*/
immediate:
- remove_wait_queue(&krxtimod_sleepq,&myself);
+ remove_wait_queue(&krxtimod_sleepq, &myself);
set_current_state(TASK_RUNNING);
- _debug("@@@ Begin Timeout of %p",timer);
+ _debug("@@@ Begin Timeout of %p", timer);
/* dequeue the timer */
list_del_init(&timer->link);
@@ -147,29 +155,30 @@ void rxrpc_krxtimod_add_timer(rxrpc_timer_t *timer, unsigned long timeout)
struct list_head *_p;
rxrpc_timer_t *ptimer;
- _enter("%p,%lu",timer,timeout);
+ _enter("%p,%lu", timer, timeout);
spin_lock(&krxtimod_lock);
list_del(&timer->link);
- /* the timer was deferred or reset - put it back in the queue at the right place */
+ /* the timer was deferred or reset - put it back in the queue at the
+ * right place */
timer->timo_jif = jiffies + timeout;
- list_for_each(_p,&krxtimod_list) {
- ptimer = list_entry(_p,rxrpc_timer_t,link);
- if (time_before(timer->timo_jif,ptimer->timo_jif))
+ list_for_each(_p, &krxtimod_list) {
+ ptimer = list_entry(_p, rxrpc_timer_t, link);
+ if (time_before(timer->timo_jif, ptimer->timo_jif))
break;
}
- list_add_tail(&timer->link,_p); /* insert before stopping point */
+ list_add_tail(&timer->link, _p); /* insert before stopping point */
spin_unlock(&krxtimod_lock);
wake_up(&krxtimod_sleepq);
_leave("");
-} /* end rxrpc_krxtimod_queue_vlocation() */
+} /* end rxrpc_krxtimod_add_timer() */
/*****************************************************************************/
/*
@@ -180,7 +189,7 @@ int rxrpc_krxtimod_del_timer(rxrpc_timer_t *timer)
{
int ret = 0;
- _enter("%p",timer);
+ _enter("%p", timer);
spin_lock(&krxtimod_lock);
@@ -193,6 +202,6 @@ int rxrpc_krxtimod_del_timer(rxrpc_timer_t *timer)
wake_up(&krxtimod_sleepq);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_krxtimod_del_timer() */
diff --git a/net/rxrpc/main.c b/net/rxrpc/main.c
index 7da19a903817..21623a90b6e5 100644
--- a/net/rxrpc/main.c
+++ b/net/rxrpc/main.c
@@ -32,7 +32,7 @@ MODULE_DESCRIPTION("Rx RPC implementation");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
-u32 rxrpc_epoch;
+uint32_t rxrpc_epoch;
/*****************************************************************************/
/*
@@ -101,11 +101,16 @@ static void __exit rxrpc_cleanup(void)
{
kenter("");
- __RXACCT(printk("Outstanding Messages : %d\n",atomic_read(&rxrpc_message_count)));
- __RXACCT(printk("Outstanding Calls : %d\n",atomic_read(&rxrpc_call_count)));
- __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
- __RXACCT(printk("Outstanding Peers : %d\n",atomic_read(&rxrpc_peer_count)));
- __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
+ __RXACCT(printk("Outstanding Messages : %d\n",
+ atomic_read(&rxrpc_message_count)));
+ __RXACCT(printk("Outstanding Calls : %d\n",
+ atomic_read(&rxrpc_call_count)));
+ __RXACCT(printk("Outstanding Connections: %d\n",
+ atomic_read(&rxrpc_connection_count)));
+ __RXACCT(printk("Outstanding Peers : %d\n",
+ atomic_read(&rxrpc_peer_count)));
+ __RXACCT(printk("Outstanding Transports : %d\n",
+ atomic_read(&rxrpc_transport_count)));
rxrpc_krxsecd_kill();
rxrpc_krxiod_kill();
@@ -117,11 +122,61 @@ static void __exit rxrpc_cleanup(void)
rxrpc_proc_cleanup();
#endif
- __RXACCT(printk("Outstanding Messages : %d\n",atomic_read(&rxrpc_message_count)));
- __RXACCT(printk("Outstanding Calls : %d\n",atomic_read(&rxrpc_call_count)));
- __RXACCT(printk("Outstanding Connections: %d\n",atomic_read(&rxrpc_connection_count)));
- __RXACCT(printk("Outstanding Peers : %d\n",atomic_read(&rxrpc_peer_count)));
- __RXACCT(printk("Outstanding Transports : %d\n",atomic_read(&rxrpc_transport_count)));
+ __RXACCT(printk("Outstanding Messages : %d\n",
+ atomic_read(&rxrpc_message_count)));
+ __RXACCT(printk("Outstanding Calls : %d\n",
+ atomic_read(&rxrpc_call_count)));
+ __RXACCT(printk("Outstanding Connections: %d\n",
+ atomic_read(&rxrpc_connection_count)));
+ __RXACCT(printk("Outstanding Peers : %d\n",
+ atomic_read(&rxrpc_peer_count)));
+ __RXACCT(printk("Outstanding Transports : %d\n",
+ atomic_read(&rxrpc_transport_count)));
kleave("");
} /* end rxrpc_cleanup() */
+
+/*****************************************************************************/
+/*
+ * clear the dead space between task_struct and kernel stack
+ * - called by supplying -finstrument-functions to gcc
+ */
+#if 0
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_enter (void *this_fn, void *call_site)
+{
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xedededed,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+__attribute__((no_instrument_function));
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+{
+ asm volatile(" movl %%esp,%%edi \n"
+ " andl %0,%%edi \n"
+ " addl %1,%%edi \n"
+ " movl %%esp,%%ecx \n"
+ " subl %%edi,%%ecx \n"
+ " shrl $2,%%ecx \n"
+ " movl $0xdadadada,%%eax \n"
+ " rep stosl \n"
+ :
+ : "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info))
+ : "eax", "ecx", "edi", "memory", "cc"
+ );
+}
+#endif
diff --git a/net/rxrpc/peer.c b/net/rxrpc/peer.c
index edd98149e628..a0665d6298e9 100644
--- a/net/rxrpc/peer.c
+++ b/net/rxrpc/peer.c
@@ -28,12 +28,14 @@
__RXACCT_DECL(atomic_t rxrpc_peer_count);
LIST_HEAD(rxrpc_peers);
DECLARE_RWSEM(rxrpc_peers_sem);
+unsigned long rxrpc_peer_timeout = 12 * 60 * 60;
static void __rxrpc_peer_timeout(rxrpc_timer_t *timer)
{
- struct rxrpc_peer *peer = list_entry(timer,struct rxrpc_peer,timeout);
+ struct rxrpc_peer *peer =
+ list_entry(timer, struct rxrpc_peer, timeout);
- _debug("Rx PEER TIMEOUT [%p{u=%d}]",peer,atomic_read(&peer->usage));
+ _debug("Rx PEER TIMEOUT [%p{u=%d}]", peer, atomic_read(&peer->usage));
rxrpc_peer_do_timeout(peer);
}
@@ -46,32 +48,35 @@ static const struct rxrpc_timer_ops rxrpc_peer_timer_ops = {
/*
* create a peer record
*/
-static int __rxrpc_create_peer(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
+static int __rxrpc_create_peer(struct rxrpc_transport *trans, uint32_t addr,
+ struct rxrpc_peer **_peer)
{
struct rxrpc_peer *peer;
- _enter("%p,%08x",trans,ntohl(addr));
+ _enter("%p,%08x", trans, ntohl(addr));
/* allocate and initialise a peer record */
- peer = kmalloc(sizeof(struct rxrpc_peer),GFP_KERNEL);
+ peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL);
if (!peer) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
- memset(peer,0,sizeof(struct rxrpc_peer));
- atomic_set(&peer->usage,1);
+ memset(peer, 0, sizeof(struct rxrpc_peer));
+ atomic_set(&peer->usage, 1);
INIT_LIST_HEAD(&peer->link);
INIT_LIST_HEAD(&peer->proc_link);
+ INIT_LIST_HEAD(&peer->conn_idlist);
INIT_LIST_HEAD(&peer->conn_active);
INIT_LIST_HEAD(&peer->conn_graveyard);
spin_lock_init(&peer->conn_gylock);
init_waitqueue_head(&peer->conn_gy_waitq);
+ rwlock_init(&peer->conn_idlock);
rwlock_init(&peer->conn_lock);
- atomic_set(&peer->conn_count,0);
+ atomic_set(&peer->conn_count, 0);
spin_lock_init(&peer->lock);
- rxrpc_timer_init(&peer->timeout,&rxrpc_peer_timer_ops);
+ rxrpc_timer_init(&peer->timeout, &rxrpc_peer_timer_ops);
peer->addr.s_addr = addr;
@@ -80,7 +85,7 @@ static int __rxrpc_create_peer(struct rxrpc_transport *trans, u32 addr, struct r
__RXACCT(atomic_inc(&rxrpc_peer_count));
*_peer = peer;
- _leave(" = 0 (%p)",peer);
+ _leave(" = 0 (%p)", peer);
return 0;
} /* end __rxrpc_create_peer() */
@@ -91,43 +96,45 @@ static int __rxrpc_create_peer(struct rxrpc_transport *trans, u32 addr, struct r
* - returns (if successful) with peer record usage incremented
* - resurrects it from the graveyard if found there
*/
-int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer **_peer)
+int rxrpc_peer_lookup(struct rxrpc_transport *trans, uint32_t addr,
+ struct rxrpc_peer **_peer)
{
struct rxrpc_peer *peer, *candidate = NULL;
struct list_head *_p;
int ret;
- _enter("%p{%hu},%08x",trans,trans->port,ntohl(addr));
+ _enter("%p{%hu},%08x", trans, trans->port, ntohl(addr));
/* [common case] search the transport's active list first */
read_lock(&trans->peer_lock);
- list_for_each(_p,&trans->peer_active) {
- peer = list_entry(_p,struct rxrpc_peer,link);
- if (peer->addr.s_addr==addr)
+ list_for_each(_p, &trans->peer_active) {
+ peer = list_entry(_p, struct rxrpc_peer, link);
+ if (peer->addr.s_addr == addr)
goto found_active;
}
read_unlock(&trans->peer_lock);
/* [uncommon case] not active - create a candidate for a new record */
- ret = __rxrpc_create_peer(trans,addr,&candidate);
- if (ret<0) {
- _leave(" = %d",ret);
+ ret = __rxrpc_create_peer(trans, addr, &candidate);
+ if (ret < 0) {
+ _leave(" = %d", ret);
return ret;
}
- /* search the active list again, just in case it appeared whilst we were busy */
+ /* search the active list again, just in case it appeared whilst we
+ * were busy */
write_lock(&trans->peer_lock);
- list_for_each(_p,&trans->peer_active) {
- peer = list_entry(_p,struct rxrpc_peer,link);
- if (peer->addr.s_addr==addr)
+ list_for_each(_p, &trans->peer_active) {
+ peer = list_entry(_p, struct rxrpc_peer, link);
+ if (peer->addr.s_addr == addr)
goto found_active_second_chance;
}
/* search the transport's graveyard list */
spin_lock(&trans->peer_gylock);
- list_for_each(_p,&trans->peer_graveyard) {
- peer = list_entry(_p,struct rxrpc_peer,link);
- if (peer->addr.s_addr==addr)
+ list_for_each(_p, &trans->peer_graveyard) {
+ peer = list_entry(_p, struct rxrpc_peer, link);
+ if (peer->addr.s_addr == addr)
goto found_in_graveyard;
}
spin_unlock(&trans->peer_gylock);
@@ -141,12 +148,12 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
if (peer->ops && peer->ops->adding) {
ret = peer->ops->adding(peer);
- if (ret<0) {
+ if (ret < 0) {
write_unlock(&trans->peer_lock);
__RXACCT(atomic_dec(&rxrpc_peer_count));
kfree(peer);
rxrpc_put_transport(trans);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
}
}
@@ -154,7 +161,7 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
atomic_inc(&trans->peer_count);
make_active:
- list_add_tail(&peer->link,&trans->peer_active);
+ list_add_tail(&peer->link, &trans->peer_active);
success_uwfree:
write_unlock(&trans->peer_lock);
@@ -166,7 +173,7 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
if (list_empty(&peer->proc_link)) {
down_write(&rxrpc_peers_sem);
- list_add_tail(&peer->proc_link,&rxrpc_peers);
+ list_add_tail(&peer->proc_link, &rxrpc_peers);
up_write(&rxrpc_peers_sem);
}
@@ -174,7 +181,9 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
*_peer = peer;
_leave(" = 0 (%p{u=%d cc=%d})",
- peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count));
+ peer,
+ atomic_read(&peer->usage),
+ atomic_read(&peer->conn_count));
return 0;
/* handle the peer being found in the active list straight off */
@@ -192,7 +201,8 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
spin_unlock(&trans->peer_gylock);
goto make_active;
- /* handle finding the peer on the second time through the active list */
+ /* handle finding the peer on the second time through the active
+ * list */
found_active_second_chance:
rxrpc_get_peer(peer);
goto success_uwfree;
@@ -202,16 +212,20 @@ int rxrpc_peer_lookup(struct rxrpc_transport *trans, u32 addr, struct rxrpc_peer
/*****************************************************************************/
/*
* finish with a peer record
- * - it gets sent to the graveyard from where it can be resurrected or timed out
+ * - it gets sent to the graveyard from where it can be resurrected or timed
+ * out
*/
void rxrpc_put_peer(struct rxrpc_peer *peer)
{
struct rxrpc_transport *trans = peer->trans;
- _enter("%p{cc=%d a=%08x}",peer,atomic_read(&peer->conn_count),ntohl(peer->addr.s_addr));
+ _enter("%p{cc=%d a=%08x}",
+ peer,
+ atomic_read(&peer->conn_count),
+ ntohl(peer->addr.s_addr));
/* sanity check */
- if (atomic_read(&peer->usage)<=0)
+ if (atomic_read(&peer->usage) <= 0)
BUG();
write_lock(&trans->peer_lock);
@@ -227,12 +241,11 @@ void rxrpc_put_peer(struct rxrpc_peer *peer)
list_del(&peer->link);
write_unlock(&trans->peer_lock);
- list_add_tail(&peer->link,&trans->peer_graveyard);
+ list_add_tail(&peer->link, &trans->peer_graveyard);
- if (!list_empty(&peer->conn_active)) BUG();
+ BUG_ON(!list_empty(&peer->conn_active));
- /* discard in 600 secs */
- rxrpc_krxtimod_add_timer(&peer->timeout,100*HZ);
+ rxrpc_krxtimod_add_timer(&peer->timeout, rxrpc_peer_timeout * HZ);
spin_unlock(&trans->peer_gylock);
@@ -251,15 +264,16 @@ void rxrpc_peer_do_timeout(struct rxrpc_peer *peer)
struct rxrpc_transport *trans = peer->trans;
_enter("%p{u=%d cc=%d a=%08x}",
- peer,atomic_read(&peer->usage),atomic_read(&peer->conn_count),
+ peer,
+ atomic_read(&peer->usage),
+ atomic_read(&peer->conn_count),
ntohl(peer->addr.s_addr));
- if (atomic_read(&peer->usage)<0)
- BUG();
+ BUG_ON(atomic_read(&peer->usage) < 0);
/* remove from graveyard if still dead */
spin_lock(&trans->peer_gylock);
- if (atomic_read(&peer->usage)==0)
+ if (atomic_read(&peer->usage) == 0)
list_del_init(&peer->link);
else
peer = NULL;
@@ -273,8 +287,8 @@ void rxrpc_peer_do_timeout(struct rxrpc_peer *peer)
/* clear all connections on this peer */
rxrpc_conn_clearall(peer);
- if (!list_empty(&peer->conn_active)) BUG();
- if (!list_empty(&peer->conn_graveyard)) BUG();
+ BUG_ON(!list_empty(&peer->conn_active));
+ BUG_ON(!list_empty(&peer->conn_graveyard));
/* inform the application layer */
if (peer->ops && peer->ops->discarding)
@@ -310,18 +324,18 @@ void rxrpc_peer_clearall(struct rxrpc_transport *trans)
_enter("%p",trans);
/* there shouldn't be any active peers remaining */
- if (!list_empty(&trans->peer_active))
- BUG();
+ BUG_ON(!list_empty(&trans->peer_active));
/* manually timeout all peers in the graveyard */
spin_lock(&trans->peer_gylock);
while (!list_empty(&trans->peer_graveyard)) {
- peer = list_entry(trans->peer_graveyard.next,struct rxrpc_peer,link);
- _debug("Clearing peer %p\n",peer);
+ peer = list_entry(trans->peer_graveyard.next,
+ struct rxrpc_peer, link);
+ _debug("Clearing peer %p\n", peer);
err = rxrpc_krxtimod_del_timer(&peer->timeout);
spin_unlock(&trans->peer_gylock);
- if (err==0)
+ if (err == 0)
rxrpc_peer_do_timeout(peer);
spin_lock(&trans->peer_gylock);
@@ -330,18 +344,17 @@ void rxrpc_peer_clearall(struct rxrpc_transport *trans)
/* wait for the the peer graveyard to be completely cleared */
set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&trans->peer_gy_waitq,&myself);
+ add_wait_queue(&trans->peer_gy_waitq, &myself);
- while (atomic_read(&trans->peer_count)!=0) {
+ while (atomic_read(&trans->peer_count) != 0) {
schedule();
set_current_state(TASK_UNINTERRUPTIBLE);
}
- remove_wait_queue(&trans->peer_gy_waitq,&myself);
+ remove_wait_queue(&trans->peer_gy_waitq, &myself);
set_current_state(TASK_RUNNING);
_leave("");
-
} /* end rxrpc_peer_clearall() */
/*****************************************************************************/
@@ -355,7 +368,7 @@ void rxrpc_peer_calculate_rtt(struct rxrpc_peer *peer,
unsigned long long rtt;
int loop;
- _enter("%p,%p,%p",peer,msg,resp);
+ _enter("%p,%p,%p", peer, msg, resp);
/* calculate the latest RTT */
rtt = resp->stamp.tv_sec - msg->stamp.tv_sec;
@@ -367,16 +380,18 @@ void rxrpc_peer_calculate_rtt(struct rxrpc_peer *peer,
peer->rtt_point++;
peer->rtt_point %= RXRPC_RTT_CACHE_SIZE;
- if (peer->rtt_usage<RXRPC_RTT_CACHE_SIZE) peer->rtt_usage++;
+ if (peer->rtt_usage < RXRPC_RTT_CACHE_SIZE)
+ peer->rtt_usage++;
/* recalculate RTT */
rtt = 0;
- for (loop=peer->rtt_usage-1; loop>=0; loop--)
+ for (loop = peer->rtt_usage - 1; loop >= 0; loop--)
rtt += peer->rtt_cache[loop];
- do_div(rtt,peer->rtt_usage);
+ do_div(rtt, peer->rtt_usage);
peer->rtt = rtt;
- _leave(" RTT=%lu.%lums",(long)(peer->rtt/1000),(long)(peer->rtt%1000));
+ _leave(" RTT=%lu.%lums",
+ (long) (peer->rtt / 1000), (long) (peer->rtt % 1000));
} /* end rxrpc_peer_calculate_rtt() */
diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index e9d979fc4eb0..0427b5f227a2 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -38,7 +38,6 @@ static struct seq_operations rxrpc_proc_transports_ops = {
};
static struct file_operations rxrpc_proc_transports_fops = {
- .owner = THIS_MODULE,
.open = rxrpc_proc_transports_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -59,7 +58,6 @@ static struct seq_operations rxrpc_proc_peers_ops = {
};
static struct file_operations rxrpc_proc_peers_fops = {
- .owner = THIS_MODULE,
.open = rxrpc_proc_peers_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -80,7 +78,6 @@ static struct seq_operations rxrpc_proc_conns_ops = {
};
static struct file_operations rxrpc_proc_conns_fops = {
- .owner = THIS_MODULE,
.open = rxrpc_proc_conns_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -101,7 +98,6 @@ static struct seq_operations rxrpc_proc_calls_ops = {
};
static struct file_operations rxrpc_proc_calls_fops = {
- .owner = THIS_MODULE,
.open = rxrpc_proc_calls_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -137,30 +133,30 @@ int rxrpc_proc_init(void)
{
struct proc_dir_entry *p;
- proc_rxrpc = proc_mkdir("rxrpc",proc_net);
+ proc_rxrpc = proc_mkdir("rxrpc", proc_net);
if (!proc_rxrpc)
goto error;
proc_rxrpc->owner = THIS_MODULE;
- p = create_proc_entry("calls",0,proc_rxrpc);
+ p = create_proc_entry("calls", 0, proc_rxrpc);
if (!p)
goto error_proc;
p->proc_fops = &rxrpc_proc_calls_fops;
p->owner = THIS_MODULE;
- p = create_proc_entry("connections",0,proc_rxrpc);
+ p = create_proc_entry("connections", 0, proc_rxrpc);
if (!p)
goto error_calls;
p->proc_fops = &rxrpc_proc_conns_fops;
p->owner = THIS_MODULE;
- p = create_proc_entry("peers",0,proc_rxrpc);
+ p = create_proc_entry("peers", 0, proc_rxrpc);
if (!p)
goto error_calls;
p->proc_fops = &rxrpc_proc_peers_fops;
p->owner = THIS_MODULE;
- p = create_proc_entry("transports",0,proc_rxrpc);
+ p = create_proc_entry("transports", 0, proc_rxrpc);
if (!p)
goto error_conns;
p->proc_fops = &rxrpc_proc_transports_fops;
@@ -169,11 +165,11 @@ int rxrpc_proc_init(void)
return 0;
error_conns:
- remove_proc_entry("conns",proc_rxrpc);
+ remove_proc_entry("connections", proc_rxrpc);
error_calls:
- remove_proc_entry("calls",proc_rxrpc);
+ remove_proc_entry("calls", proc_rxrpc);
error_proc:
- remove_proc_entry("rxrpc",proc_net);
+ remove_proc_entry("rxrpc", proc_net);
error:
return -ENOMEM;
} /* end rxrpc_proc_init() */
@@ -184,12 +180,12 @@ int rxrpc_proc_init(void)
*/
void rxrpc_proc_cleanup(void)
{
- remove_proc_entry("transports",proc_rxrpc);
- remove_proc_entry("peers",proc_rxrpc);
- remove_proc_entry("connections",proc_rxrpc);
- remove_proc_entry("calls",proc_rxrpc);
+ remove_proc_entry("transports", proc_rxrpc);
+ remove_proc_entry("peers", proc_rxrpc);
+ remove_proc_entry("connections", proc_rxrpc);
+ remove_proc_entry("calls", proc_rxrpc);
- remove_proc_entry("rxrpc",proc_net);
+ remove_proc_entry("rxrpc", proc_net);
} /* end rxrpc_proc_cleanup() */
@@ -202,8 +198,8 @@ static int rxrpc_proc_transports_open(struct inode *inode, struct file *file)
struct seq_file *m;
int ret;
- ret = seq_open(file,&rxrpc_proc_transports_ops);
- if (ret<0)
+ ret = seq_open(file, &rxrpc_proc_transports_ops);
+ if (ret < 0)
return ret;
m = file->private_data;
@@ -226,15 +222,15 @@ static void *rxrpc_proc_transports_start(struct seq_file *m, loff_t *_pos)
/* allow for the header line */
if (!pos)
- return (void *)1;
+ return (void *) 1;
pos--;
/* find the n'th element in the list */
- list_for_each(_p,&rxrpc_proc_transports)
+ list_for_each(_p, &rxrpc_proc_transports)
if (!pos--)
break;
- return _p!=&rxrpc_proc_transports ? _p : NULL;
+ return _p != &rxrpc_proc_transports ? _p : NULL;
} /* end rxrpc_proc_transports_start() */
/*****************************************************************************/
@@ -248,9 +244,9 @@ static void *rxrpc_proc_transports_next(struct seq_file *p, void *v, loff_t *pos
(*pos)++;
_p = v;
- _p = v==(void*)1 ? rxrpc_proc_transports.next : _p->next;
+ _p = v==(void *) 1 ? rxrpc_proc_transports.next : _p->next;
- return _p!=&rxrpc_proc_transports ? _p : NULL;
+ return _p != &rxrpc_proc_transports ? _p : NULL;
} /* end rxrpc_proc_transports_next() */
/*****************************************************************************/
@@ -269,16 +265,17 @@ static void rxrpc_proc_transports_stop(struct seq_file *p, void *v)
*/
static int rxrpc_proc_transports_show(struct seq_file *m, void *v)
{
- struct rxrpc_transport *trans = list_entry(v,struct rxrpc_transport,proc_link);
+ struct rxrpc_transport *trans =
+ list_entry(v, struct rxrpc_transport, proc_link);
/* display header on line 1 */
- if (v == (void *)1) {
+ if (v == (void *) 1) {
seq_puts(m, "LOCAL USE\n");
return 0;
}
/* display one transport per line on subsequent lines */
- seq_printf(m,"%5hu %3d\n",
+ seq_printf(m, "%5hu %3d\n",
trans->port,
atomic_read(&trans->usage)
);
@@ -295,8 +292,8 @@ static int rxrpc_proc_peers_open(struct inode *inode, struct file *file)
struct seq_file *m;
int ret;
- ret = seq_open(file,&rxrpc_proc_peers_ops);
- if (ret<0)
+ ret = seq_open(file, &rxrpc_proc_peers_ops);
+ if (ret < 0)
return ret;
m = file->private_data;
@@ -307,7 +304,8 @@ static int rxrpc_proc_peers_open(struct inode *inode, struct file *file)
/*****************************************************************************/
/*
- * set up the iterator to start reading from the peers list and return the first item
+ * set up the iterator to start reading from the peers list and return the
+ * first item
*/
static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos)
{
@@ -319,15 +317,15 @@ static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos)
/* allow for the header line */
if (!pos)
- return (void *)1;
+ return (void *) 1;
pos--;
/* find the n'th element in the list */
- list_for_each(_p,&rxrpc_peers)
+ list_for_each(_p, &rxrpc_peers)
if (!pos--)
break;
- return _p!=&rxrpc_peers ? _p : NULL;
+ return _p != &rxrpc_peers ? _p : NULL;
} /* end rxrpc_proc_peers_start() */
/*****************************************************************************/
@@ -341,9 +339,9 @@ static void *rxrpc_proc_peers_next(struct seq_file *p, void *v, loff_t *pos)
(*pos)++;
_p = v;
- _p = v==(void*)1 ? rxrpc_peers.next : _p->next;
+ _p = v == (void *) 1 ? rxrpc_peers.next : _p->next;
- return _p!=&rxrpc_peers ? _p : NULL;
+ return _p != &rxrpc_peers ? _p : NULL;
} /* end rxrpc_proc_peers_next() */
/*****************************************************************************/
@@ -362,21 +360,23 @@ static void rxrpc_proc_peers_stop(struct seq_file *p, void *v)
*/
static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
{
- struct rxrpc_peer *peer = list_entry(v,struct rxrpc_peer,proc_link);
+ struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
signed long timeout;
/* display header on line 1 */
- if (v == (void *)1) {
- seq_puts(m,"LOCAL REMOTE USAGE CONNS TIMEOUT MTU RTT(uS)\n");
+ if (v == (void *) 1) {
+ seq_puts(m, "LOCAL REMOTE USAGE CONNS TIMEOUT"
+ " MTU RTT(uS)\n");
return 0;
}
/* display one peer per line on subsequent lines */
timeout = 0;
if (!list_empty(&peer->timeout.link))
- timeout = (signed long)peer->timeout.timo_jif - (signed long)jiffies;
+ timeout = (signed long) peer->timeout.timo_jif -
+ (signed long) jiffies;
- seq_printf(m,"%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
+ seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
peer->trans->port,
ntohl(peer->addr.s_addr),
atomic_read(&peer->usage),
@@ -391,15 +391,16 @@ static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
/*****************************************************************************/
/*
- * open "/proc/net/rxrpc/connections" which provides a summary of extant connections
+ * open "/proc/net/rxrpc/connections" which provides a summary of extant
+ * connections
*/
static int rxrpc_proc_conns_open(struct inode *inode, struct file *file)
{
struct seq_file *m;
int ret;
- ret = seq_open(file,&rxrpc_proc_conns_ops);
- if (ret<0)
+ ret = seq_open(file, &rxrpc_proc_conns_ops);
+ if (ret < 0)
return ret;
m = file->private_data;
@@ -410,7 +411,8 @@ static int rxrpc_proc_conns_open(struct inode *inode, struct file *file)
/*****************************************************************************/
/*
- * set up the iterator to start reading from the conns list and return the first item
+ * set up the iterator to start reading from the conns list and return the
+ * first item
*/
static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos)
{
@@ -422,15 +424,15 @@ static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos)
/* allow for the header line */
if (!pos)
- return (void *)1;
+ return (void *) 1;
pos--;
/* find the n'th element in the list */
- list_for_each(_p,&rxrpc_conns)
+ list_for_each(_p, &rxrpc_conns)
if (!pos--)
break;
- return _p!=&rxrpc_conns ? _p : NULL;
+ return _p != &rxrpc_conns ? _p : NULL;
} /* end rxrpc_proc_conns_start() */
/*****************************************************************************/
@@ -444,9 +446,9 @@ static void *rxrpc_proc_conns_next(struct seq_file *p, void *v, loff_t *pos)
(*pos)++;
_p = v;
- _p = v==(void*)1 ? rxrpc_conns.next : _p->next;
+ _p = (v == (void *) 1) ? rxrpc_conns.next : _p->next;
- return _p!=&rxrpc_conns ? _p : NULL;
+ return _p != &rxrpc_conns ? _p : NULL;
} /* end rxrpc_proc_conns_next() */
/*****************************************************************************/
@@ -465,13 +467,16 @@ static void rxrpc_proc_conns_stop(struct seq_file *p, void *v)
*/
static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
{
- struct rxrpc_connection *conn = list_entry(v,struct rxrpc_connection,proc_link);
+ struct rxrpc_connection *conn;
signed long timeout;
+ conn = list_entry(v, struct rxrpc_connection, proc_link);
+
/* display header on line 1 */
- if (v == (void *)1) {
+ if (v == (void *) 1) {
seq_puts(m,
- "LOCAL REMOTE RPORT SRVC CONN END SERIALNO CALLNO MTU TIMEOUT"
+ "LOCAL REMOTE RPORT SRVC CONN END SERIALNO "
+ "CALLNO MTU TIMEOUT"
"\n");
return 0;
}
@@ -479,9 +484,11 @@ static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
/* display one conn per line on subsequent lines */
timeout = 0;
if (!list_empty(&conn->timeout.link))
- timeout = (signed long)conn->timeout.timo_jif - (signed long)jiffies;
+ timeout = (signed long) conn->timeout.timo_jif -
+ (signed long) jiffies;
- seq_printf(m,"%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
+ seq_printf(m,
+ "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
conn->trans->port,
ntohl(conn->addr.sin_addr.s_addr),
ntohs(conn->addr.sin_port),
@@ -506,8 +513,8 @@ static int rxrpc_proc_calls_open(struct inode *inode, struct file *file)
struct seq_file *m;
int ret;
- ret = seq_open(file,&rxrpc_proc_calls_ops);
- if (ret<0)
+ ret = seq_open(file, &rxrpc_proc_calls_ops);
+ if (ret < 0)
return ret;
m = file->private_data;
@@ -518,7 +525,8 @@ static int rxrpc_proc_calls_open(struct inode *inode, struct file *file)
/*****************************************************************************/
/*
- * set up the iterator to start reading from the calls list and return the first item
+ * set up the iterator to start reading from the calls list and return the
+ * first item
*/
static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos)
{
@@ -530,15 +538,15 @@ static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos)
/* allow for the header line */
if (!pos)
- return (void *)1;
+ return (void *) 1;
pos--;
/* find the n'th element in the list */
- list_for_each(_p,&rxrpc_calls)
+ list_for_each(_p, &rxrpc_calls)
if (!pos--)
break;
- return _p!=&rxrpc_calls ? _p : NULL;
+ return _p != &rxrpc_calls ? _p : NULL;
} /* end rxrpc_proc_calls_start() */
/*****************************************************************************/
@@ -552,9 +560,9 @@ static void *rxrpc_proc_calls_next(struct seq_file *p, void *v, loff_t *pos)
(*pos)++;
_p = v;
- _p = v==(void*)1 ? rxrpc_calls.next : _p->next;
+ _p = (v == (void *) 1) ? rxrpc_calls.next : _p->next;
- return _p!=&rxrpc_calls ? _p : NULL;
+ return _p != &rxrpc_calls ? _p : NULL;
} /* end rxrpc_proc_calls_next() */
/*****************************************************************************/
@@ -573,10 +581,10 @@ static void rxrpc_proc_calls_stop(struct seq_file *p, void *v)
*/
static int rxrpc_proc_calls_show(struct seq_file *m, void *v)
{
- struct rxrpc_call *call = list_entry(v,struct rxrpc_call,call_link);
+ struct rxrpc_call *call = list_entry(v, struct rxrpc_call, call_link);
/* display header on line 1 */
- if (v == (void *)1) {
+ if (v == (void *) 1) {
seq_puts(m,
"LOCAL REMOT SRVC CONN CALL DIR USE "
" L STATE OPCODE ABORT ERRNO\n"
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c
index 08df88fcd643..fbf98729c748 100644
--- a/net/rxrpc/sysctl.c
+++ b/net/rxrpc/sysctl.c
@@ -60,6 +60,22 @@ static ctl_table rxrpc_sysctl_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec
},
+ {
+ .ctl_name = 5,
+ .procname = "peertimo",
+ .data = &rxrpc_peer_timeout,
+ .maxlen = sizeof(unsigned long),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax
+ },
+ {
+ .ctl_name = 6,
+ .procname = "conntimo",
+ .data = &rxrpc_conn_timeout,
+ .maxlen = sizeof(unsigned long),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax
+ },
{ .ctl_name = 0 }
};
@@ -67,6 +83,7 @@ static ctl_table rxrpc_dir_sysctl_table[] = {
{
.ctl_name = 1,
.procname = "rxrpc",
+ .maxlen = 0,
.mode = 0555,
.child = rxrpc_sysctl_table
},
@@ -81,7 +98,7 @@ static ctl_table rxrpc_dir_sysctl_table[] = {
int rxrpc_sysctl_init(void)
{
#ifdef CONFIG_SYSCTL
- rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table,0);
+ rxrpc_sysctl = register_sysctl_table(rxrpc_dir_sysctl_table, 0);
if (!rxrpc_sysctl)
return -ENOMEM;
#endif /* CONFIG_SYSCTL */
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
index 7d0df69b16fe..33b22b36d824 100644
--- a/net/rxrpc/transport.c
+++ b/net/rxrpc/transport.c
@@ -56,7 +56,8 @@ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans);
/*
* create a new transport endpoint using the specified UDP port
*/
-int rxrpc_create_transport(unsigned short port, struct rxrpc_transport **_trans)
+int rxrpc_create_transport(unsigned short port,
+ struct rxrpc_transport **_trans)
{
struct rxrpc_transport *trans;
struct sockaddr_in sin;
@@ -64,14 +65,14 @@ int rxrpc_create_transport(unsigned short port, struct rxrpc_transport **_trans)
struct sock *sock;
int ret, opt;
- _enter("%hu",port);
+ _enter("%hu", port);
- trans = kmalloc(sizeof(struct rxrpc_transport),GFP_KERNEL);
+ trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
if (!trans)
return -ENOMEM;
- memset(trans,0,sizeof(struct rxrpc_transport));
- atomic_set(&trans->usage,1);
+ memset(trans, 0, sizeof(struct rxrpc_transport));
+ atomic_set(&trans->usage, 1);
INIT_LIST_HEAD(&trans->services);
INIT_LIST_HEAD(&trans->link);
INIT_LIST_HEAD(&trans->krxiodq_link);
@@ -81,58 +82,58 @@ int rxrpc_create_transport(unsigned short port, struct rxrpc_transport **_trans)
spin_lock_init(&trans->peer_gylock);
init_waitqueue_head(&trans->peer_gy_waitq);
rwlock_init(&trans->peer_lock);
- atomic_set(&trans->peer_count,0);
+ atomic_set(&trans->peer_count, 0);
trans->port = port;
/* create a UDP socket to be my actual transport endpoint */
- ret = sock_create(PF_INET,SOCK_DGRAM,IPPROTO_UDP,&trans->socket);
- if (ret<0)
+ ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket);
+ if (ret < 0)
goto error;
/* use the specified port */
if (port) {
- memset(&sin,0,sizeof(sin));
+ memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
- ret = trans->socket->ops->bind(trans->socket,(struct sockaddr *)&sin,sizeof(sin));
- if (ret<0)
+ ret = trans->socket->ops->bind(trans->socket,
+ (struct sockaddr *) &sin,
+ sizeof(sin));
+ if (ret < 0)
goto error;
}
opt = 1;
oldfs = get_fs();
set_fs(KERNEL_DS);
- ret = trans->socket->ops->setsockopt(trans->socket,SOL_IP,IP_RECVERR,
- (char*)&opt,sizeof(opt));
+ ret = trans->socket->ops->setsockopt(trans->socket, SOL_IP, IP_RECVERR,
+ (char *) &opt, sizeof(opt));
set_fs(oldfs);
spin_lock(&rxrpc_transports_lock);
- list_add(&trans->link,&rxrpc_transports);
+ list_add(&trans->link, &rxrpc_transports);
spin_unlock(&rxrpc_transports_lock);
/* set the socket up */
sock = trans->socket->sk;
- sock->sk_user_data = trans;
- sock->sk_data_ready = rxrpc_data_ready;
- sock->sk_error_report = rxrpc_error_report;
+ sock->sk_user_data = trans;
+ sock->sk_data_ready = rxrpc_data_ready;
+ sock->sk_error_report = rxrpc_error_report;
down_write(&rxrpc_proc_transports_sem);
- list_add_tail(&trans->proc_link,&rxrpc_proc_transports);
+ list_add_tail(&trans->proc_link, &rxrpc_proc_transports);
up_write(&rxrpc_proc_transports_sem);
__RXACCT(atomic_inc(&rxrpc_transport_count));
*_trans = trans;
- _leave(" = 0 (%p)",trans);
+ _leave(" = 0 (%p)", trans);
return 0;
error:
rxrpc_put_transport(trans);
- _leave(" = %d",ret);
-
+ _leave(" = %d", ret);
return ret;
-
} /* end rxrpc_create_transport() */
/*****************************************************************************/
@@ -151,12 +152,13 @@ void rxrpc_clear_transport(struct rxrpc_transport *trans)
*/
void rxrpc_put_transport(struct rxrpc_transport *trans)
{
- _enter("%p{u=%d p=%hu}",trans,atomic_read(&trans->usage),trans->port);
+ _enter("%p{u=%d p=%hu}",
+ trans, atomic_read(&trans->usage), trans->port);
- if (atomic_read(&trans->usage)<=0)
- BUG();
+ BUG_ON(atomic_read(&trans->usage) <= 0);
- /* to prevent a race, the decrement and the dequeue must be effectively atomic */
+ /* to prevent a race, the decrement and the dequeue must be
+ * effectively atomic */
spin_lock(&rxrpc_transports_lock);
if (likely(!atomic_dec_and_test(&trans->usage))) {
spin_unlock(&rxrpc_transports_lock);
@@ -169,7 +171,7 @@ void rxrpc_put_transport(struct rxrpc_transport *trans)
/* finish cleaning up the transport */
if (trans->socket)
- trans->socket->ops->shutdown(trans->socket,2);
+ trans->socket->ops->shutdown(trans->socket, 2);
rxrpc_krxsecd_clear_transport(trans);
rxrpc_krxiod_dequeue_transport(trans);
@@ -192,41 +194,41 @@ void rxrpc_put_transport(struct rxrpc_transport *trans)
kfree(trans);
_leave("");
-
} /* end rxrpc_put_transport() */
/*****************************************************************************/
/*
* add a service to a transport to be listened upon
*/
-int rxrpc_add_service(struct rxrpc_transport *trans, struct rxrpc_service *newsrv)
+int rxrpc_add_service(struct rxrpc_transport *trans,
+ struct rxrpc_service *newsrv)
{
struct rxrpc_service *srv;
struct list_head *_p;
int ret = -EEXIST;
- _enter("%p{%hu},%p{%hu}",trans,trans->port,newsrv,newsrv->service_id);
+ _enter("%p{%hu},%p{%hu}",
+ trans, trans->port, newsrv, newsrv->service_id);
/* verify that the service ID is not already present */
spin_lock(&trans->lock);
- list_for_each(_p,&trans->services) {
- srv = list_entry(_p,struct rxrpc_service,link);
- if (srv->service_id==newsrv->service_id)
+ list_for_each(_p, &trans->services) {
+ srv = list_entry(_p, struct rxrpc_service, link);
+ if (srv->service_id == newsrv->service_id)
goto out;
}
/* okay - add the transport to the list */
- list_add_tail(&newsrv->link,&trans->services);
+ list_add_tail(&newsrv->link, &trans->services);
rxrpc_get_transport(trans);
ret = 0;
out:
spin_unlock(&trans->lock);
- _leave("= %d",ret);
+ _leave("= %d", ret);
return ret;
-
} /* end rxrpc_add_service() */
/*****************************************************************************/
@@ -235,7 +237,7 @@ int rxrpc_add_service(struct rxrpc_transport *trans, struct rxrpc_service *newsr
*/
void rxrpc_del_service(struct rxrpc_transport *trans, struct rxrpc_service *srv)
{
- _enter("%p{%hu},%p{%hu}",trans,trans->port,srv,srv->service_id);
+ _enter("%p{%hu},%p{%hu}", trans, trans->port, srv, srv->service_id);
spin_lock(&trans->lock);
list_del(&srv->link);
@@ -244,7 +246,6 @@ void rxrpc_del_service(struct rxrpc_transport *trans, struct rxrpc_service *srv)
rxrpc_put_transport(trans);
_leave("");
-
} /* end rxrpc_del_service() */
/*****************************************************************************/
@@ -255,7 +256,7 @@ static void rxrpc_data_ready(struct sock *sk, int count)
{
struct rxrpc_transport *trans;
- _enter("%p{t=%p},%d",sk,sk->sk_user_data,count);
+ _enter("%p{t=%p},%d", sk, sk->sk_user_data, count);
/* queue the transport for attention by krxiod */
trans = (struct rxrpc_transport *) sk->sk_user_data;
@@ -267,7 +268,6 @@ static void rxrpc_data_ready(struct sock *sk, int count)
wake_up_interruptible(sk->sk_sleep);
_leave("");
-
} /* end rxrpc_data_ready() */
/*****************************************************************************/
@@ -279,7 +279,7 @@ static void rxrpc_error_report(struct sock *sk)
{
struct rxrpc_transport *trans;
- _enter("%p{t=%p}",sk,sk->sk_user_data);
+ _enter("%p{t=%p}", sk, sk->sk_user_data);
/* queue the transport for attention by krxiod */
trans = (struct rxrpc_transport *) sk->sk_user_data;
@@ -293,13 +293,12 @@ static void rxrpc_error_report(struct sock *sk)
wake_up_interruptible(sk->sk_sleep);
_leave("");
-
} /* end rxrpc_error_report() */
/*****************************************************************************/
/*
- * split a message up, allocating message records and filling them in from the contents of a
- * socket buffer
+ * split a message up, allocating message records and filling them in
+ * from the contents of a socket buffer
*/
static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
struct sk_buff *pkt,
@@ -310,18 +309,19 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
_enter("");
- msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
+ msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
if (!msg) {
_leave(" = -ENOMEM");
return -ENOMEM;
}
- memset(msg,0,sizeof(*msg));
- atomic_set(&msg->usage,1);
+ memset(msg, 0, sizeof(*msg));
+ atomic_set(&msg->usage, 1);
list_add_tail(&msg->link,msgq);
/* dig out the Rx routing parameters */
- if (skb_copy_bits(pkt,sizeof(struct udphdr),&msg->hdr,sizeof(msg->hdr))<0) {
+ if (skb_copy_bits(pkt, sizeof(struct udphdr),
+ &msg->hdr, sizeof(msg->hdr)) < 0) {
ret = -EBADMSG;
goto error;
}
@@ -352,7 +352,9 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
__RXACCT(atomic_inc(&rxrpc_message_count));
/* split off jumbo packets */
- while (msg->hdr.type==RXRPC_PACKET_TYPE_DATA && msg->hdr.flags & RXRPC_JUMBO_PACKET) {
+ while (msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
+ msg->hdr.flags & RXRPC_JUMBO_PACKET
+ ) {
struct rxrpc_jumbo_header jumbo;
struct rxrpc_message *jumbomsg = msg;
@@ -360,23 +362,25 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
/* quick sanity check */
ret = -EBADMSG;
- if (msg->dsize < RXRPC_JUMBO_DATALEN+sizeof(struct rxrpc_jumbo_header))
+ if (msg->dsize <
+ RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))
goto error;
if (msg->hdr.flags & RXRPC_LAST_PACKET)
goto error;
/* dig out the secondary header */
- if (skb_copy_bits(pkt,msg->offset+RXRPC_JUMBO_DATALEN,&jumbo,sizeof(jumbo))<0)
+ if (skb_copy_bits(pkt, msg->offset + RXRPC_JUMBO_DATALEN,
+ &jumbo, sizeof(jumbo)) < 0)
goto error;
/* allocate a new message record */
ret = -ENOMEM;
- msg = kmalloc(sizeof(struct rxrpc_message),GFP_KERNEL);
+ msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
if (!msg)
goto error;
- memcpy(msg,jumbomsg,sizeof(*msg));
- list_add_tail(&msg->link,msgq);
+ memcpy(msg, jumbomsg, sizeof(*msg));
+ list_add_tail(&msg->link, msgq);
/* adjust the jumbo packet */
jumbomsg->dsize = RXRPC_JUMBO_DATALEN;
@@ -388,12 +392,15 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
msg->seq++;
msg->hdr.seq = htonl(msg->seq);
msg->hdr.serial = htonl(ntohl(msg->hdr.serial) + 1);
- msg->offset += RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
- msg->dsize -= RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header);
+ msg->offset += RXRPC_JUMBO_DATALEN +
+ sizeof(struct rxrpc_jumbo_header);
+ msg->dsize -= RXRPC_JUMBO_DATALEN +
+ sizeof(struct rxrpc_jumbo_header);
msg->hdr.flags = jumbo.flags;
msg->hdr._rsvd = jumbo._rsvd;
- _net("Rx Split jumbo packet from %s (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
+ _net("Rx Split jumbo packet from %s"
+ " (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
msg->hdr.flags & RXRPC_CLIENT_INITIATED ? "client" : "server",
ntohl(msg->hdr.epoch),
(ntohl(msg->hdr.cid) & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT,
@@ -407,18 +414,18 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
__RXACCT(atomic_inc(&rxrpc_message_count));
}
- _leave(" = 0 #%d",atomic_read(&rxrpc_message_count));
+ _leave(" = 0 #%d", atomic_read(&rxrpc_message_count));
return 0;
error:
while (!list_empty(msgq)) {
- msg = list_entry(msgq->next,struct rxrpc_message,link);
+ msg = list_entry(msgq->next, struct rxrpc_message, link);
list_del_init(&msg->link);
rxrpc_put_message(msg);
}
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_incoming_msg() */
@@ -438,7 +445,7 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
LIST_HEAD(msgq);
- _enter("%p{%d}",trans,trans->port);
+ _enter("%p{%d}", trans, trans->port);
for (;;) {
/* deal with outstanting errors first */
@@ -446,22 +453,25 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
rxrpc_trans_receive_error_report(trans);
/* attempt to receive a packet */
- pkt = skb_recv_datagram(trans->socket->sk,0,1,&ret);
+ pkt = skb_recv_datagram(trans->socket->sk, 0, 1, &ret);
if (!pkt) {
- if (ret==-EAGAIN) {
+ if (ret == -EAGAIN) {
_leave(" EAGAIN");
return;
}
/* an icmp error may have occurred */
rxrpc_krxiod_queue_transport(trans);
- _leave(" error %d\n",ret);
+ _leave(" error %d\n", ret);
return;
}
- /* we'll probably need to checksum it (didn't call sock_recvmsg) */
+ /* we'll probably need to checksum it (didn't call
+ * sock_recvmsg) */
if (pkt->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(skb_checksum(pkt,0,pkt->len,pkt->csum))) {
+ if ((unsigned short)
+ csum_fold(skb_checksum(pkt, 0, pkt->len,
+ pkt->csum))) {
kfree_skb(pkt);
rxrpc_krxiod_queue_transport(trans);
_leave(" CSUM failed");
@@ -472,34 +482,36 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
addr = pkt->nh.iph->saddr;
port = pkt->h.uh->source;
- _net("Rx Received UDP packet from %08x:%04hu",ntohl(addr),ntohs(port));
+ _net("Rx Received UDP packet from %08x:%04hu",
+ ntohl(addr), ntohs(port));
/* unmarshall the Rx parameters and split jumbo packets */
- ret = rxrpc_incoming_msg(trans,pkt,&msgq);
- if (ret<0) {
+ ret = rxrpc_incoming_msg(trans, pkt, &msgq);
+ if (ret < 0) {
kfree_skb(pkt);
rxrpc_krxiod_queue_transport(trans);
_leave(" bad packet");
return;
}
- if (list_empty(&msgq)) BUG();
+ BUG_ON(list_empty(&msgq));
- msg = list_entry(msgq.next,struct rxrpc_message,link);
+ msg = list_entry(msgq.next, struct rxrpc_message, link);
- /* locate the record for the peer from which it originated */
- ret = rxrpc_peer_lookup(trans,addr,&peer);
- if (ret<0) {
+ /* locate the record for the peer from which it
+ * originated */
+ ret = rxrpc_peer_lookup(trans, addr, &peer);
+ if (ret < 0) {
kdebug("Rx No connections from that peer");
- rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
+ rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
goto finished_msg;
}
/* try and find a matching connection */
- ret = rxrpc_connection_lookup(peer,msg,&msg->conn);
- if (ret<0) {
+ ret = rxrpc_connection_lookup(peer, msg, &msg->conn);
+ if (ret < 0) {
kdebug("Rx Unknown Connection");
- rxrpc_trans_immediate_abort(trans,msg,-EINVAL);
+ rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
rxrpc_put_peer(peer);
goto finished_msg;
}
@@ -507,23 +519,23 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
/* deal with the first packet of a new call */
if (msg->hdr.flags & RXRPC_CLIENT_INITIATED &&
- msg->hdr.type==RXRPC_PACKET_TYPE_DATA &&
- ntohl(msg->hdr.seq)==1
+ msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
+ ntohl(msg->hdr.seq) == 1
) {
_debug("Rx New server call");
- rxrpc_trans_receive_new_call(trans,&msgq);
+ rxrpc_trans_receive_new_call(trans, &msgq);
goto finished_msg;
}
/* deal with subsequent packet(s) of call */
_debug("Rx Call packet");
while (!list_empty(&msgq)) {
- msg = list_entry(msgq.next,struct rxrpc_message,link);
+ msg = list_entry(msgq.next, struct rxrpc_message, link);
list_del_init(&msg->link);
- ret = rxrpc_conn_receive_call_packet(msg->conn,NULL,msg);
- if (ret<0) {
- rxrpc_trans_immediate_abort(trans,msg,ret);
+ ret = rxrpc_conn_receive_call_packet(msg->conn, NULL, msg);
+ if (ret < 0) {
+ rxrpc_trans_immediate_abort(trans, msg, ret);
rxrpc_put_message(msg);
goto finished_msg;
}
@@ -536,7 +548,7 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
/* dispose of the packets */
finished_msg:
while (!list_empty(&msgq)) {
- msg = list_entry(msgq.next,struct rxrpc_message,link);
+ msg = list_entry(msgq.next, struct rxrpc_message, link);
list_del_init(&msg->link);
rxrpc_put_message(msg);
@@ -561,7 +573,7 @@ static int rxrpc_trans_receive_new_call(struct rxrpc_transport *trans,
_enter("");
/* only bother with the first packet */
- msg = list_entry(msgq->next,struct rxrpc_message,link);
+ msg = list_entry(msgq->next, struct rxrpc_message, link);
list_del_init(&msg->link);
rxrpc_krxsecd_queue_incoming_call(msg);
rxrpc_put_message(msg);
@@ -584,13 +596,13 @@ int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
struct msghdr msghdr;
struct iovec iov[2];
mm_segment_t oldfs;
+ uint32_t _error;
int len, ret;
- u32 _error;
- _enter("%p,%p,%d",trans,msg,error);
+ _enter("%p,%p,%d", trans, msg, error);
/* don't abort an abort packet */
- if (msg->hdr.type==RXRPC_PACKET_TYPE_ABORT) {
+ if (msg->hdr.type == RXRPC_PACKET_TYPE_ABORT) {
_leave(" = 0");
return 0;
}
@@ -598,12 +610,13 @@ int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
_error = htonl(-error);
/* set up the message to be transmitted */
- memcpy(&ahdr,&msg->hdr,sizeof(ahdr));
+ memcpy(&ahdr, &msg->hdr, sizeof(ahdr));
ahdr.epoch = msg->hdr.epoch;
ahdr.serial = htonl(1);
ahdr.seq = 0;
ahdr.type = RXRPC_PACKET_TYPE_ABORT;
- ahdr.flags = RXRPC_LAST_PACKET | (~msg->hdr.flags & RXRPC_CLIENT_INITIATED);
+ ahdr.flags = RXRPC_LAST_PACKET;
+ ahdr.flags |= ~msg->hdr.flags & RXRPC_CLIENT_INITIATED;
iov[0].iov_len = sizeof(ahdr);
iov[0].iov_base = &ahdr;
@@ -634,17 +647,17 @@ int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
/* send the message */
oldfs = get_fs();
set_fs(KERNEL_DS);
- ret = sock_sendmsg(trans->socket,&msghdr,len);
+ ret = sock_sendmsg(trans->socket, &msghdr, len);
set_fs(oldfs);
- _leave(" = %d",ret);
+ _leave(" = %d", ret);
return ret;
} /* end rxrpc_trans_immediate_abort() */
/*****************************************************************************/
/*
- * receive an ICMP error report and percolate it to all connections heading to the affected
- * host or port
+ * receive an ICMP error report and percolate it to all connections
+ * heading to the affected host or port
*/
static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
{
@@ -655,10 +668,10 @@ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
struct errormsg emsg;
struct msghdr msg;
mm_segment_t oldfs;
+ uint16_t port;
int local, err;
- u16 port;
- _enter("%p",trans);
+ _enter("%p", trans);
for (;;) {
trans->error_rcvd = 0;
@@ -674,48 +687,63 @@ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sock_recvmsg(trans->socket,&msg,0,MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
+ err = sock_recvmsg(trans->socket, &msg, 0,
+ MSG_ERRQUEUE | MSG_DONTWAIT | MSG_TRUNC);
set_fs(oldfs);
- if (err==-EAGAIN) {
+ if (err == -EAGAIN) {
_leave("");
return;
}
- if (err<0) {
- printk("%s: unable to recv an error report: %d\n",__FUNCTION__,err);
+ if (err < 0) {
+ printk("%s: unable to recv an error report: %d\n",
+ __FUNCTION__, err);
_leave("");
return;
}
- msg.msg_controllen = (char*)msg.msg_control - (char*)&emsg;
+ msg.msg_controllen = (char *) msg.msg_control - (char *) &emsg;
- if (msg.msg_controllen<sizeof(emsg.cmsg) || msg.msg_namelen<sizeof(sin)) {
- printk("%s: short control message (nlen=%u clen=%Zu fl=%x)\n",
- __FUNCTION__,msg.msg_namelen,msg.msg_controllen,msg.msg_flags);
+ if (msg.msg_controllen < sizeof(emsg.cmsg) ||
+ msg.msg_namelen < sizeof(sin)) {
+ printk("%s: short control message"
+ " (nlen=%u clen=%Zu fl=%x)\n",
+ __FUNCTION__,
+ msg.msg_namelen,
+ msg.msg_controllen,
+ msg.msg_flags);
continue;
}
- _net("Rx Received control message { len=%Zu level=%u type=%u }",
- emsg.cmsg.cmsg_len,emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
+ _net("Rx Received control message"
+ " { len=%Zu level=%u type=%u }",
+ emsg.cmsg.cmsg_len,
+ emsg.cmsg.cmsg_level,
+ emsg.cmsg.cmsg_type);
- if (sin.sin_family!=AF_INET) {
- printk("Rx Ignoring error report with non-INET address (fam=%u)",
+ if (sin.sin_family != AF_INET) {
+ printk("Rx Ignoring error report with non-INET address"
+ " (fam=%u)",
sin.sin_family);
continue;
}
_net("Rx Received message pertaining to host addr=%x port=%hu",
- ntohl(sin.sin_addr.s_addr),ntohs(sin.sin_port));
-
- if (emsg.cmsg.cmsg_level!=SOL_IP || emsg.cmsg.cmsg_type!=IP_RECVERR) {
- printk("Rx Ignoring unknown error report { level=%u type=%u }",
- emsg.cmsg.cmsg_level,emsg.cmsg.cmsg_type);
+ ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+
+ if (emsg.cmsg.cmsg_level != SOL_IP ||
+ emsg.cmsg.cmsg_type != IP_RECVERR) {
+ printk("Rx Ignoring unknown error report"
+ " { level=%u type=%u }",
+ emsg.cmsg.cmsg_level,
+ emsg.cmsg.cmsg_type);
continue;
}
- if (msg.msg_controllen<sizeof(emsg.cmsg)+sizeof(emsg.ee)) {
- printk("%s: short error message (%Zu)\n",__FUNCTION__,msg.msg_controllen);
+ if (msg.msg_controllen < sizeof(emsg.cmsg) + sizeof(emsg.ee)) {
+ printk("%s: short error message (%Zu)\n",
+ __FUNCTION__, msg.msg_controllen);
_leave("");
return;
}
@@ -767,14 +795,15 @@ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
default:
_proto("Rx Received ICMP error { type=%u code=%u }",
- emsg.ee.ee_type,emsg.ee.ee_code);
+ emsg.ee.ee_type, emsg.ee.ee_code);
err = emsg.ee.ee_errno;
break;
}
break;
case SO_EE_ORIGIN_LOCAL:
- _proto("Rx Received local error { error=%d }",emsg.ee.ee_errno);
+ _proto("Rx Received local error { error=%d }",
+ emsg.ee.ee_errno);
local = 1;
err = emsg.ee.ee_errno;
break;
@@ -782,35 +811,41 @@ static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
case SO_EE_ORIGIN_NONE:
case SO_EE_ORIGIN_ICMP6:
default:
- _proto("Rx Received error report { orig=%u }",emsg.ee.ee_origin);
+ _proto("Rx Received error report { orig=%u }",
+ emsg.ee.ee_origin);
local = 0;
err = emsg.ee.ee_errno;
break;
}
- /* find all the connections between this transport and the affected destination */
+ /* find all the connections between this transport and the
+ * affected destination */
INIT_LIST_HEAD(&connq);
- if (rxrpc_peer_lookup(trans,sin.sin_addr.s_addr,&peer)==0) {
+ if (rxrpc_peer_lookup(trans, sin.sin_addr.s_addr,
+ &peer) == 0) {
read_lock(&peer->conn_lock);
- list_for_each(_p,&peer->conn_active) {
- conn = list_entry(_p,struct rxrpc_connection,link);
- if (port && conn->addr.sin_port!=port)
+ list_for_each(_p, &peer->conn_active) {
+ conn = list_entry(_p, struct rxrpc_connection,
+ link);
+ if (port && conn->addr.sin_port != port)
continue;
if (!list_empty(&conn->err_link))
continue;
rxrpc_get_connection(conn);
- list_add_tail(&conn->err_link,&connq);
+ list_add_tail(&conn->err_link, &connq);
}
read_unlock(&peer->conn_lock);
/* service all those connections */
while (!list_empty(&connq)) {
- conn = list_entry(connq.next,struct rxrpc_connection,err_link);
+ conn = list_entry(connq.next,
+ struct rxrpc_connection,
+ err_link);
list_del(&conn->err_link);
- rxrpc_conn_handle_error(conn,local,err);
+ rxrpc_conn_handle_error(conn, local, err);
rxrpc_put_connection(conn);
}