Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-20 20:45:03 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-20 20:45:03 -0800
commiteac94688e46e081de1c3b516ee3595d5d8a7c400 (patch)
tree092f1ed72af1a0756795de3e386e34bc640f0913
parentb585ca3ef9bff4621ee9371d5fd9ed833666d359 (diff)
parentebd627f5a848579cb0cef4d1e94b31eee0b137cf (diff)
Merge master.kernel.org:/home/mingo/BK/linux-2.5/
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
-rw-r--r--Documentation/arm/mem_alignment58
-rw-r--r--Documentation/filesystems/porting11
-rw-r--r--arch/alpha/Makefile5
-rw-r--r--arch/alpha/kernel/core_titan.c1
-rw-r--r--arch/alpha/kernel/entry.S8
-rw-r--r--arch/alpha/kernel/process.c5
-rw-r--r--arch/alpha/kernel/proto.h6
-rw-r--r--arch/alpha/kernel/sys_titan.c7
-rw-r--r--arch/arm/Config.help113
-rw-r--r--arch/arm/boot/compressed/ofw-shark.c2
-rw-r--r--arch/arm/config.in1
-rw-r--r--arch/arm/kernel/armksyms.c5
-rw-r--r--arch/arm/kernel/calls.S39
-rw-r--r--arch/arm/kernel/entry-armv.S92
-rw-r--r--arch/arm/kernel/entry-common.S60
-rw-r--r--arch/arm/kernel/entry-header.S21
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/init_task.c14
-rw-r--r--arch/arm/kernel/process.c92
-rw-r--r--arch/arm/kernel/ptrace.c20
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/signal.c14
-rw-r--r--arch/arm/kernel/traps.c9
-rw-r--r--arch/arm/lib/csumpartial.S14
-rw-r--r--arch/arm/lib/csumpartialcopygeneric.S137
-rw-r--r--arch/arm/lib/getuser.S9
-rw-r--r--arch/arm/lib/putuser.S9
-rw-r--r--arch/arm/lib/strrchr.S2
-rw-r--r--arch/arm/mach-adifcc/arch.c4
-rw-r--r--arch/arm/mach-adifcc/irq.c2
-rw-r--r--arch/arm/mach-anakin/arch.c2
-rw-r--r--arch/arm/mach-arc/arch.c1
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c1
-rw-r--r--arch/arm/mach-epxa10db/arch.c3
-rw-r--r--arch/arm/mach-ftvpci/core.c1
-rw-r--r--arch/arm/mach-integrator/pci_v3.c1
-rw-r--r--arch/arm/mach-iop310/arch.c4
-rw-r--r--arch/arm/mach-iop310/iop310-irq.c2
-rw-r--r--arch/arm/mach-iop310/iq80310-irq.c2
-rw-r--r--arch/arm/mach-iop310/mm.c2
-rw-r--r--arch/arm/mach-iop310/xs80200-irq.c2
-rw-r--r--arch/arm/mach-l7200/core.c3
-rw-r--r--arch/arm/mach-sa1100/adsbitsy.c4
-rw-r--r--arch/arm/mach-sa1100/brutus.c2
-rw-r--r--arch/arm/mach-sa1100/cerf.c4
-rw-r--r--arch/arm/mach-sa1100/empeg.c2
-rw-r--r--arch/arm/mach-sa1100/flexanet.c6
-rw-r--r--arch/arm/mach-sa1100/freebird.c2
-rw-r--r--arch/arm/mach-sa1100/graphicsclient.c2
-rw-r--r--arch/arm/mach-sa1100/graphicsmaster.c2
-rw-r--r--arch/arm/mach-sa1100/h3600.c2
-rw-r--r--arch/arm/mach-sa1100/huw_webpanel.c4
-rw-r--r--arch/arm/mach-sa1100/irq.c2
-rw-r--r--arch/arm/mach-sa1100/leds-adsbitsy.c4
-rw-r--r--arch/arm/mach-sa1100/leds-graphicsclient.c4
-rw-r--r--arch/arm/mach-sa1100/leds-graphicsmaster.c4
-rw-r--r--arch/arm/mach-sa1100/leds-system3.c1
-rw-r--r--arch/arm/mach-sa1100/leds.c1
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c2
-rw-r--r--arch/arm/mach-sa1100/omnimeter.c2
-rw-r--r--arch/arm/mach-sa1100/pangolin.c4
-rw-r--r--arch/arm/mach-sa1100/pfs168.c4
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-sa1100/sa1111-pcibuf.c1
-rw-r--r--arch/arm/mach-sa1100/sherman.c2
-rw-r--r--arch/arm/mach-sa1100/simpad.c2
-rw-r--r--arch/arm/mach-sa1100/system3.c4
-rw-r--r--arch/arm/mach-sa1100/victor.c2
-rw-r--r--arch/arm/mach-sa1100/yopy.c2
-rw-r--r--arch/arm/mm/alignment.c177
-rw-r--r--arch/arm/tools/getconstants.c14
-rw-r--r--drivers/acorn/block/mfmhd.c10
-rw-r--r--drivers/acorn/char/mouse_ps2.c2
-rw-r--r--drivers/acorn/net/ether1.c20
-rw-r--r--drivers/acorn/net/ether3.c10
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c8
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/synclink.c4
-rw-r--r--drivers/char/wdt_pci.c4
-rw-r--r--drivers/ide/sl82c105.c2
-rw-r--r--drivers/input/gameport/cs461x.c2
-rw-r--r--drivers/input/gameport/emu10k1-gp.c2
-rw-r--r--drivers/input/gameport/pcigame.c2
-rw-r--r--drivers/isdn/avmb1/capi.c2
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c4
-rw-r--r--drivers/isdn/hisax/st5481_init.c2
-rw-r--r--drivers/isdn/tpam/tpam_main.c2
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c2
-rw-r--r--drivers/media/radio/radio-maxiradio.c2
-rw-r--r--drivers/media/video/bttv-driver.c3
-rw-r--r--drivers/media/video/meye.c2
-rw-r--r--drivers/media/video/zr36120.c2
-rw-r--r--drivers/mtd/maps/elan-104nc.c2
-rw-r--r--drivers/mtd/maps/sbc_gxx.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c2
-rw-r--r--drivers/net/8139too.c2
-rw-r--r--drivers/net/Config.help61
-rw-r--r--drivers/net/arcnet/com20020-pci.c2
-rw-r--r--drivers/net/defxx.c2
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/eepro100.c2
-rw-r--r--drivers/net/epic100.c2
-rw-r--r--drivers/net/fealnx.c2
-rw-r--r--drivers/net/hamachi.c4
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/irda/vlsi_ir.c2
-rw-r--r--drivers/net/natsemi.c4
-rw-r--r--drivers/net/ne2k-pci.c2
-rw-r--r--drivers/net/ns83820.c2
-rw-r--r--drivers/net/pci-skeleton.c2
-rw-r--r--drivers/net/pcmcia/Config.help2
-rw-r--r--drivers/net/pcmcia/xircom_cb.c2
-rw-r--r--drivers/net/pcmcia/xircom_tulip_cb.c2
-rw-r--r--drivers/net/rcpci45.c4
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/starfire.c2
-rw-r--r--drivers/net/sundance.c2
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/tlan.c2
-rw-r--r--drivers/net/tokenring/abyss.c4
-rw-r--r--drivers/net/tokenring/lanstreamer.c2
-rw-r--r--drivers/net/tokenring/olympic.c15
-rw-r--r--drivers/net/tokenring/tmspci.c4
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/wan/farsync.c2
-rw-r--r--drivers/net/winbond-840.c2
-rw-r--r--drivers/net/wireless/airo.c2
-rw-r--r--drivers/net/wireless/netwave_cs.c474
-rw-r--r--drivers/net/wireless/orinoco_plx.c2
-rw-r--r--drivers/net/wireless/wavelan.c1162
-rw-r--r--drivers/net/wireless/wavelan.p.h21
-rw-r--r--drivers/net/wireless/wavelan_cs.c1720
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h31
-rw-r--r--drivers/net/yellowfin.c2
-rw-r--r--drivers/parport/parport_serial.c2
-rw-r--r--drivers/pci/pci.ids1
-rw-r--r--drivers/pcmcia/pci_socket.c2
-rw-r--r--drivers/scsi/eata.c116
-rw-r--r--drivers/scsi/eata.h2
-rw-r--r--drivers/scsi/imm.c2
-rw-r--r--drivers/scsi/ppa.c6
-rw-r--r--drivers/scsi/u14-34f.c95
-rw-r--r--drivers/scsi/u14-34f.h2
-rw-r--r--drivers/usb/hcd/Config.help1
-rw-r--r--drivers/usb/hub.c53
-rw-r--r--drivers/usb/ov511.c2750
-rw-r--r--drivers/usb/ov511.h231
-rw-r--r--drivers/usb/uhci.c229
-rw-r--r--drivers/usb/uhci.h60
-rw-r--r--drivers/usb/usb-ohci.c15
-rw-r--r--drivers/usb/usb-uhci.c10
-rw-r--r--drivers/usb/vicam.c2
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/neofb.c2
-rw-r--r--drivers/video/radeonfb.c2
-rw-r--r--drivers/video/riva/fbdev.c4
-rw-r--r--drivers/video/tdfxfb.c2
-rw-r--r--fs/fat/inode.c12
-rw-r--r--fs/reiserfs/namei.c2
-rw-r--r--include/asm-alpha/bitops.h21
-rw-r--r--include/asm-alpha/mmu_context.h25
-rw-r--r--include/asm-alpha/spinlock.h12
-rw-r--r--include/asm-alpha/system.h142
-rw-r--r--include/asm-arm/arch-adifcc/serial.h2
-rw-r--r--include/asm-arm/arch-anakin/ide.h1
-rw-r--r--include/asm-arm/arch-anakin/uncompress.h1
-rw-r--r--include/asm-arm/arch-clps711x/memory.h2
-rw-r--r--include/asm-arm/arch-ebsa285/keyboard.h1
-rw-r--r--include/asm-arm/arch-epxa10db/time.h1
-rw-r--r--include/asm-arm/arch-iop310/irqs.h2
-rw-r--r--include/asm-arm/arch-iop310/memory.h1
-rw-r--r--include/asm-arm/arch-iop310/serial.h2
-rw-r--r--include/asm-arm/arch-iop310/timex.h2
-rw-r--r--include/asm-arm/arch-iop310/uncompress.h1
-rw-r--r--include/asm-arm/arch-sa1100/assabet.h2
-rw-r--r--include/asm-arm/arch-sa1100/cerf.h2
-rw-r--r--include/asm-arm/arch-sa1100/pangolin.h3
-rw-r--r--include/asm-arm/arch-shark/keyboard.h1
-rw-r--r--include/asm-arm/bitops.h17
-rw-r--r--include/asm-arm/current.h5
-rw-r--r--include/asm-arm/fpstate.h29
-rw-r--r--include/asm-arm/hardirq.h1
-rw-r--r--include/asm-arm/mmu_context.h28
-rw-r--r--include/asm-arm/pgalloc.h8
-rw-r--r--include/asm-arm/proc-armo/processor.h14
-rw-r--r--include/asm-arm/proc-armv/processor.h22
-rw-r--r--include/asm-arm/proc-armv/uaccess.h7
-rw-r--r--include/asm-arm/processor.h57
-rw-r--r--include/asm-arm/smplock.h29
-rw-r--r--include/asm-arm/softirq.h8
-rw-r--r--include/asm-arm/stat.h29
-rw-r--r--include/asm-arm/system.h13
-rw-r--r--include/asm-arm/thread_info.h134
-rw-r--r--include/asm-arm/uaccess.h2
-rw-r--r--include/asm-arm/unistd.h13
-rw-r--r--include/linux/lvm.h35
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/math-emu/op-4.h2
-rw-r--r--sound/core/info.c22
-rw-r--r--sound/oss/btaudio.c2
-rw-r--r--sound/oss/cs4232.c8
-rw-r--r--sound/oss/emu10k1/main.c2
-rw-r--r--sound/oss/i810_audio.c4
-rw-r--r--sound/oss/mpu401.c2
-rw-r--r--sound/oss/rme96xx.c4
-rw-r--r--sound/oss/sonicvibes.c8
-rw-r--r--sound/oss/trident.c4
-rw-r--r--sound/oss/via82cxxx_audio.c6
-rw-r--r--sound/oss/ymfpci.c2
214 files changed, 5477 insertions, 3588 deletions
diff --git a/Documentation/arm/mem_alignment b/Documentation/arm/mem_alignment
new file mode 100644
index 000000000000..a944af7c0244
--- /dev/null
+++ b/Documentation/arm/mem_alignment
@@ -0,0 +1,58 @@
+Too many problems poped up because of unnoticed misaligned memory access in
+kernel code lately. Therefore the alignment fixup is now unconditionally
+configured in for SA11x0 based targets. According to Alan Cox, this is a
+bad idea to configure it out, but Russell King has some good reasons for
+doing so on some f***ed up ARM architectures like the EBSA110. However
+this is not the case on many design I'm aware of, like all SA11x0 based
+ones.
+
+Of course this is a bad idea to rely on the alignment trap to perform
+unaligned memory access in general. If those access are predictable, you
+are better to use the macros provided by include/asm/unaligned.h. The
+alignment trap can fixup misaligned access for the exception cases, but at
+a high performance cost. It better be rare.
+
+Now for user space applications, it is possible to configure the alignment
+trap to SIGBUS any code performing unaligned access (good for debugging bad
+code), or even fixup the access by software like for kernel code. The later
+mode isn't recommended for performance reasons (just think about the
+floating point emulation that works about the same way). Fix your code
+instead!
+
+Please note that randomly changing the behaviour without good thought is
+real bad - it changes the behaviour of all unaligned instructions in user
+space, and might cause programs to fail unexpectedly.
+
+To change the alignment trap behavior, simply echo a number into
+/proc/sys/debug/alignment. The number is made up from various bits:
+
+bit behavior when set
+--- -----------------
+
+0 A user process performing an unaligned memory access
+ will cause the kernel to print a message indicating
+ process name, pid, pc, instruction, address, and the
+ fault code.
+
+1 The kernel will attempt to fix up the user process
+ performing the unaligned access. This is of course
+ slow (think about the floating point emulator) and
+ not recommended for production use.
+
+2 The kernel will send a SIGBUS signal to the user process
+ performing the unaligned access.
+
+Note that not all combinations are supported - only values 0 through 5.
+(6 and 7 don't make sense).
+
+For example, the following will turn on the warnings, but without
+fixing up or sending SIGBUS signals:
+
+ echo 1 > /proc/sys/debug/alignment
+
+You can also read the content of the same file to get statistical
+information on unaligned access occurences plus the current mode of
+operation for user space code.
+
+
+Nicolas Pitre, Mar 13, 2001. Modified Russell King, Nov 30, 2001.
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 49ffdac32d14..0a4efdd817ed 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -81,11 +81,12 @@ can relax your locking.
[mandatory]
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir(),
-->rmdir(), ->link(), ->symlink() and ->rename() are called without BKL now.
-Grab it on the entry, drop upon return - that will guarantee the same
-locking you used to have. If your method or its parts do not need BKL -
-better yet, now you can shift lock_kernel() / unlock_kernel() so that
-they would protect exactly what needs to be protected.
+->rmdir(), ->link(), ->lseek(), ->symlink() and ->rename() are called
+without BKL now. Grab it on the entry, drop upon return - that will
+guarantee the same locking you used to have. If your method or its
+parts do not need BKL - better yet, now you can shift lock_kernel() and
+unlock_kernel() so that they would protect exactly what needs to be
+protected.
---
[informational]
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 4e40e6fb14d2..1436efdb8718 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -25,6 +25,11 @@ have_mcpu_ev6 := $(shell if $(CC) -mcpu=ev6 -S -o /dev/null -xc /dev/null > /dev
have_mcpu_ev67 := $(shell if $(CC) -mcpu=ev67 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+have_msmall_data := $(shell if $(CC) -msmall-data -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+ifeq ($(have_msmall_data),y)
+ CFLAGS := $(CFLAGS) -msmall-data
+endif
+
# Turn on the proper cpu optimizations.
ifeq ($(have_mcpu),y)
# If GENERIC, make sure to turn off any instruction set extensions that
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index d37a54816238..4b8168f97ca3 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -279,7 +279,6 @@ static void __init
titan_init_one_pachip_port(titan_pachip_port *port, int index)
{
struct pci_controller *hose;
- unsigned long sg_size;
hose = alloc_pci_controller();
if (index == 0)
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 155fa05bad45..58e4aa037076 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -489,22 +489,22 @@ alpha_switch_to:
.prologue 0
bsr $1,do_switch_stack
call_pal PAL_swpctx
- unop
- bsr $1,undo_switch_stack
lda $8,0x3fff
- mov $17,$0
+ bsr $1,undo_switch_stack
bic $30,$8,$8
ret $31,($26),1
.end alpha_switch_to
+#ifdef CONFIG_SMP
.globl ret_from_fork
.align 3
.ent ret_from_fork
ret_from_fork:
lda $26,ret_from_sys_call
- mov $0,$16
+ mov $17,$16
jmp $31,schedule_tail
.end ret_from_fork
+#endif
/*
* Oh, well.. Disassembling OSF/1 binaries to find out how the
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 015eaa828cf7..4f5bb5924393 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -283,6 +283,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
+ extern void ret_from_sys_call(void);
extern void ret_from_fork(void);
struct thread_info *childti = p->thread_info;
@@ -304,7 +305,11 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
stack = ((struct switch_stack *) regs) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
+#ifdef CONFIG_SMP
childstack->r26 = (unsigned long) ret_from_fork;
+#else
+ childstack->r26 = (unsigned long) ret_from_sys_call;
+#endif
childti->pcb.usp = usp;
childti->pcb.ksp = (unsigned long) childstack;
childti->pcb.flags = 1; /* set FEN, clear everything else */
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 170ee06fc5c2..746869cb1145 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -162,9 +162,9 @@ extern struct mcheck_info
unsigned char extra;
} __mcheck_info;
-#define mcheck_expected(cpu) (__mcheck_info.expected)
-#define mcheck_taken(cpu) (__mcheck_info.taken)
-#define mcheck_extra(cpu) (__mcheck_info.extra)
+#define mcheck_expected(cpu) ((void)(cpu), __mcheck_info.expected)
+#define mcheck_taken(cpu) ((void)(cpu), __mcheck_info.taken)
+#define mcheck_extra(cpu) ((void)(cpu), __mcheck_info.extra)
#endif
#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 09920c74549d..846fb3d3251f 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -84,8 +84,8 @@ titan_update_irq_hw(unsigned long mask)
*dim3;
#else
volatile unsigned long *dimB;
- if (bcpu == 0) dimB = &cchip->dim0.csr;
- else if (bcpu == 1) dimB = &cchip->dim1.csr;
+ dimB = &cchip->dim0.csr;
+ if (bcpu == 1) dimB = &cchip->dim1.csr;
else if (bcpu == 2) dimB = &cchip->dim2.csr;
else if (bcpu == 3) dimB = &cchip->dim3.csr;
@@ -190,9 +190,6 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax)
static void __init
privateer_init_irq(void)
{
- extern asmlinkage void entInt(void);
- int cpu;
-
outb(0, DMA1_RESET_REG);
outb(0, DMA2_RESET_REG);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
diff --git a/arch/arm/Config.help b/arch/arm/Config.help
index 7b8bfc3f5574..5dcb3a722cd4 100644
--- a/arch/arm/Config.help
+++ b/arch/arm/Config.help
@@ -116,6 +116,16 @@ CONFIG_PCI_INTEGRATOR
information about which PCI hardware does work under Linux and which
doesn't.
+CONFIG_PREEMPT
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ This allows applications to run more reliably even when the system is
+ under load.
+
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
+
CONFIG_MCA
MicroChannel Architecture is found in some IBM PS/2 machines and
laptops. It is a bus system similar to PCI or ISA. See
@@ -521,6 +531,10 @@ CONFIG_ARCH_EBSA285_HOST
Saying N will reduce the size of the Footbridge kernel.
+CONFIG_ARCH_IQ80310
+ Say Y here if you want to run your kernel on the Intel IQ80310
+ evaluation kit for the IOP310 chipset.
+
CONFIG_ARCH_L7200
Say Y here if you intend to run this kernel on a LinkUp Systems
L7200 Software Development Board which uses an ARM720T processor.
@@ -558,6 +572,13 @@ CONFIG_ARCH_PERSONAL_SERVER
If you have any questions or comments about the Compaq Personal
Server, send e-mail to skiff@crl.dec.com.
+CONFIG_PLD_HOTSWAP
+ This enables support for the dynamic loading and configuration of
+ compatible drivers when the contents of the PLD are changed. This
+ is still experimental and requires configuration tools which are
+ not yet generally available. Say N here. You must enable the kernel
+ module loader for this feature to work.
+
CONFIG_SA1100_ASSABET
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
Microprocessor Development Board (also known as the Assabet).
@@ -567,28 +588,14 @@ CONFIG_ASSABET_NEPONSET
Microprocessor Development Board (Assabet) with the SA-1111
Development Board (Nepon).
-CONFIG_SA1100_H3600
- Say Y here if you intend to run this kernel on the Compaq iPAQ
- H3600 handheld computer. Information about this machine and the
- Linux port to this machine can be found at:
-
- <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
- <http://www.compaq.com/products/handhelds/pocketpc/>
+CONFIG_SA1100_BADGE4
+ Say Y here if you want to build a kernel for the HP Laboratories
+ BadgePAD 4.
CONFIG_SA1100_BRUTUS
Say Y here if you are using the Intel(R) StrongARM(R) SA-1100
Microprocessor Development Board (also known as the Brutus).
-CONFIG_SA1100_LART
- Say Y here if you are using the Linux Advanced Radio Terminal
- (also known as the LART). See <http://www.lart.tudelft.nl/> for
- information on the LART.
-
-CONFIG_SA1100_GRAPHICSCLIENT
- Say Y here if you are using an Applied Data Systems Intel(R)
- StrongARM(R) SA-1100 based Graphics Client SBC. See
- <http://www.flatpanels.com/> for information on this system.
-
CONFIG_SA1100_CERF
The Intrinsyc CerfBoard is based on the StrongARM 1110.
More information is available at:
@@ -602,6 +609,24 @@ CONFIG_SA1100_FLEXANET
handheld instruments. Information about this machine can be
found at: <http://www.flexanet.com/>.
+CONFIG_SA1100_GRAPHICSCLIENT
+ Say Y here if you are using an Applied Data Systems Intel(R)
+ StrongARM(R) SA-1100 based Graphics Client SBC. See
+ <http://www.flatpanels.com/> for information on this system.
+
+CONFIG_SA1100_H3600
+ Say Y here if you intend to run this kernel on the Compaq iPAQ
+ H3600 handheld computer. Information about this machine and the
+ Linux port to this machine can be found at:
+
+ <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
+ <http://www.compaq.com/products/handhelds/pocketpc/>
+
+CONFIG_SA1100_LART
+ Say Y here if you are using the Linux Advanced Radio Terminal
+ (also known as the LART). See <http://www.lart.tudelft.nl/> for
+ information on the LART.
+
CONFIG_SA1100_NANOENGINE
The nanoEngine is a StrongARM 1110-based single board computer
from Bright Star Engineering. More information is available at:
@@ -619,6 +644,19 @@ CONFIG_SA1100_PANGOLIN
Say Y if configuring for a Pangolin.
Say N otherwise.
+CONFIG_SA1100_PFS168
+ The Radisys Corp. PFS-168 (aka Tulsa) is an IntelŪ StrongArmŪ SA-1110 based
+ computer which includes the SA-1111 Microprocessor Companion Chip and other
+ custom I/O designed to add connectivity and multimedia features for vending
+ and business machine applications. Say Y here if you require support for
+ this target.
+
+CONFIG_SA1100_SHANNON
+ The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
+ limited edition webphone produced by Philips. The Shannon is a SA1100
+ platform with a 640x480 LCD, touchscreen, CIR keyboard, PCMCIA slots,
+ and a telco interface.
+
CONFIG_SA1100_VICTOR
Say Y here if you are using a Visu Aide Intel(R) StrongARM(R)
SA-1100 based Victor Digital Talking Book Reader. See
@@ -656,6 +694,31 @@ CONFIG_CPU_ARM920T
Say Y if you want support for the ARM920T processor.
Otherwise, say N.
+CONFIG_CPU_ARM922T
+ The ARM922T is a version of the ARM920T, but with smaller
+ instruction and data caches. It is used in Altera's
+ Excalibur XA device family.
+
+ Say Y if you want support for the ARM922T processor.
+ Otherwise, say N.
+
+CONFIG_CPU_ARM922_CPU_IDLE
+ Saying Y here will allow the processor to enter a low power
+ mode whilst waiting for an interrupt in idle. If you're unsure
+ say Y.
+
+CONFIG_CPU_ARM922_I_CACHE_ON
+ Say Y here to enable the processor instruction cache. Unless
+ you have a reason not to, say Y.
+
+CONFIG_CPU_ARM922_D_CACHE_ON
+ Say Y here to enable the processor data cache. Unless
+ you have a reason not to, say Y.
+
+CONFIG_CPU_ARM922_WRITETHROUGH
+ Say Y here to use the data cache in writethough mode. Unless you
+ specifically require this, say N.
+
CONFIG_CPU_ARM1020
The ARM1020 is the cached version of the ARM10 processor,
with an addition of a floating-point unit.
@@ -688,16 +751,14 @@ CONFIG_FPE_NWFPE
CONFIG_FPE_FASTFPE
Say Y here to include the FAST floating point emulator in the kernel.
- This is an experimental much faster emulator which has only 32 bit
+ This is an experimental much faster emulator which now also has full
precision for the mantissa. It does not support any exceptions.
- This makes it very simple, it is approximately 4-8 times faster than
- NWFPE.
-
- It should be sufficient for most programs. It is definitely not
- suitable if you do scientific calculations that need double
- precision for iteration formulas that sum up lots of very small
- numbers. If you do not feel you need a faster FP emulation you
- should better choose NWFPE.
+ It is very simple, and approximately 3-6 times faster than NWFPE.
+
+ It should be sufficient for most programs. It may be not suitable
+ for scientific calculations, but you have to check this for yourself.
+ If you do not feel you need a faster FP emulation you should better
+ choose NWFPE.
It is also possible to say M to build the emulator as a module
(fastfpe.o). But keep in mind that you should only load the FP
diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c
index 821e549c153a..2091e68d4ba7 100644
--- a/arch/arm/boot/compressed/ofw-shark.c
+++ b/arch/arm/boot/compressed/ofw-shark.c
@@ -19,7 +19,7 @@
asmlinkage void
create_params (unsigned long *buffer)
{
- /* Is there a better address? Also change in mach-shark/arch.c */
+ /* Is there a better address? Also change in mach-shark/core.c */
struct tag *tag = (struct tag *) 0x08003000;
int j,i,m,k,nr_banks,size;
unsigned char *c;
diff --git a/arch/arm/config.in b/arch/arm/config.in
index 16f059d77215..991a4e5e7f65 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -464,6 +464,7 @@ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'Power Management support' CONFIG_PM
+dep_bool 'Preemptible Kernel (experimental)' CONFIG_PREEMPT $CONFIG_CPU_32 $CONFIG_EXPERIMENTAL
dep_tristate 'Advanced Power Management Emulation' CONFIG_APM $CONFIG_PM
dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 4c496827b2d9..f90e82eb02fd 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -21,6 +21,7 @@
#include <linux/pm.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
+#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/elf.h>
@@ -273,3 +274,7 @@ EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
EXPORT_SYMBOL(get_wchan);
+
+#ifdef CONFIG_PREEMPT
+EXPORT_SYMBOL(kernel_flag);
+#endif
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 74278f6a4e65..f998d7eb68c0 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -21,13 +21,13 @@ __syscall_start:
.long SYMBOL_NAME(sys_write)
/* 5 */ .long SYMBOL_NAME(sys_open)
.long SYMBOL_NAME(sys_close)
- .long SYMBOL_NAME(sys_waitpid)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_waitpid */
.long SYMBOL_NAME(sys_creat)
.long SYMBOL_NAME(sys_link)
/* 10 */ .long SYMBOL_NAME(sys_unlink)
.long SYMBOL_NAME(sys_execve_wrapper)
.long SYMBOL_NAME(sys_chdir)
- .long SYMBOL_NAME(sys_time)
+ .long SYMBOL_NAME(sys_time) /* used by libc4 */
.long SYMBOL_NAME(sys_mknod)
/* 15 */ .long SYMBOL_NAME(sys_chmod)
.long SYMBOL_NAME(sys_lchown16)
@@ -36,15 +36,15 @@ __syscall_start:
.long SYMBOL_NAME(sys_lseek)
/* 20 */ .long SYMBOL_NAME(sys_getpid)
.long SYMBOL_NAME(sys_mount)
- .long SYMBOL_NAME(sys_oldumount)
+ .long SYMBOL_NAME(sys_oldumount) /* used by libc4 */
.long SYMBOL_NAME(sys_setuid16)
.long SYMBOL_NAME(sys_getuid16)
/* 25 */ .long SYMBOL_NAME(sys_stime)
.long SYMBOL_NAME(sys_ptrace)
- .long SYMBOL_NAME(sys_alarm)
+ .long SYMBOL_NAME(sys_alarm) /* used by libc4 */
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_fstat */
.long SYMBOL_NAME(sys_pause)
-/* 30 */ .long SYMBOL_NAME(sys_utime)
+/* 30 */ .long SYMBOL_NAME(sys_utime) /* used by libc4 */
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_stty */
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_getty */
.long SYMBOL_NAME(sys_access)
@@ -62,7 +62,7 @@ __syscall_start:
/* 45 */ .long SYMBOL_NAME(sys_brk)
.long SYMBOL_NAME(sys_setgid16)
.long SYMBOL_NAME(sys_getgid16)
- .long SYMBOL_NAME(sys_signal)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_signal */
.long SYMBOL_NAME(sys_geteuid16)
/* 50 */ .long SYMBOL_NAME(sys_getegid16)
.long SYMBOL_NAME(sys_acct)
@@ -82,29 +82,29 @@ __syscall_start:
/* 65 */ .long SYMBOL_NAME(sys_getpgrp)
.long SYMBOL_NAME(sys_setsid)
.long SYMBOL_NAME(sys_sigaction)
- .long SYMBOL_NAME(sys_sgetmask)
- .long SYMBOL_NAME(sys_ssetmask)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_sgetmask */
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_ssetmask */
/* 70 */ .long SYMBOL_NAME(sys_setreuid16)
.long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend_wrapper)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
/* 75 */ .long SYMBOL_NAME(sys_setrlimit)
- .long SYMBOL_NAME(sys_old_getrlimit)
+ .long SYMBOL_NAME(sys_old_getrlimit) /* used by libc4 */
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
/* 80 */ .long SYMBOL_NAME(sys_getgroups16)
.long SYMBOL_NAME(sys_setgroups16)
- .long SYMBOL_NAME(old_select)
+ .long SYMBOL_NAME(old_select) /* used by libc4 */
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_lstat */
/* 85 */ .long SYMBOL_NAME(sys_readlink)
.long SYMBOL_NAME(sys_uselib)
.long SYMBOL_NAME(sys_swapon)
.long SYMBOL_NAME(sys_reboot)
- .long SYMBOL_NAME(old_readdir)
-/* 90 */ .long SYMBOL_NAME(old_mmap)
+ .long SYMBOL_NAME(old_readdir) /* used by libc4 */
+/* 90 */ .long SYMBOL_NAME(old_mmap) /* used by libc4 */
.long SYMBOL_NAME(sys_munmap)
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
@@ -236,7 +236,22 @@ __syscall_start:
.long SYMBOL_NAME(sys_mincore)
/* 220 */ .long SYMBOL_NAME(sys_madvise)
.long SYMBOL_NAME(sys_fcntl64)
+ .long SYMBOL_NAME(sys_ni_syscall) /* TUX */
+ .long SYMBOL_NAME(sys_ni_syscall) /* Security */
.long SYMBOL_NAME(sys_gettid)
+/* 225 */ .long SYMBOL_NAME(sys_readahead)
+ .long SYMBOL_NAME(sys_setxattr)
+ .long SYMBOL_NAME(sys_lsetxattr)
+ .long SYMBOL_NAME(sys_fsetxattr)
+ .long SYMBOL_NAME(sys_getxattr)
+/* 230 */ .long SYMBOL_NAME(sys_lgetxattr)
+ .long SYMBOL_NAME(sys_fgetxattr)
+ .long SYMBOL_NAME(sys_listxattr)
+ .long SYMBOL_NAME(sys_llistxattr)
+ .long SYMBOL_NAME(sys_flistxattr)
+/* 235 */ .long SYMBOL_NAME(sys_removexattr)
+ .long SYMBOL_NAME(sys_lremovexattr)
+ .long SYMBOL_NAME(sys_fremovexattr)
.long SYMBOL_NAME(sys_tkill)
__syscall_end:
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 889ddca82381..e5c15ce45edf 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -15,6 +15,7 @@
*/
#include <linux/config.h>
#include "entry-header.S"
+#include <asm/thread_info.h>
#ifdef IOC_BASE
@@ -690,8 +691,7 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
msr cpsr_c, r9
mov r2, sp
bl SYMBOL_NAME(do_DataAbort)
- mov r0, #PSR_I_BIT | MODE_SVC
- msr cpsr_c, r0
+ set_cpsr_c r0, #PSR_I_BIT | MODE_SVC
ldr r0, [sp, #S_PSR]
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
@@ -705,17 +705,50 @@ __irq_svc: sub sp, sp, #S_FRAME_SIZE
add r4, sp, #S_SP
mov r6, lr
stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+#ifdef CONFIG_PREEMPT
+ get_thread_info r8
+ ldr r9, [r8, #TI_PREEMPT] @ get preempt count
+ add r7, r9, #1 @ increment it
+ str r7, [r8, #TI_PREEMPT]
+#endif
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrsvc ne, lr, 1b
- bne do_IRQ
+ bne asm_do_IRQ
+#ifdef CONFIG_PREEMPT
+ ldr r0, [r8, #TI_FLAGS] @ get flags
+ tst r0, #_TIF_NEED_RESCHED
+ ldrne r6, .LCirq_stat
+ blne svc_preempt
+preempt_return:
+ ldr r0, [r8, #TI_PREEMPT] @ read preempt value
+ teq r0, r7
+ strne r0, [r0, -r0] @ bug()
+ str r9, [r8, #TI_PREEMPT] @ restore preempt count
+#endif
ldr r0, [sp, #S_PSR] @ irqs are already disabled
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+#ifdef CONFIG_PREEMPT
+svc_preempt: teq r9, #0
+ movne pc, lr
+ ldr r0, [r6, #4] @ local_irq_count
+ ldr r1, [r6, #8] @ local_b_count
+ adds r0, r0, r1
+ movne pc, lr
+1: set_cpsr_c r0, #MODE_SVC @ enable IRQs
+ bl SYMBOL_NAME(preempt_schedule)
+ set_cpsr_c r0, #PSR_I_BIT | MODE_SVC @ disable IRQs
+ ldr r0, [r8, #TI_FLAGS]
+ tst r0, #_TIF_NEED_RESCHED
+ bne 1b
+ b preempt_return
+#endif
+
.align 5
__und_svc: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
@@ -733,8 +766,7 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
mov r1, sp @ struct pt_regs *regs
bl SYMBOL_NAME(do_undefinstr)
-1: mov r0, #PSR_I_BIT | MODE_SVC
- msr cpsr_c, r0
+1: set_cpsr_c r0, #PSR_I_BIT | MODE_SVC
ldr lr, [sp, #S_PSR] @ Get SVC cpsr
msr spsr, lr
ldmia sp, {r0 - pc}^ @ Restore SVC registers
@@ -755,8 +787,7 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE
mov r0, r2 @ address (pc)
mov r1, sp @ regs
bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
- mov r0, #PSR_I_BIT | MODE_SVC
- msr cpsr_c, r0
+ set_cpsr_c r0, #PSR_I_BIT | MODE_SVC
ldr r0, [sp, #S_PSR]
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
@@ -769,6 +800,9 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE
.LCprocfns: .word SYMBOL_NAME(processor)
#endif
.LCfp: .word SYMBOL_NAME(fp_enter)
+#ifdef CONFIG_PREEMPT
+.LCirq_stat: .word SYMBOL_NAME(irq_stat)
+#endif
irq_prio_table
@@ -793,8 +827,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#else
bl cpu_data_abort
#endif
- mov r2, #MODE_SVC
- msr cpsr_c, r2 @ Enable interrupts
+ set_cpsr_c r2, #MODE_SVC @ Enable interrupts
mov r2, sp
adrsvc al, lr, ret_from_exception
b SYMBOL_NAME(do_DataAbort)
@@ -809,15 +842,29 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE
stmdb r8, {sp, lr}^
alignment_trap r4, r7, __temp_irq
zero_fp
+#ifdef CONFIG_PREEMPT
+ get_thread_info r8
+ ldr r9, [r8, #TI_PREEMPT] @ get preempt count
+ add r7, r9, #1 @ increment it
+ str r7, [r8, #TI_PREEMPT]
+#endif
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
adrsvc ne, lr, 1b
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
- bne do_IRQ
+ bne asm_do_IRQ
+#ifdef CONFIG_PREEMPT
+ ldr r0, [r8, #TI_PREEMPT]
+ teq r0, r7
+ strne r0, [r0, -r0]
+ str r9, [r8, #TI_PREEMPT]
+ mov tsk, r8
+#else
+ get_thread_info tsk
+#endif
mov why, #0
- get_current_task tsk
b ret_to_user
.align 5
@@ -833,15 +880,15 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
adrsvc al, r9, ret_from_exception @ r9 = normal FP return
adrsvc al, lr, fpundefinstr @ lr = undefined instr return
-call_fpe: get_current_task r10
+call_fpe: get_thread_info r10 @ get current thread
+ ldr r4, [r10, #TI_TASK] @ get current task
mov r8, #1
- strb r8, [r10, #TSK_USED_MATH] @ set current->used_math
+ strb r8, [r4, #TSK_USED_MATH] @ set current->used_math
ldr r4, .LCfp
- add r10, r10, #TSS_FPESAVE @ r10 = workspace
+ add r10, r10, #TI_FPSTATE @ r10 = workspace
ldr pc, [r4] @ Call FP module USR entry point
-fpundefinstr: mov r0, #MODE_SVC
- msr cpsr_c, r0 @ Enable interrupts
+fpundefinstr: set_cpsr_c r0, #MODE_SVC @ Enable interrupts
mov r0, lr
mov r1, sp
adrsvc al, lr, ret_from_exception
@@ -857,8 +904,7 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
alignment_trap r4, r7, __temp_abt
zero_fp
- mov r0, #MODE_SVC
- msr cpsr_c, r0 @ Enable interrupts
+ set_cpsr_c r0, #MODE_SVC @ Enable interrupts
mov r0, r5 @ address (pc)
mov r1, sp @ regs
bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
@@ -867,7 +913,7 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
* This is the return code to user mode for abort handlers
*/
ENTRY(ret_from_exception)
- get_current_task tsk
+ get_thread_info tsk
mov why, #0
b ret_to_user
@@ -877,16 +923,16 @@ ENTRY(fp_enter)
.text
/*
* Register switch for ARMv3 and ARMv4 processors
- * r0 = previous, r1 = next, return previous.
+ * r0 = previous thread_info, r1 = next thread_info, return previous.
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
mrs ip, cpsr
str ip, [sp, #-4]! @ Save cpsr_SVC
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldr r2, [r1, #TSS_DOMAIN]
+ str sp, [r0, #TI_CPU_SAVE] @ Save sp_SVC
+ ldr sp, [r1, #TI_CPU_SAVE] @ Get saved sp_SVC
+ ldr r2, [r1, #TI_CPU_DOMAIN]
ldr ip, [sp], #4
mcr p15, 0, r2, c3, c0 @ Set domain register
msr spsr, ip @ Save tasks CPSR into SPSR for this return
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index a10389665262..9dd36ce59501 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -9,6 +9,7 @@
*/
#include <linux/config.h>
#include "entry-header.S"
+#include <asm/thread_info.h>
/*
* We rely on the fact that R0 is at the bottom of the stack (due to
@@ -34,39 +35,42 @@ ENTRY(__do_softirq)
* stack.
*/
ret_fast_syscall:
-#error ldr r1, [tsk, #TSK_NEED_RESCHED]
-#error ldr r2, [tsk, #TSK_SIGPENDING]
- teq r1, #0 @ need_resched || sigpending
- teqeq r2, #0
- bne slow
+ set_cpsr_c r1, #PSR_I_BIT | MODE_SVC @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ bne ret_fast_work
fast_restore_user_regs
/*
* Ok, we need to do extra processing, enter the slow path.
*/
-slow: str r0, [sp, #S_R0+S_OFF]! @ returned r0
- b 1f
+ret_fast_work:
+ str r0, [sp, #S_R0+S_OFF]! @ returned r0
+ b work_pending
+work_resched:
+ bl SYMBOL_NAME(schedule)
/*
* "slow" syscall return path. "why" tells us if this was a real syscall.
*/
-reschedule:
- bl SYMBOL_NAME(schedule)
ENTRY(ret_to_user)
ret_slow_syscall:
-#error ldr r1, [tsk, #TSK_NEED_RESCHED]
-#error ldr r2, [tsk, #TSK_SIGPENDING]
-1: teq r1, #0 @ need_resched => schedule()
- bne reschedule
- teq r2, #0 @ sigpending => do_signal()
- blne __do_signal
+ set_cpsr_c r1, #PSR_I_BIT | MODE_SVC
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ beq no_work_pending
+work_pending:
+ tst r1, #_TIF_NEED_RESCHED
+ bne work_resched
+ tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING
+ blne __do_notify_resume
+no_work_pending:
restore_user_regs
-__do_signal:
- mov r0, #0 @ NULL 'oldset'
- mov r1, sp @ 'regs'
+__do_notify_resume:
+ mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
-#error b SYMBOL_NAME(do_signal) @ note the bl above sets lr
+ b SYMBOL_NAME(do_notify_resume) @ note the bl above sets lr
/*
* This is how we return from a fork. __switch_to will be calling us
@@ -75,14 +79,14 @@ __do_signal:
*/
ENTRY(ret_from_fork)
bl SYMBOL_NAME(schedule_tail)
- get_current_task tsk
- ldr ip, [tsk, #TSK_PTRACE] @ check for syscall tracing
+ get_thread_info tsk
+ ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
mov why, #1
- tst ip, #PT_TRACESYS @ are we tracing syscalls?
+ tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
beq ret_slow_syscall
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
-#error bl SYMBOL_NAME(syscall_trace)
+ bl SYMBOL_NAME(syscall_trace)
b ret_slow_syscall
@@ -134,12 +138,12 @@ ENTRY(vector_swi)
str r4, [sp, #-S_OFF]! @ push fifth arg
- get_current_task tsk
- ldr ip, [tsk, #TSK_PTRACE] @ check for syscall tracing
+ get_thread_info tsk
+ ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #OS_NUMBER << 20 @ check OS number
adr tbl, sys_call_table @ load syscall table pointer
- tst ip, #PT_TRACESYS @ are we tracing syscalls?
+ tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
adrsvc al, lr, ret_fast_syscall @ return address
@@ -160,7 +164,7 @@ ENTRY(vector_swi)
__sys_trace:
add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0]
-#error bl SYMBOL_NAME(syscall_trace)
+ bl SYMBOL_NAME(syscall_trace)
adrsvc al, lr, __sys_trace_return @ return address
add r1, sp, #S_R0 + S_OFF @ pointer to regs
@@ -173,7 +177,7 @@ __sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
-#error bl SYMBOL_NAME(syscall_trace)
+ bl SYMBOL_NAME(syscall_trace)
b ret_slow_syscall
.align 5
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 184145c2bb70..e6204e218a77 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -113,7 +113,7 @@
msr cpsr_c, \temp
.endm
- .macro get_current_task, rd
+ .macro get_thread_info, rd
mov \rd, sp, lsr #13
mov \rd, \rd, lsl #13
.endm
@@ -171,7 +171,7 @@
.macro initialise_traps_extra
.endm
- .macro get_current_task, rd
+ .macro get_thread_info, rd
mov \rd, sp, lsr #13
mov \rd, \rd, lsl #13
.endm
@@ -197,10 +197,10 @@
*
* We must set at least "tsk" and "why" when calling ret_with_reschedule.
*/
-scno .req r7 @ syscall number
-tbl .req r8 @ syscall table pointer
-why .req r8 @ Linux syscall (!= 0)
-tsk .req r9 @ current task
+scno .req r7 @ syscall number
+tbl .req r8 @ syscall table pointer
+why .req r8 @ Linux syscall (!= 0)
+tsk .req r9 @ current thread_info
/*
* Get the system call number.
@@ -217,3 +217,12 @@ tsk .req r9 @ current task
#endif
.endm
+ .macro set_cpsr_c, reg, mode
+#if 1
+ mov \reg, \mode
+ msr cpsr_c, \reg
+#else
+ msr cpsr_c, \mode
+#endif
+ .endm
+
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 36e7f142049b..a8b811c47902 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -149,7 +149,7 @@ __switch_data: .long __mmap_switched
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(__machine_arch_type)
.long SYMBOL_NAME(cr_alignment)
- .long SYMBOL_NAME(init_task_union)+8192
+ .long SYMBOL_NAME(init_thread_union)+8192
.type __ret, %function
__ret: ldr lr, __switch_data
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index 2e3ce17b0ca1..0cdc608bd862 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -16,7 +16,7 @@ static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
/*
- * Initial task structure.
+ * Initial thread structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
@@ -25,5 +25,13 @@ struct mm_struct init_mm = INIT_MM(init_mm);
*
* The things we do for performance..
*/
-union task_union init_task_union __attribute__((__section__(".init.task"))) =
- { INIT_TASK(init_task_union.task) };
+union thread_union init_thread_union
+ __attribute__((__section__(".init.task"))) =
+ { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 61b592b9747c..e0b2eac9faa0 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -19,6 +19,7 @@
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
+#include <linux/a.out.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
@@ -27,6 +28,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/leds.h>
+#include <asm/processor.h>
#include <asm/uaccess.h>
/*
@@ -83,9 +85,7 @@ void (*pm_power_off)(void);
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
- init_idle();
- current->nice = 20;
-
+ preempt_disable();
while (1) {
void (*idle)(void) = pm_idle;
if (!idle)
@@ -228,51 +228,61 @@ void show_fpregs(struct user_fp *regs)
/*
* Task structure and kernel stack allocation.
*/
-static struct task_struct *task_struct_head;
-static unsigned int nr_task_struct;
+static unsigned long *thread_info_head;
+static unsigned int nr_thread_info;
#ifdef CONFIG_CPU_32
#define EXTRA_TASK_STRUCT 4
+#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
+#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
#else
+extern unsigned long get_page_8k(int priority);
+extern void free_page_8k(unsigned long page);
+
#define EXTRA_TASK_STRUCT 0
+#define ll_alloc_task_struct() ((struct task_struct *)get_page_8k(GFP_KERNEL))
+#define ll_free_task_struct(p) free_page_8k((unsigned long)(p))
#endif
-struct task_struct *alloc_task_struct(void)
+struct thread_info *alloc_thread_info(void)
{
- struct task_struct *tsk;
+ struct thread_info *thread = NULL;
- if (EXTRA_TASK_STRUCT)
- tsk = task_struct_head;
- else
- tsk = NULL;
+ if (EXTRA_TASK_STRUCT) {
+ unsigned long *p = thread_info_head;
- if (tsk) {
- task_struct_head = tsk->next_task;
- nr_task_struct -= 1;
- } else
- tsk = ll_alloc_task_struct();
+ if (p) {
+ thread_info_head = (unsigned long *)p[0];
+ nr_thread_info -= 1;
+ }
+ thread = (struct thread_info *)p;
+ }
+
+ if (!thread)
+ thread = ll_alloc_task_struct();
#ifdef CONFIG_SYSRQ
/*
* The stack must be cleared if you want SYSRQ-T to
* give sensible stack usage information
*/
- if (tsk) {
- char *p = (char *)tsk;
+ if (thread) {
+ char *p = (char *)thread;
memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
}
#endif
- return tsk;
+ return thread;
}
-void __free_task_struct(struct task_struct *p)
+void free_thread_info(struct thread_info *thread)
{
- if (EXTRA_TASK_STRUCT && nr_task_struct < EXTRA_TASK_STRUCT) {
- p->next_task = task_struct_head;
- task_struct_head = p;
- nr_task_struct += 1;
+ if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) {
+ unsigned long *p = (unsigned long *)thread;
+ p[0] = (unsigned long)thread_info_head;
+ thread_info_head = p;
+ nr_thread_info += 1;
} else
- ll_free_task_struct(p);
+ ll_free_task_struct(thread);
}
/*
@@ -284,10 +294,13 @@ void exit_thread(void)
void flush_thread(void)
{
- memset(&current->thread.debug, 0, sizeof(struct debug_info));
- memset(&current->thread.fpstate, 0, sizeof(union fp_state));
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = current;
+
+ memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+ memset(&thread->fpstate, 0, sizeof(union fp_state));
+
current->used_math = 0;
- current->flags &= ~PF_USEDFPU;
}
void release_thread(struct task_struct *dead_task)
@@ -300,21 +313,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
- struct pt_regs * childregs;
- struct context_save_struct * save;
+ struct pt_regs *childregs;
+ struct cpu_context_save *save;
- atomic_set(&p->thread.refcount, 1);
-
- childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
+ childregs = ((struct pt_regs *)((unsigned long)p->thread_info + THREAD_SIZE)) - 1;
*childregs = *regs;
childregs->ARM_r0 = 0;
childregs->ARM_sp = esp;
- save = ((struct context_save_struct *)(childregs)) - 1;
+ save = ((struct cpu_context_save *)(childregs)) - 1;
*save = INIT_CSS;
save->pc |= (unsigned long)ret_from_fork;
- p->thread.save = save;
+ p->thread_info->cpu_context = save;
return 0;
}
@@ -324,10 +335,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
*/
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
- if (current->used_math)
- memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
+ struct thread_info *thread = current_thread_info();
+ int used_math = current->used_math;
+
+ if (used_math)
+ memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
- return current->used_math;
+ return used_math;
}
/*
@@ -405,7 +419,7 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
stack_page = 4096 + (unsigned long)p;
- fp = get_css_fp(&p->thread);
+ fp = thread_saved_fp(p);
do {
if (fp < stack_page || fp > 4092+stack_page)
return 0;
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 5b23dc653be1..5128ad63f8ee 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -9,6 +9,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -72,7 +73,7 @@ put_stack_long(struct task_struct *task, int offset, long data)
newregs = *regs;
newregs.uregs[offset] = data;
-
+
if (valid_user_regs(&newregs)) {
regs->uregs[offset] = data;
ret = 0;
@@ -455,9 +456,9 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
if ((unsigned long) data > _NSIG)
break;
if (request == PTRACE_SYSCALL)
- child->ptrace |= PT_TRACESYS;
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
else
- child->ptrace &= ~PT_TRACESYS;
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* make sure single-step breakpoint is gone. */
__ptrace_cancel_bpt(child);
@@ -490,7 +491,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
if ((unsigned long) data > _NSIG)
break;
child->thread.debug.nsaved = -1;
- child->ptrace &= ~PT_TRACESYS;
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);
@@ -547,7 +548,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
break;
/* we should check child->used_math here */
- ret = __copy_to_user((void *)data, &child->thread.fpstate,
+ ret = __copy_to_user((void *)data, &child->thread_info->fpstate,
sizeof(struct user_fp)) ? -EFAULT : 0;
break;
@@ -560,7 +561,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
break;
child->used_math = 1;
- ret = __copy_from_user(&child->thread.fpstate, (void *)data,
+ ret = __copy_from_user(&child->thread_info->fpstate, (void *)data,
sizeof(struct user_fp)) ? -EFAULT : 0;
break;
@@ -616,7 +617,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = do_ptrace(request, child, addr, data);
out_tsk:
- free_task_struct(child);
+ put_task_struct(child);
out:
unlock_kernel();
return ret;
@@ -626,8 +627,9 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
- if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
- != (PT_PTRACED|PT_TRACESYS))
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+ if (!(current->ptrace & PT_PTRACED))
return;
/*
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index fbec81f49714..52ae2e5e5a46 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -38,6 +38,10 @@
#define CONFIG_CMDLINE ""
#endif
+#ifdef CONFIG_PREEMPT
+spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+#endif
+
#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
char fpe_type[8];
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 6c2c1806921a..ca21ff1d4cec 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -480,6 +480,7 @@ static void
handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
+ struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
int usig = sig;
int ret;
@@ -487,8 +488,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
/*
* translate the signal
*/
- if (usig < 32 && tsk->exec_domain && tsk->exec_domain->signal_invmap)
- usig = tsk->exec_domain->signal_invmap[usig];
+ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
+ usig = thread->exec_domain->signal_invmap[usig];
/*
* Set up the stack frame
@@ -532,7 +533,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
{
struct k_sigaction *ka;
siginfo_t info;
@@ -678,3 +679,10 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
ptrace_set_bpt(current);
return 0;
}
+
+asmlinkage void
+do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+{
+ if (thread_flags & _TIF_SIGPENDING)
+ do_signal(NULL, regs, syscall);
+}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 29fdb8263764..17560d1ec6f9 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -115,7 +115,7 @@ static void dump_instr(struct pt_regs *regs)
static void dump_stack(struct task_struct *tsk, unsigned long sp)
{
- dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk);
+ dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk->thread_info);
}
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
@@ -146,7 +146,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
void show_trace_task(struct task_struct *tsk)
{
if (tsk != current) {
- unsigned int fp = tsk->thread.save->fp;
+ unsigned int fp = thread_saved_fp(tsk);
c_backtrace(fp, 0x10);
}
}
@@ -304,16 +304,17 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
static int bad_syscall(int n, struct pt_regs *regs)
{
+ struct thread_info *thread = current_thread_info();
siginfo_t info;
/* You might think just testing `handler' would be enough, but PER_LINUX
* points it to no_lcall7 to catch undercover SVr4 binaries. Gutted.
*/
- if (current->personality != PER_LINUX && current->exec_domain->handler) {
+ if (current->personality != PER_LINUX && thread->exec_domain->handler) {
/* Hand it off to iBCS. The extra parameter and consequent type
* forcing is necessary because of the weird ARM calling convention.
*/
- current->exec_domain->handler(n, regs);
+ thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
index 0e3ee26298f4..1e7f4a60fedb 100644
--- a/arch/arm/lib/csumpartial.S
+++ b/arch/arm/lib/csumpartial.S
@@ -41,7 +41,7 @@ td3 .req lr
tst buf, #1 @ odd address?
ldrneb td0, [buf], #1
subne len, len, #1
- adcnes sum, sum, td0, lsl #8
+ adcnes sum, sum, td0, lsl #byte(1)
.less4: tst len, #6
beq .less8_byte
@@ -56,7 +56,11 @@ td3 .req lr
ldrb td0, [buf], #1
ldrb td3, [buf], #1
sub len, len, #2
+#ifndef __ARMEB__
orr td0, td0, td3, lsl #8
+#else
+ orr td0, td3, td0, lsl #8
+#endif
#endif
adcs sum, sum, td0
tst len, #6
@@ -64,7 +68,7 @@ td3 .req lr
.less8_byte: tst len, #1 @ odd number of bytes
ldrneb td0, [buf], #1 @ include last byte
- adcnes sum, sum, td0 @ update checksum
+ adcnes sum, sum, td0, lsl #byte(0) @ update checksum
.done: adc r0, sum, #0 @ collect up the last carry
ldr td0, [sp], #4
@@ -76,7 +80,7 @@ td3 .req lr
.not_aligned: tst buf, #1 @ odd address
ldrneb td0, [buf], #1 @ make even
subne len, len, #1
- adcnes sum, sum, td0, lsl #8 @ update checksum
+ adcnes sum, sum, td0, lsl #byte(1) @ update checksum
tst buf, #2 @ 32-bit aligned?
#ifdef __ARM_ARCH_4__
@@ -86,7 +90,11 @@ td3 .req lr
ldrneb td0, [buf], #1
ldrneb ip, [buf], #1
subne len, len, #2
+#ifndef __ARMEB__
orrne td0, td0, ip, lsl #8
+#else
+ orrne td0, ip, td0, lsl #8
+#endif
#endif
adcnes sum, sum, td0 @ update checksum
mov pc, lr
diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S
index efc34e5c08df..5189c5f58fcd 100644
--- a/arch/arm/lib/csumpartialcopygeneric.S
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -36,16 +36,16 @@ sum .req r3
load1b ip
sub len, len, #1
- adcs sum, sum, ip, lsl #8 @ update checksum
+ adcs sum, sum, ip, lsl #byte(1) @ update checksum
strb ip, [dst], #1
tst dst, #2
moveq pc, lr @ dst is now 32bit aligned
.dst_16bit: load2b r8, ip
sub len, len, #2
- adcs sum, sum, r8
+ adcs sum, sum, r8, lsl #byte(0)
strb r8, [dst], #1
- adcs sum, sum, ip, lsl #8
+ adcs sum, sum, ip, lsl #byte(1)
strb ip, [dst], #1
mov pc, lr @ dst is now 32bit aligned
@@ -63,16 +63,16 @@ sum .req r3
/* Align dst */
load1b ip
sub len, len, #1
- adcs sum, sum, ip, lsl #8 @ update checksum
+ adcs sum, sum, ip, lsl #byte(1) @ update checksum
strb ip, [dst], #1
tst len, #6
beq .less8_byteonly
1: load2b r8, ip
sub len, len, #2
- adcs sum, sum, r8
+ adcs sum, sum, r8, lsl #byte(0)
strb r8, [dst], #1
- adcs sum, sum, ip, lsl #8
+ adcs sum, sum, ip, lsl #byte(1)
strb ip, [dst], #1
.less8_aligned: tst len, #6
bne 1b
@@ -80,7 +80,7 @@ sum .req r3
tst len, #1
beq .done
load1b r8
- adcs sum, sum, r8 @ update checksum
+ adcs sum, sum, r8, lsl #byte(0) @ update checksum
strb r8, [dst], #1
b .done
@@ -137,18 +137,19 @@ FN_ENTRY
4: ands len, len, #3
beq .done
- load1l r4
+ load1l r5
tst len, #2
+ mov r4, r5, lsr #byte(0)
beq .exit
- adcs sum, sum, r4, lsl #16
+ adcs sum, sum, r5, push #16
strb r4, [dst], #1
- mov r4, r4, lsr #8
+ mov r4, r5, lsr #byte(1)
strb r4, [dst], #1
- mov r4, r4, lsr #8
+ mov r4, r5, lsr #byte(2)
.exit: tst len, #1
strneb r4, [dst], #1
andne r4, r4, #255
- adcnes sum, sum, r4
+ adcnes sum, sum, r4, lsl #byte(0)
/*
* If the dst pointer was not 16-bit aligned, we
@@ -167,27 +168,27 @@ FN_ENTRY
adc sum, sum, #0 @ include C from dst alignment
and ip, src, #3
bic src, src, #3
- load1l r4
+ load1l r5
cmp ip, #2
beq .src2_aligned
bhi .src3_aligned
- mov r4, r4, lsr #8 @ C = 0
+ mov r4, r5, pull #8 @ C = 0
bics ip, len, #15
beq 2f
1: load4l r5, r6, r7, r8
- orr r4, r4, r5, lsl #24
- mov r5, r5, lsr #8
- orr r5, r5, r6, lsl #24
- mov r6, r6, lsr #8
- orr r6, r6, r7, lsl #24
- mov r7, r7, lsr #8
- orr r7, r7, r8, lsl #24
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
+ mov r6, r6, pull #8
+ orr r6, r6, r7, push #24
+ mov r7, r7, pull #8
+ orr r7, r7, r8, push #24
stmia dst!, {r4, r5, r6, r7}
adcs sum, sum, r4
adcs sum, sum, r5
adcs sum, sum, r6
adcs sum, sum, r7
- mov r4, r8, lsr #8
+ mov r4, r8, pull #8
sub ip, ip, #16
teq ip, #0
bne 1b
@@ -196,49 +197,50 @@ FN_ENTRY
tst ip, #8
beq 3f
load2l r5, r6
- orr r4, r4, r5, lsl #24
- mov r5, r5, lsr #8
- orr r5, r5, r6, lsl #24
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
stmia dst!, {r4, r5}
adcs sum, sum, r4
adcs sum, sum, r5
- mov r4, r6, lsr #8
+ mov r4, r6, pull #8
tst ip, #4
beq 4f
3: load1l r5
- orr r4, r4, r5, lsl #24
+ orr r4, r4, r5, push #24
str r4, [dst], #4
adcs sum, sum, r4
- mov r4, r5, lsr #8
4: ands len, len, #3
beq .done
+ mov r4, r5, lsr #byte(1)
tst len, #2
beq .exit
- adcs sum, sum, r4, lsl #16
+ bic r5, r5, #0xff << byte(0)
+ adcs sum, sum, r5, push #8
strb r4, [dst], #1
- mov r4, r4, lsr #8
+ mov r4, r5, lsr #byte(2)
strb r4, [dst], #1
- mov r4, r4, lsr #8
+ mov r4, r5, lsr #byte(3)
b .exit
-.src2_aligned: mov r4, r4, lsr #16
+.src2_aligned: mov r4, r5, pull #16
adds sum, sum, #0
bics ip, len, #15
beq 2f
1: load4l r5, r6, r7, r8
- orr r4, r4, r5, lsl #16
- mov r5, r5, lsr #16
- orr r5, r5, r6, lsl #16
- mov r6, r6, lsr #16
- orr r6, r6, r7, lsl #16
- mov r7, r7, lsr #16
- orr r7, r7, r8, lsl #16
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
+ mov r6, r6, pull #16
+ orr r6, r6, r7, push #16
+ mov r7, r7, pull #16
+ orr r7, r7, r8, push #16
stmia dst!, {r4, r5, r6, r7}
adcs sum, sum, r4
adcs sum, sum, r5
adcs sum, sum, r6
adcs sum, sum, r7
- mov r4, r8, lsr #16
+ mov r4, r8, pull #16
sub ip, ip, #16
teq ip, #0
bne 1b
@@ -247,51 +249,51 @@ FN_ENTRY
tst ip, #8
beq 3f
load2l r5, r6
- orr r4, r4, r5, lsl #16
- mov r5, r5, lsr #16
- orr r5, r5, r6, lsl #16
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
stmia dst!, {r4, r5}
adcs sum, sum, r4
adcs sum, sum, r5
- mov r4, r6, lsr #16
+ mov r4, r6, pull #16
tst ip, #4
beq 4f
3: load1l r5
- orr r4, r4, r5, lsl #16
+ orr r4, r4, r5, push #16
str r4, [dst], #4
adcs sum, sum, r4
- mov r4, r5, lsr #16
4: ands len, len, #3
beq .done
+ mov r4, r5, lsr #byte(2)
tst len, #2
beq .exit
- adcs sum, sum, r4, lsl #16
+ adcs sum, sum, r5, pull #16
strb r4, [dst], #1
- mov r4, r4, lsr #8
+ mov r4, r5, lsr #byte(3)
strb r4, [dst], #1
tst len, #1
beq .done
load1b r4
b .exit
-.src3_aligned: mov r4, r4, lsr #24
+.src3_aligned: mov r4, r5, pull #24
adds sum, sum, #0
bics ip, len, #15
beq 2f
1: load4l r5, r6, r7, r8
- orr r4, r4, r5, lsl #8
- mov r5, r5, lsr #24
- orr r5, r5, r6, lsl #8
- mov r6, r6, lsr #24
- orr r6, r6, r7, lsl #8
- mov r7, r7, lsr #24
- orr r7, r7, r8, lsl #8
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
+ mov r6, r6, pull #24
+ orr r6, r6, r7, push #8
+ mov r7, r7, pull #24
+ orr r7, r7, r8, push #8
stmia dst!, {r4, r5, r6, r7}
adcs sum, sum, r4
adcs sum, sum, r5
adcs sum, sum, r6
adcs sum, sum, r7
- mov r4, r8, lsr #24
+ mov r4, r8, pull #24
sub ip, ip, #16
teq ip, #0
bne 1b
@@ -300,28 +302,29 @@ FN_ENTRY
tst ip, #8
beq 3f
load2l r5, r6
- orr r4, r4, r5, lsl #8
- mov r5, r5, lsr #24
- orr r5, r5, r6, lsl #8
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
stmia dst!, {r4, r5}
adcs sum, sum, r4
adcs sum, sum, r5
- mov r4, r6, lsr #24
+ mov r4, r6, pull #24
tst ip, #4
beq 4f
3: load1l r5
- orr r4, r4, r5, lsl #8
+ orr r4, r4, r5, push #8
str r4, [dst], #4
adcs sum, sum, r4
- mov r4, r5, lsr #24
4: ands len, len, #3
beq .done
+ mov r4, r5, lsr #byte(3)
tst len, #2
beq .exit
- adcs sum, sum, r4, lsl #16
+ adcs sum, sum, r5, pull #24
strb r4, [dst], #1
- load1l r4
+ load1l r5
+ mov r4, r5, lsr #byte(0)
strb r4, [dst], #1
- adcs sum, sum, r4, lsl #24
- mov r4, r4, lsr #8
+ adcs sum, sum, r4, push #24
+ mov r4, r5, lsr #byte(1)
b .exit
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 6278b2a60afb..fb60cc05d2ec 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -27,12 +27,13 @@
* Note also that it is intended that __get_user_bad is not global.
*/
#include <asm/constants.h>
+#include <asm/thread_info.h>
.global __get_user_1
__get_user_1:
bic r1, sp, #0x1f00
bic r1, r1, #0x00ff
- ldr r1, [r1, #TSK_ADDR_LIMIT]
+ ldr r1, [r1, #TI_ADDR_LIMIT]
sub r1, r1, #1
cmp r0, r1
1: ldrlsbt r1, [r0]
@@ -44,7 +45,7 @@ __get_user_1:
__get_user_2:
bic r2, sp, #0x1f00
bic r2, r2, #0x00ff
- ldr r2, [r2, #TSK_ADDR_LIMIT]
+ ldr r2, [r2, #TI_ADDR_LIMIT]
sub r2, r2, #2
cmp r0, r2
2: ldrlsbt r1, [r0], #1
@@ -62,7 +63,7 @@ __get_user_2:
__get_user_4:
bic r1, sp, #0x1f00
bic r1, r1, #0x00ff
- ldr r1, [r1, #TSK_ADDR_LIMIT]
+ ldr r1, [r1, #TI_ADDR_LIMIT]
sub r1, r1, #4
cmp r0, r1
4: ldrlst r1, [r0]
@@ -74,7 +75,7 @@ __get_user_4:
__get_user_8:
bic r2, sp, #0x1f00
bic r2, r2, #0x00ff
- ldr r2, [r2, #TSK_ADDR_LIMIT]
+ ldr r2, [r2, #TI_ADDR_LIMIT]
sub r2, r2, #8
cmp r0, r2
5: ldrlst r1, [r0], #4
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index b98b89a306d8..81d8c5d14435 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -27,12 +27,13 @@
* Note also that it is intended that __put_user_bad is not global.
*/
#include <asm/constants.h>
+#include <asm/thread_info.h>
.global __put_user_1
__put_user_1:
bic r2, sp, #0x1f00
bic r2, r2, #0x00ff
- ldr r2, [r2, #TSK_ADDR_LIMIT]
+ ldr r2, [r2, #TI_ADDR_LIMIT]
sub r2, r2, #1
cmp r0, r2
1: strlsbt r1, [r0]
@@ -44,7 +45,7 @@ __put_user_1:
__put_user_2:
bic r2, sp, #0x1f00
bic r2, r2, #0x00ff
- ldr r2, [r2, #TSK_ADDR_LIMIT]
+ ldr r2, [r2, #TI_ADDR_LIMIT]
sub r2, r2, #2
cmp r0, r2
movls r2, r1, lsr #8
@@ -63,7 +64,7 @@ __put_user_2:
__put_user_4:
bic r2, sp, #0x1f00
bic r2, r2, #0x00ff
- ldr r2, [r2, #TSK_ADDR_LIMIT]
+ ldr r2, [r2, #TI_ADDR_LIMIT]
sub r2, r2, #4
cmp r0, r2
4: strlst r1, [r0]
@@ -75,7 +76,7 @@ __put_user_4:
__put_user_8:
bic ip, sp, #0x1f00
bic ip, ip, #0x00ff
- ldr ip, [ip, #TSK_ADDR_LIMIT]
+ ldr ip, [ip, #TI_ADDR_LIMIT]
sub ip, ip, #8
cmp r0, ip
5: strlst r1, [r0], #4
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
index 7ef7fa439b35..fa923f026f15 100644
--- a/arch/arm/lib/strrchr.S
+++ b/arch/arm/lib/strrchr.S
@@ -18,7 +18,7 @@ ENTRY(strrchr)
mov r3, #0
1: ldrb r2, [r0], #1
teq r2, r1
- moveq r3, r0
+ subeq r3, r0, #1
teq r2, #0
bne 1b
mov r0, r3
diff --git a/arch/arm/mach-adifcc/arch.c b/arch/arm/mach-adifcc/arch.c
index 353af8e71fe2..eeaf870fcc4c 100644
--- a/arch/arm/mach-adifcc/arch.c
+++ b/arch/arm/mach-adifcc/arch.c
@@ -7,7 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -33,7 +33,7 @@ fixup_adifcc(struct machine_desc *desc, struct param_struct *params,
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( 0xc0800000, 3*1024*1024 );
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
#endif
}
diff --git a/arch/arm/mach-adifcc/irq.c b/arch/arm/mach-adifcc/irq.c
index de4067072153..e8e659a54ef4 100644
--- a/arch/arm/mach-adifcc/irq.c
+++ b/arch/arm/mach-adifcc/irq.c
@@ -12,8 +12,6 @@
* 80200 on chip interrupts. That'll change once the hardware adds
* support for PCI though.
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-anakin/arch.c b/arch/arm/mach-anakin/arch.c
index 4361fabc727c..c72858e44c52 100644
--- a/arch/arm/mach-anakin/arch.c
+++ b/arch/arm/mach-anakin/arch.c
@@ -30,7 +30,7 @@ static void __init
fixup_anakin(struct machine_desc *desc, struct param_struct *unused,
char **cmdline, struct meminfo *mi)
{
- ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
setup_initrd(0xc0800000, 4 * 1024 * 1024);
}
diff --git a/arch/arm/mach-arc/arch.c b/arch/arm/mach-arc/arch.c
index 00472e7ccf35..216b4188ab03 100644
--- a/arch/arm/mach-arc/arch.c
+++ b/arch/arm/mach-arc/arch.c
@@ -9,6 +9,7 @@
*
* Architecture specific fixups.
*/
+#include <linux/config.h>
#include <linux/tty.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index 9764b379be50..2fc5c29aef12 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/string.h>
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 5ab0067a249c..7eb131f9de8d 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -18,7 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -46,7 +45,7 @@ epxa10db_fixup(struct machine_desc *desc, struct param_struct *params,
mi->bank[0].node = 0;
/*
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd(0xc0200000, 6*1024*1024);
*/
diff --git a/arch/arm/mach-ftvpci/core.c b/arch/arm/mach-ftvpci/core.c
index d9d2f3fea3c6..3e073e527d75 100644
--- a/arch/arm/mach-ftvpci/core.c
+++ b/arch/arm/mach-ftvpci/core.c
@@ -8,7 +8,6 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 914d097a74e8..108999083e44 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -20,6 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
diff --git a/arch/arm/mach-iop310/arch.c b/arch/arm/mach-iop310/arch.c
index 3e6956c2c7b1..bda5f721605e 100644
--- a/arch/arm/mach-iop310/arch.c
+++ b/arch/arm/mach-iop310/arch.c
@@ -9,7 +9,7 @@
* published by the Free Software Foundation.
*
*/
-
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -44,7 +44,7 @@ fixup_iq80310(struct machine_desc *desc, struct param_struct *params,
#elif defined(CONFIG_BLK_DEV_INITRD)
setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE );
setup_initrd( 0xc0800000, 4*1024*1024 );
- ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); /* /dev/ram */
#endif
}
diff --git a/arch/arm/mach-iop310/iop310-irq.c b/arch/arm/mach-iop310/iop310-irq.c
index 30cc61408a5f..1be67fc26932 100644
--- a/arch/arm/mach-iop310/iop310-irq.c
+++ b/arch/arm/mach-iop310/iop310-irq.c
@@ -13,8 +13,6 @@
* Added IOP310 chipset and IQ80310 board demuxing, masking code. - DS
*
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-iop310/iq80310-irq.c b/arch/arm/mach-iop310/iq80310-irq.c
index 4347f13fb092..853dabe7d5dd 100644
--- a/arch/arm/mach-iop310/iq80310-irq.c
+++ b/arch/arm/mach-iop310/iq80310-irq.c
@@ -14,8 +14,6 @@
* Moved demux from asm to C - DS
* Fixes for various revision boards - DS
*/
-
-#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-iop310/mm.c b/arch/arm/mach-iop310/mm.c
index 4ef0c65ba677..d2a7b08a6f03 100644
--- a/arch/arm/mach-iop310/mm.c
+++ b/arch/arm/mach-iop310/mm.c
@@ -13,7 +13,7 @@
* option) any later version.
*
*/
-
+#include <linux/config.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-iop310/xs80200-irq.c b/arch/arm/mach-iop310/xs80200-irq.c
index bc0fbf7e6af9..bae1ad8f3586 100644
--- a/arch/arm/mach-iop310/xs80200-irq.c
+++ b/arch/arm/mach-iop310/xs80200-irq.c
@@ -10,8 +10,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 8c91b16b0700..3347a97028df 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -5,6 +5,7 @@
*
* Extra MM routines for L7200 architecture
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <asm/hardware.h>
@@ -90,7 +91,7 @@ fixup_l7200(struct machine_desc *desc, struct param_struct *unused,
mi->bank[0].size = (32*1024*1024);
mi->bank[0].node = 0;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
setup_initrd( __phys_to_virt(0xf1000000), 0x005dac7b);
diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c
index c2acd141e3ec..eedeabb18634 100644
--- a/arch/arm/mach-sa1100/adsbitsy.c
+++ b/arch/arm/mach-sa1100/adsbitsy.c
@@ -26,8 +26,6 @@
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
-#include <asm/arch/irq.h>
-
#include "generic.h"
#include "sa1111.h"
@@ -120,7 +118,7 @@ fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 32*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/brutus.c b/arch/arm/mach-sa1100/brutus.c
index f9b50ac8235b..0e4c4ba3faad 100644
--- a/arch/arm/mach-sa1100/brutus.c
+++ b/arch/arm/mach-sa1100/brutus.c
@@ -32,7 +32,7 @@ fixup_brutus(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 3, 0xd8000000, 4*1024*1024 );
mi->nr_banks = 4;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 73868b2ebc63..bdbb7b8280b2 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mach-sa1100/cerf.c
*/
-
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
@@ -55,7 +55,7 @@ fixup_cerf(struct machine_desc *desc, struct param_struct *params,
#error "Undefined memory size for Cerfboard."
#endif
-// ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+// ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
// setup_ramdisk(1, 0, 0, 8192);
// // Save 2Meg for RAMDisk
// setup_initrd(0xc0500000, 3*1024*1024);
diff --git a/arch/arm/mach-sa1100/empeg.c b/arch/arm/mach-sa1100/empeg.c
index 5ea32f2f5880..682e99d522d2 100644
--- a/arch/arm/mach-sa1100/empeg.c
+++ b/arch/arm/mach-sa1100/empeg.c
@@ -24,7 +24,7 @@ fixup_empeg(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 1, 0xc8000000, 4*1024*1024 );
mi->nr_banks = 2;
- ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
+ ROOT_DEV = mk_kdev( 3, 1 ); /* /dev/hda1 */
setup_ramdisk( 1, 0, 0, 4096 );
setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
}
diff --git a/arch/arm/mach-sa1100/flexanet.c b/arch/arm/mach-sa1100/flexanet.c
index fb7d57ea9567..8ce7cea310c8 100644
--- a/arch/arm/mach-sa1100/flexanet.c
+++ b/arch/arm/mach-sa1100/flexanet.c
@@ -9,8 +9,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -113,7 +111,6 @@ static void flexanet_set_mctrl(struct uart_port *port, u_int mctrl)
*
* get_mctrl : set state of modem control lines
* set_mctrl : set the modem control lines
- * enable_ms : enable modem-status interrupts
* pm : power-management. Turn device on/off.
*
*/
@@ -121,7 +118,6 @@ static struct sa1100_port_fns flexanet_port_fns __initdata =
{
set_mctrl : flexanet_set_mctrl,
get_mctrl : flexanet_get_mctrl,
- enable_ms : NULL,
pm : NULL,
};
@@ -168,7 +164,7 @@ fixup_flexanet(struct machine_desc *desc, struct param_struct *params,
mi->nr_banks = 1;
/* setup ramdisk */
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( 0xc0800000, 3*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/freebird.c b/arch/arm/mach-sa1100/freebird.c
index 3ba93785ab4c..3a28685b6a21 100644
--- a/arch/arm/mach-sa1100/freebird.c
+++ b/arch/arm/mach-sa1100/freebird.c
@@ -58,7 +58,7 @@ fixup_freebird(struct machine_desc *desc, struct param_struct *params,
#ifdef CONFIG_SA1100_FREEBIRD_OLD
SET_BANK( 0, 0xc0000000, 32*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0 ,0 , 8192 );
setup_initrd( 0xc0800000, 3*1024*1024 );
#endif
diff --git a/arch/arm/mach-sa1100/graphicsclient.c b/arch/arm/mach-sa1100/graphicsclient.c
index 037e950c29f7..6bcfcbdaba25 100644
--- a/arch/arm/mach-sa1100/graphicsclient.c
+++ b/arch/arm/mach-sa1100/graphicsclient.c
@@ -130,7 +130,7 @@ fixup_graphicsclient(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 1, 0xc8000000, 16*1024*1024 );
mi->nr_banks = 2;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c
index 9972bdbf661c..4366a75bc572 100644
--- a/arch/arm/mach-sa1100/graphicsmaster.c
+++ b/arch/arm/mach-sa1100/graphicsmaster.c
@@ -193,7 +193,7 @@ fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 1, 0xc8000000, 16*1024*1024 );
mi->nr_banks = 2;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index af6fef821ae2..86e1c81a8db1 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -19,8 +19,6 @@
* and abstracted EGPIO interface.
*
*/
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mach-sa1100/huw_webpanel.c b/arch/arm/mach-sa1100/huw_webpanel.c
index 969e7c84ce72..41a8ec5eedbf 100644
--- a/arch/arm/mach-sa1100/huw_webpanel.c
+++ b/arch/arm/mach-sa1100/huw_webpanel.c
@@ -2,8 +2,6 @@
* linux/arch/arm/mach-sa1100/huw_webpanel.c
*
*/
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -66,7 +64,7 @@ fixup_huw_webpanel(struct machine_desc *desc, struct param_struct *params,
**/
SET_BANK( 0, 0xc0000000, ((32*1024 - (256 + 32)) * 1024));
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 8*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 8c0412148bda..64021ff67a35 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -9,8 +9,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
diff --git a/arch/arm/mach-sa1100/leds-adsbitsy.c b/arch/arm/mach-sa1100/leds-adsbitsy.c
index e76286129897..5b8ca7119a90 100644
--- a/arch/arm/mach-sa1100/leds-adsbitsy.c
+++ b/arch/arm/mach-sa1100/leds-adsbitsy.c
@@ -28,7 +28,7 @@ void adsbitsy_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -92,5 +92,5 @@ void adsbitsy_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
diff --git a/arch/arm/mach-sa1100/leds-graphicsclient.c b/arch/arm/mach-sa1100/leds-graphicsclient.c
index c872653a7734..439975e65ebe 100644
--- a/arch/arm/mach-sa1100/leds-graphicsclient.c
+++ b/arch/arm/mach-sa1100/leds-graphicsclient.c
@@ -30,7 +30,7 @@ void graphicsclient_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -100,5 +100,5 @@ void graphicsclient_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
diff --git a/arch/arm/mach-sa1100/leds-graphicsmaster.c b/arch/arm/mach-sa1100/leds-graphicsmaster.c
index b900167a93f2..297dc613a100 100644
--- a/arch/arm/mach-sa1100/leds-graphicsmaster.c
+++ b/arch/arm/mach-sa1100/leds-graphicsmaster.c
@@ -30,7 +30,7 @@ void graphicsmaster_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -100,5 +100,5 @@ void graphicsmaster_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
diff --git a/arch/arm/mach-sa1100/leds-system3.c b/arch/arm/mach-sa1100/leds-system3.c
index f9b68a1f044f..364ab67af7e1 100644
--- a/arch/arm/mach-sa1100/leds-system3.c
+++ b/arch/arm/mach-sa1100/leds-system3.c
@@ -26,7 +26,6 @@
*
*
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
index 8e3a7ab50985..5d08e1e713d8 100644
--- a/arch/arm/mach-sa1100/leds.c
+++ b/arch/arm/mach-sa1100/leds.c
@@ -5,7 +5,6 @@
*
* Copyright (C) 2001 Nicolas Pitre
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <asm/leds.h>
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index d7f7ab213481..8aad8bd919b3 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -23,7 +23,7 @@ fixup_nanoengine(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 32*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
diff --git a/arch/arm/mach-sa1100/omnimeter.c b/arch/arm/mach-sa1100/omnimeter.c
index 8258fdc19981..76eaa1fb724d 100644
--- a/arch/arm/mach-sa1100/omnimeter.c
+++ b/arch/arm/mach-sa1100/omnimeter.c
@@ -47,7 +47,7 @@ fixup_omnimeter(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 16*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xd0000000), 0x00400000 );
}
diff --git a/arch/arm/mach-sa1100/pangolin.c b/arch/arm/mach-sa1100/pangolin.c
index a9637352a45d..f27c7f4aa836 100644
--- a/arch/arm/mach-sa1100/pangolin.c
+++ b/arch/arm/mach-sa1100/pangolin.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mach-sa1100/pangolin.c
*/
-
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
@@ -23,7 +23,7 @@ fixup_pangolin(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 128*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 16384 );
setup_initrd( 0xc0800000, 3*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/pfs168.c b/arch/arm/mach-sa1100/pfs168.c
index 19085bffb658..8820c4a97b3f 100644
--- a/arch/arm/mach-sa1100/pfs168.c
+++ b/arch/arm/mach-sa1100/pfs168.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mach-sa1100/pfs168.c
*/
-
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
@@ -96,7 +96,7 @@ fixup_pfs168(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 16*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( 0xc0800000, 3*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 6003b5d71d6b..49c608198034 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -28,7 +28,7 @@ fixup_pleb(struct machine_desc *desc, struct param_struct *params,
/* make it 1 if a 16MB memory card is used */
mi->nr_banks = 2; /* Default 32MB */
- ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0);
setup_ramdisk(1, 0, 0, 8192);
setup_initrd(0xc0400000, 4*1024*1024);
}
diff --git a/arch/arm/mach-sa1100/sa1111-pcibuf.c b/arch/arm/mach-sa1100/sa1111-pcibuf.c
index 2863c19338cf..f3c3e730dc25 100644
--- a/arch/arm/mach-sa1100/sa1111-pcibuf.c
+++ b/arch/arm/mach-sa1100/sa1111-pcibuf.c
@@ -13,7 +13,6 @@
*
* 06/13/2001 - created.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/arch/arm/mach-sa1100/sherman.c b/arch/arm/mach-sa1100/sherman.c
index 658d164234f8..3fe87bc3ad32 100644
--- a/arch/arm/mach-sa1100/sherman.c
+++ b/arch/arm/mach-sa1100/sherman.c
@@ -24,7 +24,7 @@ fixup_sherman(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 1, 0xc8000000, 64*1024*1024 );
mi->nr_banks = 2;
- ROOT_DEV = MKDEV( 60, 2 );
+ ROOT_DEV = mk_kdev( 60, 2 );
setup_ramdisk( 1, 0, 0, 8192 );
// setup_initrd( 0xc0400000, 8*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 514d6ca3706b..8f5e76d1e220 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -50,7 +50,7 @@ fixup_simpad(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 32*1024*1024 );
#endif
mi->nr_banks = 1;
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c
index 028558a56a07..9745fea25720 100644
--- a/arch/arm/mach-sa1100/system3.c
+++ b/arch/arm/mach-sa1100/system3.c
@@ -54,8 +54,6 @@
#include <asm/mach/irq.h>
#include <asm/mach/serial_sa1100.h>
-#include <asm/arch/irq.h>
-
#include <linux/serial_core.h>
#include "generic.h"
@@ -227,7 +225,7 @@ static void __init fixup_system3(struct machine_desc *desc,
{
DPRINTK( "%s\n", "START" );
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ ROOT_DEV = mk_kdev(RAMDISK_MAJOR,0);
setup_ramdisk( 1, 0, 0, 8192 );
setup_initrd( 0xc0800000, 8*1024*1024 );
}
diff --git a/arch/arm/mach-sa1100/victor.c b/arch/arm/mach-sa1100/victor.c
index 4fca53c5f0ab..a4378e32d4a2 100644
--- a/arch/arm/mach-sa1100/victor.c
+++ b/arch/arm/mach-sa1100/victor.c
@@ -48,7 +48,7 @@ fixup_victor(struct machine_desc *desc, struct param_struct *params,
SET_BANK( 0, 0xc0000000, 4*1024*1024 );
mi->nr_banks = 1;
- ROOT_DEV = MKDEV( 60, 2 );
+ ROOT_DEV = mk_kdev( 60, 2 );
/* Get command line parameters passed from the loader (if any) */
if( *((char*)0xc0000000) )
diff --git a/arch/arm/mach-sa1100/yopy.c b/arch/arm/mach-sa1100/yopy.c
index 770636e145d1..fa8b5c8fc9c6 100644
--- a/arch/arm/mach-sa1100/yopy.c
+++ b/arch/arm/mach-sa1100/yopy.c
@@ -1,8 +1,6 @@
/*
* linux/arch/arm/mach-sa1100/yopy.c
*/
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 6ff2d5385d5d..0e76c39dc3f5 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -30,6 +30,10 @@
#include <asm/pgtable.h>
#include <asm/unaligned.h>
+extern void
+do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
+ int error_code, struct pt_regs *regs);
+
/*
* 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
* /proc/sys/debug/alignment, modified and integrated into
@@ -163,9 +167,9 @@ union offset_union {
#define TYPE_LDST 2
#define TYPE_DONE 3
-#define get8_unaligned_check(val,addr,err) \
+#define __get8_unaligned_check(ins,val,addr,err) \
__asm__( \
- "1: ldrb %1, [%2], #1\n" \
+ "1: "ins" %1, [%2], #1\n" \
"2:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -179,39 +183,49 @@ union offset_union {
: "=r" (err), "=&r" (val), "=r" (addr) \
: "0" (err), "2" (addr))
-#define get8t_unaligned_check(val,addr,err) \
- __asm__( \
- "1: ldrbt %1, [%2], #1\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: mov %0, #1\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous\n" \
- : "=r" (err), "=&r" (val), "=r" (addr) \
- : "0" (err), "2" (addr))
+#define __get16_unaligned_check(ins,val,addr) \
+ do { \
+ unsigned int err = 0, v, a = addr; \
+ __get8_unaligned_check(ins,val,a,err); \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << 8; \
+ if (err) \
+ goto fault; \
+ } while (0)
+
+#define get16_unaligned_check(val,addr) \
+ __get16_unaligned_check("ldrb",val,addr)
+
+#define get16t_unaligned_check(val,addr) \
+ __get16_unaligned_check("ldrbt",val,addr)
-#define get16_unaligned_check(val,addr) \
+#define __get32_unaligned_check(ins,val,addr) \
do { \
unsigned int err = 0, v, a = addr; \
- get8_unaligned_check(val,a,err); \
- get8_unaligned_check(v,a,err); \
+ __get8_unaligned_check(ins,val,a,err); \
+ __get8_unaligned_check(ins,v,a,err); \
val |= v << 8; \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << 16; \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << 24; \
if (err) \
goto fault; \
} while (0)
-#define put16_unaligned_check(val,addr) \
+#define get32_unaligned_check(val,addr) \
+ __get32_unaligned_check("ldrb",val,addr)
+
+#define get32t_unaligned_check(val,addr) \
+ __get32_unaligned_check("ldrbt",val,addr)
+
+#define __put16_unaligned_check(ins,val,addr) \
do { \
unsigned int err = 0, v = val, a = addr; \
__asm__( \
- "1: strb %1, [%2], #1\n" \
+ "1: "ins" %1, [%2], #1\n" \
" mov %1, %1, lsr #8\n" \
- "2: strb %1, [%2]\n" \
+ "2: "ins" %1, [%2]\n" \
"3:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -229,6 +243,12 @@ union offset_union {
goto fault; \
} while (0)
+#define put16_unaligned_check(val,addr) \
+ __put16_unaligned_check("strb",val,addr)
+
+#define put16t_unaligned_check(val,addr) \
+ __put16_unaligned_check("strbt",val,addr)
+
#define __put32_unaligned_check(ins,val,addr) \
do { \
unsigned int err = 0, v = val, a = addr; \
@@ -259,37 +279,9 @@ union offset_union {
goto fault; \
} while (0)
-#define get32_unaligned_check(val,addr) \
- do { \
- unsigned int err = 0, v, a = addr; \
- get8_unaligned_check(val,a,err); \
- get8_unaligned_check(v,a,err); \
- val |= v << 8; \
- get8_unaligned_check(v,a,err); \
- val |= v << 16; \
- get8_unaligned_check(v,a,err); \
- val |= v << 24; \
- if (err) \
- goto fault; \
- } while (0)
-
#define put32_unaligned_check(val,addr) \
__put32_unaligned_check("strb", val, addr)
-#define get32t_unaligned_check(val,addr) \
- do { \
- unsigned int err = 0, v, a = addr; \
- get8t_unaligned_check(val,a,err); \
- get8t_unaligned_check(v,a,err); \
- val |= v << 8; \
- get8t_unaligned_check(v,a,err); \
- val |= v << 16; \
- get8t_unaligned_check(v,a,err); \
- val |= v << 24; \
- if (err) \
- goto fault; \
- } while (0)
-
#define put32t_unaligned_check(val,addr) \
__put32_unaligned_check("strbt", val, addr)
@@ -319,6 +311,9 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
ai_half += 1;
+ if (user_mode(regs))
+ goto user;
+
if (LDST_L_BIT(instr)) {
unsigned long val;
get16_unaligned_check(val, addr);
@@ -333,12 +328,27 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
return TYPE_LDST;
-swp:
+ user:
+ if (LDST_L_BIT(instr)) {
+ unsigned long val;
+ get16t_unaligned_check(val, addr);
+
+ /* signed half-word? */
+ if (instr & 0x40)
+ val = (signed long)((signed short) val);
+
+ regs->uregs[rd] = val;
+ } else
+ put16t_unaligned_check(regs->uregs[rd], addr);
+
+ return TYPE_LDST;
+
+ swp:
printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
-bad:
+ bad:
return TYPE_ERROR;
-fault:
+ fault:
return TYPE_FAULT;
}
@@ -349,23 +359,27 @@ do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *reg
ai_word += 1;
- if (!LDST_P_BIT(instr) && LDST_W_BIT(instr))
+ if ((!LDST_P_BIT(instr) && LDST_W_BIT(instr)) || user_mode(regs))
goto trans;
- if (LDST_L_BIT(instr))
- get32_unaligned_check(regs->uregs[rd], addr);
- else
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ } else
put32_unaligned_check(regs->uregs[rd], addr);
return TYPE_LDST;
-trans:
- if (LDST_L_BIT(instr))
- get32t_unaligned_check(regs->uregs[rd], addr);
- else
+ trans:
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32t_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ } else
put32t_unaligned_check(regs->uregs[rd], addr);
return TYPE_LDST;
-fault:
+ fault:
return TYPE_FAULT;
}
@@ -431,14 +445,31 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
}
#endif
- for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
- if (regbits & 1) {
- if (LDST_L_BIT(instr))
- get32_unaligned_check(regs->uregs[rd], eaddr);
- else
- put32_unaligned_check(regs->uregs[rd], eaddr);
- eaddr += 4;
- }
+ if (user_mode(regs)) {
+ for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+ regbits >>= 1, rd += 1)
+ if (regbits & 1) {
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32t_unaligned_check(val, eaddr);
+ regs->uregs[rd] = val;
+ } else
+ put32t_unaligned_check(regs->uregs[rd], eaddr);
+ eaddr += 4;
+ }
+ } else {
+ for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+ regbits >>= 1, rd += 1)
+ if (regbits & 1) {
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32_unaligned_check(val, eaddr);
+ regs->uregs[rd] = val;
+ } else
+ put32_unaligned_check(regs->uregs[rd], eaddr);
+ eaddr += 4;
+ }
+ }
if (LDST_W_BIT(instr))
regs->uregs[rn] = newaddr;
@@ -539,7 +570,7 @@ int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
return 0;
-bad_or_fault:
+ bad_or_fault:
if (type == TYPE_ERROR)
goto bad;
regs->ARM_pc -= 4;
@@ -549,7 +580,7 @@ bad_or_fault:
do_bad_area(current, current->mm, addr, error_code, regs);
return 0;
-bad:
+ bad:
/*
* Oops, we didn't handle the instruction.
*/
diff --git a/arch/arm/tools/getconstants.c b/arch/arm/tools/getconstants.c
index b75ba79e384d..e6b3395083cd 100644
--- a/arch/arm/tools/getconstants.c
+++ b/arch/arm/tools/getconstants.c
@@ -32,23 +32,21 @@
#endif
#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
+#define OFF_VMA(n) (unsigned long)&(((struct vm_area_struct *)0)->n)
#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off))
void func(void)
{
-#error DEFN("TSK_SIGPENDING", OFF_TSK(sigpending));
-DEFN("TSK_ADDR_LIMIT", OFF_TSK(addr_limit));
-#error DEFN("TSK_NEED_RESCHED", OFF_TSK(need_resched));
-#error DEFN("TSK_PTRACE", OFF_TSK(ptrace));
DEFN("TSK_USED_MATH", OFF_TSK(used_math));
+DEFN("TSK_ACTIVE_MM", OFF_TSK(active_mm));
-DEFN("TSS_SAVE", OFF_TSK(thread.save));
-DEFN("TSS_FPESAVE", OFF_TSK(thread.fpstate.soft.save));
+DEFN("VMA_VM_MM", OFF_VMA(vm_mm));
+DEFN("VMA_VM_FLAGS", OFF_VMA(vm_flags));
-#ifdef CONFIG_CPU_32
-DEFN("TSS_DOMAIN", OFF_TSK(thread.domain));
+DEFN("VM_EXEC", VM_EXEC);
+#ifdef CONFIG_CPU_32
DEFN("HPTE_TYPE_SMALL", PTE_TYPE_SMALL);
DEFN("HPTE_AP_READ", PTE_AP_READ);
DEFN("HPTE_AP_WRITE", PTE_AP_WRITE);
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index d6948420bd9d..e1a9122353f1 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -321,14 +321,14 @@ static void console_printf(const char *fmt,...)
unsigned long flags;
va_list ap;
- save_flags_cli(flags);
+ local_irq_save(flags);
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
console_print(buffer);
va_end(fmt);
- restore_flags(flags);
+ local_irq_restore(flags);
}; /* console_printf */
#define DBG(x...) console_printf(x)
@@ -1451,13 +1451,13 @@ static int mfm_reread_partitions(kdev_t dev)
unsigned int start, i, maxp, target = DEVICE_NR(MINOR(dev));
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
if (mfm_info[target].busy || mfm_info[target].access_count > 1) {
- restore_flags (flags);
+ local_irq_restore (flags);
return -EBUSY;
}
mfm_info[target].busy = 1;
- restore_flags (flags);
+ local_irq_restore (flags);
maxp = 1 << mfm_gendisk.minor_shift;
start = target << mfm_gendisk.minor_shift;
diff --git a/drivers/acorn/char/mouse_ps2.c b/drivers/acorn/char/mouse_ps2.c
index 1c6d75dd2f8e..544e7cf5e2a5 100644
--- a/drivers/acorn/char/mouse_ps2.c
+++ b/drivers/acorn/char/mouse_ps2.c
@@ -1,8 +1,6 @@
/*
* Driver for PS/2 mouse on IOMD interface
*/
-
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
diff --git a/drivers/acorn/net/ether1.c b/drivers/acorn/net/ether1.c
index c27cc2c32aa4..9b91f7642abb 100644
--- a/drivers/acorn/net/ether1.c
+++ b/drivers/acorn/net/ether1.c
@@ -99,13 +99,13 @@ ether1_inw_p (struct net_device *dev, int addr, int svflgs)
unsigned long flags;
unsigned short ret;
- if (svflgs) {
- save_flags_cli (flags);
- }
+ if (svflgs)
+ local_irq_save (flags);
+
outb (addr >> 12, REG_PAGE);
ret = inw (ETHER1_RAM + ((addr & 4095) >> 1));
if (svflgs)
- restore_flags (flags);
+ local_irq_restore (flags);
return ret;
}
@@ -114,13 +114,13 @@ ether1_outw_p (struct net_device *dev, unsigned short val, int addr, int svflgs)
{
unsigned long flags;
- if (svflgs) {
- save_flags_cli (flags);
- }
+ if (svflgs)
+ local_irq_save (flags);
+
outb (addr >> 12, REG_PAGE);
outw (val, ETHER1_RAM + ((addr & 4095) >> 1));
if (svflgs)
- restore_flags (flags);
+ local_irq_restore (flags);
}
/*
@@ -722,7 +722,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
nop.nop_command = CMD_NOP;
nop.nop_link = nopaddr;
- save_flags_cli(flags);
+ local_irq_save(flags);
ether1_writebuffer (dev, &tx, txaddr, TX_SIZE);
ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE);
ether1_writebuffer (dev, skb->data, dataddr, len);
@@ -733,7 +733,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
/* now reset the previous nop pointer */
ether1_outw (dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS);
- restore_flags(flags);
+ local_irq_restore(flags);
/* handle transmit */
dev->trans_start = jiffies;
diff --git a/drivers/acorn/net/ether3.c b/drivers/acorn/net/ether3.c
index 7bec245b89b4..196be921aec3 100644
--- a/drivers/acorn/net/ether3.c
+++ b/drivers/acorn/net/ether3.c
@@ -491,7 +491,7 @@ ether3_timeout(struct net_device *dev)
del_timer(&priv->timer);
- save_flags_cli(flags);
+ local_irq_save(flags);
printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name);
printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name,
ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2));
@@ -501,7 +501,7 @@ ether3_timeout(struct net_device *dev)
priv->tx_head, priv->tx_tail);
ether3_setbuffer(dev, buffer_read, priv->tx_tail);
printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev));
- restore_flags(flags);
+ local_irq_restore(flags);
priv->regs.config2 |= CFG2_CTRLO;
priv->stats.tx_errors += 1;
@@ -533,10 +533,10 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
next_ptr = (priv->tx_head + 1) & 15;
- save_flags_cli(flags);
+ local_irq_save(flags);
if (priv->tx_tail == next_ptr) {
- restore_flags(flags);
+ local_irq_restore(flags);
return 1; /* unable to queue */
}
@@ -565,7 +565,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
}
next_ptr = (priv->tx_head + 1) & 15;
- restore_flags(flags);
+ local_irq_restore(flags);
dev_kfree_skb(skb);
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 9ca723bb68a2..638e8d0ef7ac 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2310,7 +2310,7 @@ static struct pci_driver eni_driver = {
name: DEV_LABEL,
id_table: eni_pci_tbl,
probe: eni_init_one,
- remove: eni_remove_one,
+ remove: __devexit_p(eni_remove_one),
};
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index a6a9046dea8d..8e65eda23b87 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1530,7 +1530,7 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp, int gfp_flags)
fs_dprintk (FS_DEBUG_QUEUE, "Added %d entries. \n", n);
}
-static void __exit free_queue (struct fs_dev *dev, struct queue *txq)
+static void __devexit free_queue (struct fs_dev *dev, struct queue *txq)
{
func_enter ();
@@ -1546,7 +1546,7 @@ static void __exit free_queue (struct fs_dev *dev, struct queue *txq)
func_exit ();
}
-static void __exit free_freepool (struct fs_dev *dev, struct freepool *fp)
+static void __devexit free_freepool (struct fs_dev *dev, struct freepool *fp)
{
func_enter ();
@@ -2088,7 +2088,7 @@ int __init init_PCI (void)
#endif
*/
-const static struct pci_device_id firestream_pci_tbl[] __devinitdata = {
+static struct pci_device_id firestream_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS50},
{ PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155,
@@ -2102,7 +2102,7 @@ static struct pci_driver firestream_driver = {
name: "firestream",
id_table: firestream_pci_tbl,
probe: firestream_init_one,
- remove: firestream_remove_one,
+ remove: __devexit_p(firestream_remove_one),
};
static int __init firestream_init_module (void)
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7d3a5f665af9..47d9b0808280 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2617,7 +2617,7 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
static struct pci_driver cciss_pci_driver = {
name: "cciss",
probe: cciss_init_one,
- remove: cciss_remove_one,
+ remove: __devexit_p(cciss_remove_one),
id_table: cciss_pci_device_id, /* id_table */
};
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index c2c352d4d24b..3edd33c306ce 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -268,7 +268,7 @@ static int rd_make_request(request_queue_t * q, struct bio *sbh)
goto fail;
set_bit(BIO_UPTODATE, &sbh->bi_flags);
- sbh->bi_end_io(sbh, len >> 9);
+ sbh->bi_end_io(sbh);
return 0;
fail:
bio_io_error(sbh);
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index e22ec9668393..b0a2caae5035 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -461,7 +461,7 @@ static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
* mwave_exit is called on module unload
* mwave_exit is also used to clean up after an aborted mwave_init
*/
-static void __exit mwave_exit(void)
+static void mwave_exit(void)
{
pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index f2afd4cf4db3..80a894193622 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -941,7 +941,7 @@ static struct pci_driver synclink_pci_driver = {
name: "synclink",
id_table: synclink_pci_tbl,
probe: synclink_init_one,
- remove: synclink_remove_one,
+ remove: __devexit_p(synclink_remove_one),
};
static struct tty_driver serial_driver, callout_driver;
@@ -8220,7 +8220,7 @@ static int __init synclink_init_one (struct pci_dev *dev,
return 0;
}
-static void __exit synclink_remove_one (struct pci_dev *dev)
+static void __devexit synclink_remove_one (struct pci_dev *dev)
{
}
diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c
index 872a5e453ae4..9097fe935726 100644
--- a/drivers/char/wdt_pci.c
+++ b/drivers/char/wdt_pci.c
@@ -558,7 +558,7 @@ out_reg:
}
-static void __exit wdtpci_remove_one (struct pci_dev *pdev)
+static void __devexit wdtpci_remove_one (struct pci_dev *pdev)
{
/* here we assume only one device will ever have
* been picked up and registered by probe function */
@@ -583,7 +583,7 @@ static struct pci_driver wdtpci_driver = {
name: "wdt-pci",
id_table: wdtpci_pci_tbl,
probe: wdtpci_init_one,
- remove: wdtpci_remove_one,
+ remove: __devexit_p(wdtpci_remove_one),
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 4e9e16d82318..30bc38167e54 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -8,8 +8,6 @@
* Drive tuning added from Rebel.com's kernel sources
* -- Russell King (15/11/98) linux@arm.linux.org.uk
*/
-
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/timer.h>
diff --git a/drivers/input/gameport/cs461x.c b/drivers/input/gameport/cs461x.c
index 7116b3453c04..6b096f0fe43a 100644
--- a/drivers/input/gameport/cs461x.c
+++ b/drivers/input/gameport/cs461x.c
@@ -313,7 +313,7 @@ static struct pci_driver cs461x_pci_driver = {
name: "PCI Gameport",
id_table: cs461x_pci_tbl,
probe: cs461x_pci_probe,
- remove: cs461x_pci_remove,
+ remove: __devexit_p(cs461x_pci_remove),
};
int __init js_cs461x_init(void)
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c
index 2489b11c6020..4763a02c7177 100644
--- a/drivers/input/gameport/emu10k1-gp.c
+++ b/drivers/input/gameport/emu10k1-gp.c
@@ -108,7 +108,7 @@ static struct pci_driver emu_driver = {
name: "Emu10k1 Gameport",
id_table: emu_tbl,
probe: emu_probe,
- remove: emu_remove,
+ remove: __devexit_p(emu_remove),
};
int __init emu_init(void)
diff --git a/drivers/input/gameport/pcigame.c b/drivers/input/gameport/pcigame.c
index 04e1bee04f9c..194814ca64fc 100644
--- a/drivers/input/gameport/pcigame.c
+++ b/drivers/input/gameport/pcigame.c
@@ -180,7 +180,7 @@ static struct pci_driver pcigame_driver = {
name: "pcigame",
id_table: pcigame_id_table,
probe: pcigame_probe,
- remove: pcigame_remove,
+ remove: __devexit_p(pcigame_remove),
};
int __init pcigame_init(void)
diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c
index e50cd7c31767..32e784ec5faf 100644
--- a/drivers/isdn/avmb1/capi.c
+++ b/drivers/isdn/avmb1/capi.c
@@ -1535,7 +1535,7 @@ static void __exit proc_exit(void)
/* -------- init function and module interface ---------------------- */
-static void __exit alloc_exit(void)
+static void alloc_exit(void)
{
if (capidev_cachep) {
(void)kmem_cache_destroy(capidev_cachep);
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 3c5d5435395e..77c9a77d61d0 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -945,14 +945,14 @@ static void __devexit fcpnp_remove(struct pci_dev *pdev)
static struct pci_driver fcpci_driver = {
name: "fcpci",
probe: fcpci_probe,
- remove: fcpci_remove,
+ remove: __devexit_p(fcpci_remove),
id_table: fcpci_ids,
};
static struct isapnp_driver fcpnp_driver = {
name: "fcpnp",
probe: fcpnp_probe,
- remove: fcpnp_remove,
+ remove: __devexit_p(fcpnp_remove),
id_table: fcpnp_ids,
};
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 28ea25bf56a3..8aad86d9d37d 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -178,7 +178,7 @@ MODULE_DEVICE_TABLE (usb, st5481_ids);
static struct usb_driver st5481_usb_driver = {
name: "st5481_usb",
probe: probe_st5481,
- disconnect: disconnect_st5481,
+ disconnect: __devexit_p(disconnect_st5481),
id_table: st5481_ids,
};
diff --git a/drivers/isdn/tpam/tpam_main.c b/drivers/isdn/tpam/tpam_main.c
index 9a000b3d1f63..4573cad5a0af 100644
--- a/drivers/isdn/tpam/tpam_main.c
+++ b/drivers/isdn/tpam/tpam_main.c
@@ -254,7 +254,7 @@ static struct pci_driver tpam_driver = {
name: "tpam",
id_table: tpam_pci_tbl,
probe: tpam_probe,
- remove: tpam_remove,
+ remove: __devexit_p(tpam_remove),
};
static int __init tpam_init(void) {
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 68f612caa530..2885fd0a6aff 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -424,7 +424,7 @@ static struct pci_driver gemtek_pci_driver =
name: "gemtek_pci",
id_table: gemtek_pci_id,
probe: gemtek_pci_probe,
- remove: gemtek_pci_remove
+ remove: __devexit_p(gemtek_pci_remove)
};
static int __init gemtek_pci_init_module( void )
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 1368ff2ed012..dec250a7d582 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -376,7 +376,7 @@ static struct pci_driver maxiradio_driver = {
name: "radio-maxiradio",
id_table: maxiradio_pci_tbl,
probe: maxiradio_init_one,
- remove: maxiradio_remove_one,
+ remove: __devexit_p(maxiradio_remove_one),
};
int __init maxiradio_radio_init(void)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 44641b9ce187..8d182b5b9f3a 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -2798,7 +2798,8 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
* Scan for a Bt848 card, request the irq and map the io memory
*/
-static void __devexit bttv_remove(struct pci_dev *pci_dev)
+/* Can't be marked __devexit with a reference from bttv_probe. */
+static void bttv_remove(struct pci_dev *pci_dev)
{
u8 command;
int j;
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 62f649d7f210..014894936dd2 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1424,7 +1424,7 @@ static struct pci_driver meye_driver = {
name: "meye",
id_table: meye_pci_tbl,
probe: meye_probe,
- remove: meye_remove,
+ remove: __devexit_p(meye_remove),
};
static int __init meye_init_module(void) {
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
index 9f76cd8d2321..6e33e94b9e6d 100644
--- a/drivers/media/video/zr36120.c
+++ b/drivers/media/video/zr36120.c
@@ -2024,7 +2024,7 @@ int __init init_zoran(int card)
}
static
-void __exit release_zoran(int max)
+void release_zoran(int max)
{
struct zoran *ztv;
int i;
diff --git a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
index eaa9d43c626e..0776fd053243 100644
--- a/drivers/mtd/maps/elan-104nc.c
+++ b/drivers/mtd/maps/elan-104nc.c
@@ -213,7 +213,7 @@ static struct map_info elan_104nc_map = {
/* MTD device for all of the flash. */
static struct mtd_info *all_mtd;
-static void __exit cleanup_elan_104nc(void)
+static void cleanup_elan_104nc(void)
{
if( all_mtd ) {
del_mtd_partitions( all_mtd );
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index e5915c8433e0..2ea82481099e 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -221,7 +221,7 @@ static struct map_info sbc_gxx_map = {
/* MTD device for all of the flash. */
static struct mtd_info *all_mtd;
-static void __exit cleanup_sbc_gxx(void)
+static void cleanup_sbc_gxx(void)
{
if( all_mtd ) {
del_mtd_partitions( all_mtd );
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 01c369cbfb74..c31306fd995e 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -2916,7 +2916,7 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
static struct pci_driver vortex_driver = {
name: "3c59x",
probe: vortex_init_one,
- remove: vortex_remove_one,
+ remove: __devexit_p(vortex_remove_one),
id_table: vortex_pci_tbl,
#ifdef CONFIG_PM
suspend: vortex_suspend,
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 944407bdaa5a..8f6ee6676ab3 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1371,7 +1371,7 @@ static struct pci_driver cp_driver = {
name: DRV_NAME,
id_table: cp_pci_tbl,
probe: cp_init_one,
- remove: cp_remove_one,
+ remove: __devexit_p(cp_remove_one),
};
static int __init cp_init (void)
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index f9d076567706..b8df6899461c 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -2499,7 +2499,7 @@ static struct pci_driver rtl8139_pci_driver = {
name: DRV_NAME,
id_table: rtl8139_pci_tbl,
probe: rtl8139_init_one,
- remove: rtl8139_remove_one,
+ remove: __devexit_p(rtl8139_remove_one),
#ifdef CONFIG_PM
suspend: rtl8139_suspend,
resume: rtl8139_resume,
diff --git a/drivers/net/Config.help b/drivers/net/Config.help
index e4f99625536f..009107037d07 100644
--- a/drivers/net/Config.help
+++ b/drivers/net/Config.help
@@ -3,6 +3,10 @@ CONFIG_BAGETLANCE
MIPS-32-based Baget embedded system. This chipset is better known
via the NE2100 cards.
+CONFIG_LASI_82596
+ Say Y here to support the on-board Intel 82596 ethernet controller
+ built into Hewlett-Packard PA-RISC machines.
+
CONFIG_MIPS_JAZZ_SONIC
This is the driver for the onboard card of MIPS Magnum 4000,
Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
@@ -214,6 +218,12 @@ CONFIG_PPPOE
pppd, along with binaries of a patched pppd package can be found at:
<http://www.shoshin.uwaterloo.ca/~mostrows/>.
+CONFIG_PPPOATM
+ Support PPP (Point to Point Protocol) encapsulated in ATM frames.
+ This implementation does not yet comply with section 8 of RFC2364,
+ which can lead to bad results if the ATM peer loses state and
+ changes its encapsulation unilaterally.
+
CONFIG_NET_RADIO
Support for wireless LANs and everything having to do with radio,
but not with amateur radio or FM broadcasting.
@@ -853,6 +863,10 @@ CONFIG_LANCE
say M here and read <file:Documentation/modules.txt>. This is
recommended. The module will be called lance.o.
+CONFIG_MIPS_AU1000_ENET
+ If you have an Alchemy Semi AU1000 ethernet controller
+ on an SGI MIPS system, say Y. Otherwise, say N.
+
CONFIG_SGI_IOC3_ETH
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
@@ -1326,6 +1340,24 @@ CONFIG_DE4X5
module, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/networking/net-modules.txt>.
+CONFIG_DE2104X
+ This driver is developed for the SMC EtherPower series Ethernet
+ cards and also works with cards based on the DECchip
+ 21040 (Tulip series) chips. Some LinkSys PCI cards are
+ of this type. (If your card is NOT SMC EtherPower 10/100 PCI
+ (smc9332dst), you can also try the driver for "Generic DECchip"
+ cards, above. However, most people with a network card of this type
+ will say Y here.) Do read the Ethernet-HOWTO, available from
+ <http://www.linuxdoc.org/docs.html#howto>. More specific
+ information is contained in
+ <file:Documentation/DocBook/tulip-user.tmpl>.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called tulip.o. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt> as well
+ as <file:Documentation/networking/net-modules.txt>.
+
CONFIG_TULIP
This driver is developed for the SMC EtherPower series Ethernet
cards and also works with cards based on the DECchip
@@ -1344,6 +1376,20 @@ CONFIG_TULIP
module, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/networking/net-modules.txt>.
+CONFIG_TULIP_MWI
+ This configures your Tulip card specifically for the card and
+ system cache line size type you are using.
+
+ This is experimental code, not yet tested on many boards.
+
+ If unsure, say N.
+
+CONFIG_TULIP_MMIO
+ Use PCI shared memory for the NIC registers, rather than going through
+ the Tulip's PIO (programmed I/O ports). Faster, but could produce
+ obscure bugs if your mainboard has memory controller timing issues.
+ If in doubt, say N.
+
CONFIG_DGRS
This is support for the Digi International RightSwitch series of
PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6
@@ -1374,6 +1420,11 @@ CONFIG_FEALNX
cards. Specifications and data at
<http://www.myson.com.hk/mtd/datasheet/>.
+CONFIG_LP486E
+ Say Y here to support the 82596-based on-board Ethernet controller
+ for the Panther motherboard, which is one of the two shipped in the
+ Intel Professional Workstation.
+
CONFIG_ETH16I
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
@@ -1413,6 +1464,16 @@ CONFIG_VIA_RHINE
a module, say M here and read <file:Documentation/modules.txt> as
well as <file:Documentation/networking/net-modules.txt>.
+CONFIG_VIA_RHINE_MMIO
+ This instructs the driver to use PCI shared memory (MMIO) instead of
+ programmed I/O ports (PIO). Enabling this gives an improvement in
+ processing time in parts of the driver.
+
+ It is not known if this works reliably on all "rhine" based cards,
+ but it has been tested successfully on some DFE-530TX adapters.
+
+ If unsure, say N.
+
CONFIG_DM9102
This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
Davicom (<http://www.davicom.com.tw/>). If you have such a network
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index a6b5bc7efe88..9a297615862d 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -160,7 +160,7 @@ static struct pci_driver com20020pci_driver = {
name: "com20020",
id_table: com20020pci_id_table,
probe: com20020pci_probe,
- remove: com20020pci_remove
+ remove: __devexit_p(com20020pci_remove)
};
static int __init com20020pci_init(void)
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index a54402308b84..97e5b891b1e7 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -3362,7 +3362,7 @@ MODULE_DEVICE_TABLE(pci, dfx_pci_tbl);
static struct pci_driver dfx_driver = {
name: "defxx",
probe: dfx_init_one,
- remove: dfx_remove_one,
+ remove: __devexit_p(dfx_remove_one),
id_table: dfx_pci_tbl,
};
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index efdffd67667e..8869df646b2a 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -1682,7 +1682,7 @@ static struct pci_driver rio_driver = {
name:"dl2k",
id_table:rio_pci_tbl,
probe:rio_probe1,
- remove:rio_remove1,
+ remove: __devexit_p(rio_remove1),
};
static int __init
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index f79245c07ec6..dd232b4e25e7 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -2288,7 +2288,7 @@ static struct pci_driver eepro100_driver = {
name: "eepro100",
id_table: eepro100_pci_tbl,
probe: eepro100_init_one,
- remove: eepro100_remove_one,
+ remove: __devexit_p(eepro100_remove_one),
#ifdef CONFIG_PM
suspend: eepro100_suspend,
resume: eepro100_resume,
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 2805d9d42f2f..4f9ad8cf8879 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1533,7 +1533,7 @@ static struct pci_driver epic_driver = {
name: DRV_NAME,
id_table: epic_pci_tbl,
probe: epic_init_one,
- remove: epic_remove_one,
+ remove: __devexit_p(epic_remove_one),
#ifdef CONFIG_PM
suspend: epic_suspend,
resume: epic_resume,
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 473e59d9bde5..9aea4b32484f 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1929,7 +1929,7 @@ static struct pci_driver fealnx_driver = {
name: "fealnx",
id_table: fealnx_pci_tbl,
probe: fealnx_init_one,
- remove: fealnx_remove_one,
+ remove: __devexit_p(fealnx_remove_one),
};
static int __init fealnx_init(void)
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 45c3021f8673..6dd6f95daef1 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1978,7 +1978,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
-static void __exit hamachi_remove_one (struct pci_dev *pdev)
+static void __devexit hamachi_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -2008,7 +2008,7 @@ static struct pci_driver hamachi_driver = {
name: DRV_NAME,
id_table: hamachi_pci_tbl,
probe: hamachi_init_one,
- remove: hamachi_remove_one,
+ remove: __devexit_p(hamachi_remove_one),
};
static int __init hamachi_init (void)
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 1a3e62efe656..ac98e3ad7a2e 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1516,7 +1516,7 @@ static struct pci_driver ioc3_driver = {
name: "ioc3-eth",
id_table: ioc3_pci_tbl,
probe: ioc3_probe,
- remove: ioc3_remove_one,
+ remove: __devexit_p(ioc3_remove_one),
};
static int __init ioc3_init_module(void)
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index e46fe529394a..000f8389272d 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1291,7 +1291,7 @@ static struct pci_driver vlsi_irda_driver = {
name: drivername,
id_table: vlsi_irda_table,
probe: vlsi_irda_probe,
- remove: vlsi_irda_remove,
+ remove: __devexit_p(vlsi_irda_remove),
suspend: vlsi_irda_suspend,
resume: vlsi_irda_resume,
};
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index d3d57823aa0e..d96e3d7bf94b 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1925,6 +1925,8 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
+ /* LSTATUS is latched low until a read - so read twice */
+ mdio_read(dev, 1, MII_BMSR);
edata.data = (mdio_read(dev, 1, MII_BMSR)&BMSR_LSTATUS) ? 1:0;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
@@ -2504,7 +2506,7 @@ static struct pci_driver natsemi_driver = {
name: DRV_NAME,
id_table: natsemi_pci_tbl,
probe: natsemi_probe1,
- remove: natsemi_remove1,
+ remove: __devexit_p(natsemi_remove1),
#ifdef CONFIG_PM
suspend: natsemi_suspend,
resume: natsemi_resume,
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index 0189756a64bb..d1addf61c7c0 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -642,7 +642,7 @@ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
static struct pci_driver ne2k_driver = {
name: DRV_NAME,
probe: ne2k_pci_init_one,
- remove: ne2k_pci_remove_one,
+ remove: __devexit_p(ne2k_pci_remove_one),
id_table: ne2k_pci_tbl,
};
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 5e72b5c6b2ed..1dbffb650357 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1637,7 +1637,7 @@ static struct pci_driver driver = {
name: "ns83820",
id_table: ns83820_pci_tbl,
probe: ns83820_init_one,
- remove: ns83820_remove_one,
+ remove: __devexit_p(ns83820_remove_one),
#if 0 /* FIXME: implement */
suspend: ,
resume: ,
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 957b71b82245..45c435f843d6 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1956,7 +1956,7 @@ static struct pci_driver netdrv_pci_driver = {
name: MODNAME,
id_table: netdrv_pci_tbl,
probe: netdrv_init_one,
- remove: netdrv_remove_one,
+ remove: __devexit_p(netdrv_remove_one),
#ifdef CONFIG_PM
suspend: netdrv_suspend,
resume: netdrv_resume,
diff --git a/drivers/net/pcmcia/Config.help b/drivers/net/pcmcia/Config.help
index 17c240b36465..d7304d7bceca 100644
--- a/drivers/net/pcmcia/Config.help
+++ b/drivers/net/pcmcia/Config.help
@@ -133,7 +133,7 @@ CONFIG_PCMCIA_XIRCOM
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
- The module will be called xircom_tulip_cb.o. If you want to compile
+ The module will be called xircom_cb.o. If you want to compile
it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say N.
diff --git a/drivers/net/pcmcia/xircom_cb.c b/drivers/net/pcmcia/xircom_cb.c
index 9fb35d9d0ff6..cc15b93a4cde 100644
--- a/drivers/net/pcmcia/xircom_cb.c
+++ b/drivers/net/pcmcia/xircom_cb.c
@@ -170,7 +170,7 @@ static struct pci_driver xircom_ops = {
name: "xircom_cb",
id_table: xircom_pci_table,
probe: xircom_probe,
- remove: xircom_remove,
+ remove: __devexit_p(xircom_remove),
};
diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c
index 81b91524db03..60973d670ce0 100644
--- a/drivers/net/pcmcia/xircom_tulip_cb.c
+++ b/drivers/net/pcmcia/xircom_tulip_cb.c
@@ -1709,7 +1709,7 @@ static struct pci_driver xircom_driver = {
name: DRV_NAME,
id_table: xircom_pci_table,
probe: xircom_init_one,
- remove: xircom_remove_one,
+ remove: __devexit_p(xircom_remove_one),
#ifdef CONFIG_PM
suspend: xircom_suspend,
resume: xircom_resume
diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
index f0a8fedaf8ba..87d34f4e86ac 100644
--- a/drivers/net/rcpci45.c
+++ b/drivers/net/rcpci45.c
@@ -115,7 +115,7 @@ static struct pci_device_id rcpci45_pci_table[] __devinitdata = {
MODULE_DEVICE_TABLE (pci, rcpci45_pci_table);
MODULE_LICENSE("GPL");
-static void __exit
+static void __devexit
rcpci45_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
@@ -267,7 +267,7 @@ static struct pci_driver rcpci45_driver = {
name: "rcpci45",
id_table: rcpci45_pci_table,
probe: rcpci45_init_one,
- remove: rcpci45_remove_one,
+ remove: __devexit_p(rcpci45_remove_one),
};
static int __init
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index ab7f222fbf66..af4ce801b507 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -2129,7 +2129,7 @@ static struct pci_driver sis900_pci_driver = {
name: SIS900_MODULE_NAME,
id_table: sis900_pci_tbl,
probe: sis900_probe,
- remove: sis900_remove,
+ remove: __devexit_p(sis900_remove),
};
static int __init sis900_init_module(void)
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 57920334c0ce..e01635c9646e 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1982,7 +1982,7 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
static struct pci_driver starfire_driver = {
name: DRV_NAME,
probe: starfire_init_one,
- remove: starfire_remove_one,
+ remove: __devexit_p(starfire_remove_one),
id_table: starfire_pci_tbl,
};
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 510573b723f4..e92d0c138c01 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1463,7 +1463,7 @@ static struct pci_driver sundance_driver = {
name: DRV_NAME,
id_table: sundance_pci_tbl,
probe: sundance_probe1,
- remove: sundance_remove1,
+ remove: __devexit_p(sundance_remove1),
};
static int __init sundance_init(void)
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index cd8dce3f18f7..bbdc8ca9ae6f 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2835,7 +2835,7 @@ static struct pci_driver gem_driver = {
name: GEM_MODULE_NAME,
id_table: gem_pci_tbl,
probe: gem_init_one,
- remove: gem_remove_one,
+ remove: __devexit_p(gem_remove_one),
#ifdef CONFIG_PM
suspend: gem_suspend,
resume: gem_resume,
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 59a9f0cd1f64..144f7c688177 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -431,7 +431,7 @@ static struct pci_driver tlan_driver = {
name: "tlan",
id_table: tlan_pci_tbl,
probe: tlan_init_one,
- remove: tlan_remove_one,
+ remove: __devexit_p(tlan_remove_one),
};
static int __init tlan_probe(void)
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
index bafb344b2fe2..8b9a003a5786 100644
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -433,7 +433,7 @@ static int abyss_close(struct net_device *dev)
return 0;
}
-static void __exit abyss_detach (struct pci_dev *pdev)
+static void __devexit abyss_detach (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -451,7 +451,7 @@ static struct pci_driver abyss_driver = {
name: "abyss",
id_table: abyss_pci_tbl,
probe: abyss_attach,
- remove: abyss_detach,
+ remove: __devexit_p(abyss_detach),
};
static int __init abyss_init (void)
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index bbae0d62254d..32a11e49beaa 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -1812,7 +1812,7 @@ static struct pci_driver streamer_pci_driver = {
name: "lanstreamer",
id_table: streamer_pci_tbl,
probe: streamer_init_one,
- remove: streamer_remove_one,
+ remove: __devexit_p(streamer_remove_one),
};
static int __init streamer_init_module(void) {
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 00044db1bb0f..e2a1bb3ddd15 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -433,8 +433,6 @@ static int olympic_open(struct net_device *dev)
do {
int i;
- save_flags(flags);
- cli();
for(i=0;i<SRB_COMMAND_SIZE;i+=4)
writel(0,init_srb+i);
if(SRB_COMMAND_SIZE & 2)
@@ -465,10 +463,12 @@ static int olympic_open(struct net_device *dev)
memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;
}
writeb(1,init_srb+30);
-
+
+ spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
olympic_priv->srb_queued=1;
writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
+ spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
t = jiffies ;
@@ -496,7 +496,6 @@ static int olympic_open(struct net_device *dev)
remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_RUNNING) ;
- restore_flags(flags);
#if OLYMPIC_DEBUG
printk("init_srb(%p): ",init_srb);
for(i=0;i<20;i++)
@@ -1058,12 +1057,11 @@ static int olympic_close(struct net_device *dev)
writeb(0,srb+1);
writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
- save_flags(flags);
- cli();
-
+ spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
olympic_priv->srb_queued=1;
writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
+ spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
t = jiffies ;
@@ -1088,7 +1086,6 @@ static int olympic_close(struct net_device *dev)
remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_RUNNING) ;
- restore_flags(flags) ;
olympic_priv->rx_status_last_received++;
olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
@@ -1760,7 +1757,7 @@ static struct pci_driver olympic_driver = {
name: "olympic",
id_table: olympic_pci_tbl,
probe: olympic_probe,
- remove: olympic_remove_one
+ remove: __devexit_p(olympic_remove_one)
};
static int __init olympic_pci_init(void)
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index b361b223ca0e..deca3a49caae 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -220,7 +220,7 @@ static unsigned short tms_pci_setnselout_pins(struct net_device *dev)
return val;
}
-static void __exit tms_pci_detach (struct pci_dev *pdev)
+static void __devexit tms_pci_detach (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -238,7 +238,7 @@ static struct pci_driver tms_pci_driver = {
name: "tmspci",
id_table: tmspci_pci_tbl,
probe: tms_pci_attach,
- remove: tms_pci_detach,
+ remove: __devexit_p(tms_pci_detach),
};
static int __init tms_pci_init (void)
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 9d62e00518d6..90d533330785 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1754,7 +1754,7 @@ static struct pci_driver via_rhine_driver = {
name: "via-rhine",
id_table: via_rhine_pci_tbl,
probe: via_rhine_init_one,
- remove: via_rhine_remove_one,
+ remove: __devexit_p(via_rhine_remove_one),
};
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 031506a5c2da..64258f647ce4 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -1810,7 +1810,7 @@ static struct pci_driver fst_driver = {
name: FST_NAME,
id_table: fst_pci_dev_id,
probe: fst_add_one,
- remove: fst_remove_one,
+ remove: __devexit_p(fst_remove_one),
suspend: NULL,
resume: NULL,
};
diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c
index 90055d16871c..7616fad688ec 100644
--- a/drivers/net/winbond-840.c
+++ b/drivers/net/winbond-840.c
@@ -1732,7 +1732,7 @@ static struct pci_driver w840_driver = {
name: DRV_NAME,
id_table: w840_pci_tbl,
probe: w840_probe1,
- remove: w840_remove1,
+ remove: __devexit_p(w840_remove1),
#ifdef CONFIG_PM
suspend: w840_suspend,
resume: w840_resume,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 72f4225836d1..454ad2adfc8a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -63,7 +63,7 @@ static struct pci_driver airo_driver = {
name: "airo",
id_table: card_ids,
probe: airo_pci_probe,
- remove: airo_pci_remove,
+ remove: __devexit_p(airo_pci_remove),
};
#endif /* CONFIG_PCI */
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 9823adc71276..d5f52f16ed8e 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -63,6 +63,9 @@
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif /* WIRELESS_EXT > 12 */
#endif
#include <pcmcia/version.h>
@@ -269,6 +272,16 @@ static dev_link_t *dev_list;
because they generally can't be allocated dynamically.
*/
+#if WIRELESS_EXT <= 12
+/* Wireless extensions backward compatibility */
+
+/* Part of iw_handler prototype we need */
+struct iw_request_info
+{
+ __u16 cmd; /* Wireless Extension command */
+ __u16 flags; /* More to come ;-) */
+};
+
/* Wireless Extension Backward compatibility - Jean II
* If the new wireless device private ioctl range is not defined,
* default to standard device private ioctl range */
@@ -276,8 +289,11 @@ static dev_link_t *dev_list;
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
#endif /* SIOCIWFIRSTPRIV */
-#define SIOCGIPSNAP SIOCIWFIRSTPRIV /* Site Survey Snapshot */
-/*#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1*/
+#else /* WIRELESS_EXT <= 12 */
+static const struct iw_handler_def netwave_handler_def;
+#endif /* WIRELESS_EXT <= 12 */
+
+#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
#define MAX_ESA 10
@@ -483,7 +499,10 @@ static dev_link_t *netwave_attach(void)
/* wireless extensions */
#ifdef WIRELESS_EXT
dev->get_wireless_stats = &netwave_get_wireless_stats;
-#endif
+#if WIRELESS_EXT > 12
+ dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
+#endif /* WIRELESS_EXT > 12 */
+#endif /* WIRELESS_EXT */
dev->do_ioctl = &netwave_ioctl;
dev->tx_timeout = &netwave_watchdog;
@@ -596,6 +615,303 @@ static void netwave_flush_stale_links(void)
} /* netwave_flush_stale_links */
/*
+ * Wireless Handler : get protocol name
+ */
+static int netwave_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ strcpy(wrqu->name, "Netwave");
+ return 0;
+}
+
+/*
+ * Wireless Handler : set Network ID
+ */
+static int netwave_set_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long flags;
+ ioaddr_t iobase = dev->base_addr;
+ netwave_private *priv = (netwave_private *) dev->priv;
+ u_char *ramBase = priv->ramBase;
+
+ /* Disable interrupts & save flags */
+ save_flags(flags);
+ cli();
+
+#if WIRELESS_EXT > 8
+ if(!wrqu->nwid.disabled) {
+ domain = wrqu->nwid.value;
+#else /* WIRELESS_EXT > 8 */
+ if(wrqu->nwid.on) {
+ domain = wrqu->nwid.nwid;
+#endif /* WIRELESS_EXT > 8 */
+ printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
+ (domain >> 8) & 0x01, domain & 0xff);
+ wait_WOC(iobase);
+ writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
+ writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
+ writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
+ writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
+ }
+
+ /* ReEnable interrupts & restore flags */
+ restore_flags(flags);
+
+ return 0;
+}
+
+/*
+ * Wireless Handler : get Network ID
+ */
+static int netwave_get_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+#if WIRELESS_EXT > 8
+ wrqu->nwid.value = domain;
+ wrqu->nwid.disabled = 0;
+ wrqu->nwid.fixed = 1;
+#else /* WIRELESS_EXT > 8 */
+ wrqu->nwid.nwid = domain;
+ wrqu->nwid.on = 1;
+#endif /* WIRELESS_EXT > 8 */
+
+ return 0;
+}
+
+/*
+ * Wireless Handler : set scramble key
+ */
+static int netwave_set_scramble(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *key)
+{
+ unsigned long flags;
+ ioaddr_t iobase = dev->base_addr;
+ netwave_private *priv = (netwave_private *) dev->priv;
+ u_char *ramBase = priv->ramBase;
+
+ /* Disable interrupts & save flags */
+ save_flags(flags);
+ cli();
+
+ scramble_key = (key[0] << 8) | key[1];
+ wait_WOC(iobase);
+ writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
+ writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
+ writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
+ writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
+
+ /* ReEnable interrupts & restore flags */
+ restore_flags(flags);
+
+ return 0;
+}
+
+/*
+ * Wireless Handler : get scramble key
+ */
+static int netwave_get_scramble(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *key)
+{
+ key[1] = scramble_key & 0xff;
+ key[0] = (scramble_key>>8) & 0xff;
+#if WIRELESS_EXT > 8
+ wrqu->encoding.flags = IW_ENCODE_ENABLED;
+ wrqu->encoding.length = 2;
+#else /* WIRELESS_EXT > 8 */
+ wrqu->encoding.method = 1;
+#endif /* WIRELESS_EXT > 8 */
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 8
+/*
+ * Wireless Handler : get mode
+ */
+static int netwave_get_mode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ if(domain & 0x100)
+ wrqu->mode = IW_MODE_INFRA;
+ else
+ wrqu->mode = IW_MODE_ADHOC;
+
+ return 0;
+}
+#endif /* WIRELESS_EXT > 8 */
+
+/*
+ * Wireless Handler : get range info
+ */
+static int netwave_get_range(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct iw_range *range = (struct iw_range *) extra;
+ int ret = 0;
+
+ /* Set the length (very important for backward compatibility) */
+ wrqu->data.length = sizeof(struct iw_range);
+
+ /* Set all the info we don't care or don't know about to zero */
+ memset(range, 0, sizeof(struct iw_range));
+
+#if WIRELESS_EXT > 10
+ /* Set the Wireless Extension versions */
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 9; /* Nothing for us in v10 and v11 */
+#endif /* WIRELESS_EXT > 10 */
+
+ /* Set information in the range struct */
+ range->throughput = 450 * 1000; /* don't argue on this ! */
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x01FF;
+
+ range->num_channels = range->num_frequency = 0;
+
+ range->sensitivity = 0x3F;
+ range->max_qual.qual = 255;
+ range->max_qual.level = 255;
+ range->max_qual.noise = 0;
+
+#if WIRELESS_EXT > 7
+ range->num_bitrates = 1;
+ range->bitrate[0] = 1000000; /* 1 Mb/s */
+#endif /* WIRELESS_EXT > 7 */
+
+#if WIRELESS_EXT > 8
+ range->encoding_size[0] = 2; /* 16 bits scrambling */
+ range->num_encoding_sizes = 1;
+ range->max_encoding_tokens = 1; /* Only one key possible */
+#endif /* WIRELESS_EXT > 8 */
+
+ return ret;
+}
+
+/*
+ * Wireless Private Handler : get snapshot
+ */
+static int netwave_get_snap(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long flags;
+ ioaddr_t iobase = dev->base_addr;
+ netwave_private *priv = (netwave_private *) dev->priv;
+ u_char *ramBase = priv->ramBase;
+
+ /* Disable interrupts & save flags */
+ save_flags(flags);
+ cli();
+
+ /* Take snapshot of environment */
+ netwave_snapshot( priv, ramBase, iobase);
+ wrqu->data.length = priv->nss.length;
+ memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
+
+ priv->lastExec = jiffies;
+
+ /* ReEnable interrupts & restore flags */
+ restore_flags(flags);
+
+ return(0);
+}
+
+/*
+ * Structures to export the Wireless Handlers
+ * This is the stuff that are treated the wireless extensions (iwconfig)
+ */
+
+static const struct iw_priv_args netwave_private_args[] = {
+/*{ cmd, set_args, get_args, name } */
+ { SIOCGIPSNAP, 0,
+ IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
+ "getsitesurvey" },
+};
+
+#if WIRELESS_EXT > 12
+
+static const iw_handler netwave_handler[] =
+{
+ NULL, /* SIOCSIWNAME */
+ netwave_get_name, /* SIOCGIWNAME */
+ netwave_set_nwid, /* SIOCSIWNWID */
+ netwave_get_nwid, /* SIOCGIWNWID */
+ NULL, /* SIOCSIWFREQ */
+ NULL, /* SIOCGIWFREQ */
+ NULL, /* SIOCSIWMODE */
+ netwave_get_mode, /* SIOCGIWMODE */
+ NULL, /* SIOCSIWSENS */
+ NULL, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE */
+ netwave_get_range, /* SIOCGIWRANGE */
+ NULL, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+ NULL, /* SIOCSIWSPY */
+ NULL, /* SIOCGIWSPY */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWAP */
+ NULL, /* SIOCGIWAP */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCGIWAPLIST */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWESSID */
+ NULL, /* SIOCGIWESSID */
+ NULL, /* SIOCSIWNICKN */
+ NULL, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWRATE */
+ NULL, /* SIOCGIWRATE */
+ NULL, /* SIOCSIWRTS */
+ NULL, /* SIOCGIWRTS */
+ NULL, /* SIOCSIWFRAG */
+ NULL, /* SIOCGIWFRAG */
+ NULL, /* SIOCSIWTXPOW */
+ NULL, /* SIOCGIWTXPOW */
+ NULL, /* SIOCSIWRETRY */
+ NULL, /* SIOCGIWRETRY */
+ netwave_set_scramble, /* SIOCSIWENCODE */
+ netwave_get_scramble, /* SIOCGIWENCODE */
+};
+
+static const iw_handler netwave_private_handler[] =
+{
+ NULL, /* SIOCIWFIRSTPRIV */
+ netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
+};
+
+static const struct iw_handler_def netwave_handler_def =
+{
+ num_standard: sizeof(netwave_handler)/sizeof(iw_handler),
+ num_private: sizeof(netwave_private_handler)/sizeof(iw_handler),
+ num_private_args: sizeof(netwave_private_args)/sizeof(struct iw_priv_args),
+ standard: (iw_handler *) netwave_handler,
+ private: (iw_handler *) netwave_private_handler,
+ private_args: (struct iw_priv_args *) netwave_private_args,
+};
+#endif /* WIRELESS_EXT > 12 */
+
+/*
* Function netwave_ioctl (dev, rq, cmd)
*
* Perform ioctl : config & info stuff
@@ -606,56 +922,28 @@ static int netwave_ioctl(struct net_device *dev, /* ioctl device */
struct ifreq *rq, /* Data passed */
int cmd) /* Ioctl number */
{
- unsigned long flags;
int ret = 0;
#ifdef WIRELESS_EXT
- ioaddr_t iobase = dev->base_addr;
- netwave_private *priv = (netwave_private *) dev->priv;
- u_char *ramBase = priv->ramBase;
+#if WIRELESS_EXT <= 12
struct iwreq *wrq = (struct iwreq *) rq;
#endif
+#endif
DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
- /* Disable interrupts & save flags */
- save_flags(flags);
- cli();
-
/* Look what is the request */
switch(cmd) {
/* --------------- WIRELESS EXTENSIONS --------------- */
#ifdef WIRELESS_EXT
+#if WIRELESS_EXT <= 12
case SIOCGIWNAME:
- /* Get name */
- strcpy(wrq->u.name, "Netwave");
+ netwave_get_name(dev, NULL, &(wrq->u), NULL);
break;
case SIOCSIWNWID:
- /* Set domain */
-#if WIRELESS_EXT > 8
- if(!wrq->u.nwid.disabled) {
- domain = wrq->u.nwid.value;
-#else /* WIRELESS_EXT > 8 */
- if(wrq->u.nwid.on) {
- domain = wrq->u.nwid.nwid;
-#endif /* WIRELESS_EXT > 8 */
- printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
- (domain >> 8) & 0x01, domain & 0xff);
- wait_WOC(iobase);
- writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
- writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
- writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
- writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
- } break;
+ ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
+ break;
case SIOCGIWNWID:
- /* Read domain*/
-#if WIRELESS_EXT > 8
- wrq->u.nwid.value = domain;
- wrq->u.nwid.disabled = 0;
- wrq->u.nwid.fixed = 1;
-#else /* WIRELESS_EXT > 8 */
- wrq->u.nwid.nwid = domain;
- wrq->u.nwid.on = 1;
-#endif /* WIRELESS_EXT > 8 */
+ ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
break;
#if WIRELESS_EXT > 8 /* Note : The API did change... */
case SIOCGIWENCODE:
@@ -663,10 +951,7 @@ static int netwave_ioctl(struct net_device *dev, /* ioctl device */
if(wrq->u.encoding.pointer != (caddr_t) 0)
{
char key[2];
- key[1] = scramble_key & 0xff;
- key[0] = (scramble_key>>8) & 0xff;
- wrq->u.encoding.flags = IW_ENCODE_ENABLED;
- wrq->u.encoding.length = 2;
+ ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
if(copy_to_user(wrq->u.encoding.pointer, key, 2))
ret = -EFAULT;
}
@@ -681,127 +966,68 @@ static int netwave_ioctl(struct net_device *dev, /* ioctl device */
ret = -EFAULT;
break;
}
- scramble_key = (key[0] << 8) | key[1];
- wait_WOC(iobase);
- writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
- writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
- writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
- writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
+ ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
}
break;
case SIOCGIWMODE:
- /* Mode of operation */
- if(domain & 0x100)
- wrq->u.mode = IW_MODE_INFRA;
- else
- wrq->u.mode = IW_MODE_ADHOC;
- break;
+ /* Mode of operation */
+ ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
+ break;
#else /* WIRELESS_EXT > 8 */
case SIOCGIWENCODE:
/* Get scramble key */
- wrq->u.encoding.code = scramble_key;
- wrq->u.encoding.method = 1;
+ ret = netwave_get_scramble(dev, NULL, &(wrq->u),
+ (char *) &wrq->u.encoding.code);
break;
case SIOCSIWENCODE:
/* Set scramble key */
- scramble_key = wrq->u.encoding.code;
- wait_WOC(iobase);
- writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
- writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
- writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
- writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
+ ret = netwave_set_scramble(dev, NULL, &(wrq->u),
+ (char *) &wrq->u.encoding.code);
break;
#endif /* WIRELESS_EXT > 8 */
case SIOCGIWRANGE:
/* Basic checking... */
if(wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_range range;
-
- /* Set the length (very important for backward compatibility) */
- wrq->u.data.length = sizeof(struct iw_range);
-
- /* Set all the info we don't care or don't know about to zero */
- memset(&range, 0, sizeof(range));
-
-#if WIRELESS_EXT > 10
- /* Set the Wireless Extension versions */
- range.we_version_compiled = WIRELESS_EXT;
- range.we_version_source = 9; /* Nothing for us in v10 and v11 */
-#endif /* WIRELESS_EXT > 10 */
-
- /* Set information in the range struct */
- range.throughput = 450 * 1000; /* don't argue on this ! */
- range.min_nwid = 0x0000;
- range.max_nwid = 0x01FF;
-
- range.num_channels = range.num_frequency = 0;
-
- range.sensitivity = 0x3F;
- range.max_qual.qual = 255;
- range.max_qual.level = 255;
- range.max_qual.noise = 0;
-
-#if WIRELESS_EXT > 7
- range.num_bitrates = 1;
- range.bitrate[0] = 1000000; /* 1 Mb/s */
-#endif /* WIRELESS_EXT > 7 */
-
-#if WIRELESS_EXT > 8
- range.encoding_size[0] = 2; /* 16 bits scrambling */
- range.num_encoding_sizes = 1;
- range.max_encoding_tokens = 1; /* Only one key possible */
-#endif /* WIRELESS_EXT > 8 */
-
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, &range,
- sizeof(struct iw_range)))
- ret = -EFAULT;
+ struct iw_range range;
+ ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
+ if (copy_to_user(wrq->u.data.pointer, &range,
+ sizeof(struct iw_range)))
+ ret = -EFAULT;
}
break;
case SIOCGIWPRIV:
/* Basic checking... */
if(wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_priv_args priv[] =
- { /* cmd, set_args, get_args, name */
- { SIOCGIPSNAP, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 0,
- sizeof(struct site_survey),
- "getsitesurvey" },
- };
-
/* Set the number of ioctl available */
- wrq->u.data.length = 1;
+ wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
/* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
- sizeof(priv)))
+ if(copy_to_user(wrq->u.data.pointer,
+ (u_char *) netwave_private_args,
+ sizeof(netwave_private_args)))
ret = -EFAULT;
}
break;
case SIOCGIPSNAP:
if(wrq->u.data.pointer != (caddr_t) 0) {
- /* Take snapshot of environment */
- netwave_snapshot( priv, ramBase, iobase);
- wrq->u.data.length = priv->nss.length;
+ char buffer[sizeof( struct site_survey)];
+ ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
/* Copy structure to the user buffer */
if(copy_to_user(wrq->u.data.pointer,
- (u_char *) &priv->nss,
- sizeof( struct site_survey)))
+ buffer,
+ sizeof( struct site_survey)))
{
printk(KERN_DEBUG "Bad buffer!\n");
break;
}
-
- priv->lastExec = jiffies;
}
break;
-#endif
+#endif /* WIRELESS_EXT <= 12 */
+#endif /* WIRELESS_EXT */
default:
ret = -EOPNOTSUPP;
}
- /* ReEnable interrupts & restore flags */
- restore_flags(flags);
-
return ret;
}
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 751a1e7335f7..9c84936c43ad 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -279,7 +279,7 @@ static struct pci_driver orinoco_plx_driver = {
name:"orinoco_plx",
id_table:orinoco_plx_pci_id_table,
probe:orinoco_plx_init_one,
- remove:orinoco_plx_remove_one,
+ remove:__devexit_p(orinoco_plx_remove_one),
suspend:0,
resume:0
};
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 10805eff7113..cd2471a4d1df 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -24,28 +24,6 @@
/*------------------------------------------------------------------*/
/*
- * Wrapper for disabling interrupts and locking the driver.
- * (note : inline, so optimised away)
- */
-static inline void wv_splhi(net_local * lp,
- unsigned long * pflags)
-{
- spin_lock_irqsave(&lp->spinlock, *pflags);
- /* Note : above does the cli(); itself */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper for re-enabling interrupts and un-locking the driver.
- */
-static inline void wv_splx(net_local * lp,
- unsigned long * pflags)
-{
- spin_unlock_irqrestore(&lp->spinlock, *pflags);
-}
-
-/*------------------------------------------------------------------*/
-/*
* Translate irq number to PSA irq parameter
*/
static u8 wv_irq_to_psa(int irq)
@@ -870,10 +848,10 @@ static inline void wv_82586_reconfig(device * dev)
/* Check if we can do it now ! */
if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* May fail */
wv_82586_config(dev);
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
}
else {
#ifdef DEBUG_CONFIG_INFO
@@ -1786,170 +1764,287 @@ static inline void wl_his_gather(device * dev, u8 * stats)
/*------------------------------------------------------------------*/
/*
- * Perform ioctl for configuration and information.
- * It is here that the wireless extensions are treated (iwconfig).
+ * Wireless Handler : get protocol name
*/
-static int wavelan_ioctl(struct net_device *dev, /* device on which the ioctl is applied */
- struct ifreq *rq, /* data passed */
- int cmd)
-{ /* ioctl number */
+static int wavelan_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ strcpy(wrqu->name, "WaveLAN");
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set NWID
+ */
+static int wavelan_set_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
unsigned long ioaddr = dev->base_addr;
net_local *lp = (net_local *) dev->priv; /* lp is not unused */
- struct iwreq *wrq = (struct iwreq *) rq;
psa_t psa;
mm_t m;
unsigned long flags;
int ret = 0;
- int err = 0;
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name,
- cmd);
-#endif
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Set NWID in WaveLAN. */
+ if (!wrqu->nwid.disabled) {
+ /* Set NWID in psa */
+ psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
+ psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
+ psa.psa_nwid_select = 0x01;
+ psa_write(ioaddr, lp->hacr,
+ (char *) psa.psa_nwid - (char *) &psa,
+ (unsigned char *) psa.psa_nwid, 3);
+
+ /* Set NWID in mmc. */
+ m.w.mmw_netw_id_l = psa.psa_nwid[1];
+ m.w.mmw_netw_id_h = psa.psa_nwid[0];
+ mmc_write(ioaddr,
+ (char *) &m.w.mmw_netw_id_l -
+ (char *) &m,
+ (unsigned char *) &m.w.mmw_netw_id_l, 2);
+ mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
+ } else {
+ /* Disable NWID in the psa. */
+ psa.psa_nwid_select = 0x00;
+ psa_write(ioaddr, lp->hacr,
+ (char *) &psa.psa_nwid_select -
+ (char *) &psa,
+ (unsigned char *) &psa.psa_nwid_select,
+ 1);
+
+ /* Disable NWID in the mmc (no filtering). */
+ mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel),
+ MMW_LOOPT_SEL_DIS_NWID);
+ }
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev, ioaddr, lp->hacr);
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get NWID
+ */
+static int wavelan_get_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
/* Disable interrupts and save flags. */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
- /* Look what is the request */
- switch (cmd) {
- /* --------------- WIRELESS EXTENSIONS --------------- */
-
- case SIOCGIWNAME:
- strcpy(wrq->u.name, "WaveLAN");
- break;
-
- case SIOCSIWNWID:
- /* Set NWID in WaveLAN. */
- if (!wrq->u.nwid.disabled) {
- /* Set NWID in psa */
- psa.psa_nwid[0] =
- (wrq->u.nwid.value & 0xFF00) >> 8;
- psa.psa_nwid[1] = wrq->u.nwid.value & 0xFF;
- psa.psa_nwid_select = 0x01;
- psa_write(ioaddr, lp->hacr,
- (char *) psa.psa_nwid - (char *) &psa,
- (unsigned char *) psa.psa_nwid, 3);
-
- /* Set NWID in mmc. */
- m.w.mmw_netw_id_l = psa.psa_nwid[1];
- m.w.mmw_netw_id_h = psa.psa_nwid[0];
- mmc_write(ioaddr,
- (char *) &m.w.mmw_netw_id_l -
- (char *) &m,
- (unsigned char *) &m.w.mmw_netw_id_l, 2);
- mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
- } else {
- /* Disable NWID in the psa. */
- psa.psa_nwid_select = 0x00;
- psa_write(ioaddr, lp->hacr,
- (char *) &psa.psa_nwid_select -
- (char *) &psa,
- (unsigned char *) &psa.psa_nwid_select,
- 1);
+ /* Read the NWID. */
+ psa_read(ioaddr, lp->hacr,
+ (char *) psa.psa_nwid - (char *) &psa,
+ (unsigned char *) psa.psa_nwid, 3);
+ wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
+ wrqu->nwid.disabled = !(psa.psa_nwid_select);
+ wrqu->nwid.fixed = 1; /* Superfluous */
- /* Disable NWID in the mmc (no filtering). */
- mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel),
- MMW_LOOPT_SEL_DIS_NWID);
- }
- /* update the Wavelan checksum */
- update_psa_checksum(dev, ioaddr, lp->hacr);
- break;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- case SIOCGIWNWID:
- /* Read the NWID. */
- psa_read(ioaddr, lp->hacr,
- (char *) psa.psa_nwid - (char *) &psa,
- (unsigned char *) psa.psa_nwid, 3);
- wrq->u.nwid.value =
- (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
- wrq->u.nwid.disabled = !(psa.psa_nwid_select);
- wrq->u.nwid.fixed = 1; /* Superfluous */
- break;
-
- case SIOCSIWFREQ:
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
- if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
- ret = wv_set_frequency(ioaddr, &(wrq->u.freq));
- else
- ret = -EOPNOTSUPP;
- break;
-
- case SIOCGIWFREQ:
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
- * Does it work for everybody, especially old cards? */
- if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
- unsigned short freq;
-
- /* Ask the EEPROM to read the frequency from the first area. */
- fee_read(ioaddr, 0x00, &freq, 1);
- wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
- wrq->u.freq.e = 1;
- } else {
- psa_read(ioaddr, lp->hacr,
- (char *) &psa.psa_subband - (char *) &psa,
- (unsigned char *) &psa.psa_subband, 1);
-
- if (psa.psa_subband <= 4) {
- wrq->u.freq.m =
- fixed_bands[psa.psa_subband];
- wrq->u.freq.e = (psa.psa_subband != 0);
- } else
- ret = -EOPNOTSUPP;
- }
- break;
+ return ret;
+}
- case SIOCSIWSENS:
- /* Set the level threshold. */
- /* We should complain loudly if wrq->u.sens.fixed = 0, because we
- * can't set auto mode... */
- psa.psa_thr_pre_set = wrq->u.sens.value & 0x3F;
- psa_write(ioaddr, lp->hacr,
- (char *) &psa.psa_thr_pre_set - (char *) &psa,
- (unsigned char *) &psa.psa_thr_pre_set, 1);
- /* update the Wavelan checksum */
- update_psa_checksum(dev, ioaddr, lp->hacr);
- mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set),
- psa.psa_thr_pre_set);
- break;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set frequency
+ */
+static int wavelan_set_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ int ret;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
+ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
+ ret = wv_set_frequency(ioaddr, &(wrqu->freq));
+ else
+ ret = -EOPNOTSUPP;
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get frequency
+ */
+static int wavelan_get_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
+ * Does it work for everybody, especially old cards? */
+ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
+ unsigned short freq;
- case SIOCGIWSENS:
- /* Read the level threshold. */
+ /* Ask the EEPROM to read the frequency from the first area. */
+ fee_read(ioaddr, 0x00, &freq, 1);
+ wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
+ wrqu->freq.e = 1;
+ } else {
psa_read(ioaddr, lp->hacr,
- (char *) &psa.psa_thr_pre_set - (char *) &psa,
- (unsigned char *) &psa.psa_thr_pre_set, 1);
- wrq->u.sens.value = psa.psa_thr_pre_set & 0x3F;
- wrq->u.sens.fixed = 1;
- break;
-
- case SIOCSIWENCODE:
- /* Set encryption key */
- if (!mmc_encr(ioaddr)) {
+ (char *) &psa.psa_subband - (char *) &psa,
+ (unsigned char *) &psa.psa_subband, 1);
+
+ if (psa.psa_subband <= 4) {
+ wrqu->freq.m = fixed_bands[psa.psa_subband];
+ wrqu->freq.e = (psa.psa_subband != 0);
+ } else
ret = -EOPNOTSUPP;
- break;
- }
+ }
- /* Basic checking... */
- if (wrq->u.encoding.pointer != (caddr_t) 0) {
- /* Check the size of the key */
- if (wrq->u.encoding.length != 8) {
- ret = -EINVAL;
- break;
- }
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- /* Copy the key in the driver */
- wv_splx(lp, &flags);
- err = copy_from_user(psa.psa_encryption_key,
- wrq->u.encoding.pointer,
- wrq->u.encoding.length);
- wv_splhi(lp, &flags);
- if (err) {
- ret = -EFAULT;
- break;
- }
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set level threshold
+ */
+static int wavelan_set_sens(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Set the level threshold. */
+ /* We should complain loudly if wrqu->sens.fixed = 0, because we
+ * can't set auto mode... */
+ psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
+ psa_write(ioaddr, lp->hacr,
+ (char *) &psa.psa_thr_pre_set - (char *) &psa,
+ (unsigned char *) &psa.psa_thr_pre_set, 1);
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev, ioaddr, lp->hacr);
+ mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set),
+ psa.psa_thr_pre_set);
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get level threshold
+ */
+static int wavelan_get_sens(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Read the level threshold. */
+ psa_read(ioaddr, lp->hacr,
+ (char *) &psa.psa_thr_pre_set - (char *) &psa,
+ (unsigned char *) &psa.psa_thr_pre_set, 1);
+ wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
+ wrqu->sens.fixed = 1;
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set encryption key
+ */
+static int wavelan_set_encode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ psa_t psa;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check if capable of encryption */
+ if (!mmc_encr(ioaddr)) {
+ ret = -EOPNOTSUPP;
+ }
+
+ /* Check the size of the key */
+ if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
+ ret = -EINVAL;
+ }
+ if(!ret) {
+ /* Basic checking... */
+ if (wrqu->encoding.length == 8) {
+ /* Copy the key in the driver */
+ memcpy(psa.psa_encryption_key, extra,
+ wrqu->encoding.length);
psa.psa_encryption_select = 1;
+
psa_write(ioaddr, lp->hacr,
(char *) &psa.psa_encryption_select -
(char *) &psa,
@@ -1963,7 +2058,8 @@ static int wavelan_ioctl(struct net_device *dev, /* device on which the ioctl is
psa_encryption_key, 8);
}
- if (wrq->u.encoding.flags & IW_ENCODE_DISABLED) { /* disable encryption */
+ /* disable encryption */
+ if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
psa.psa_encryption_select = 0;
psa_write(ioaddr, lp->hacr,
(char *) &psa.psa_encryption_select -
@@ -1975,350 +2071,430 @@ static int wavelan_ioctl(struct net_device *dev, /* device on which the ioctl is
}
/* update the Wavelan checksum */
update_psa_checksum(dev, ioaddr, lp->hacr);
- break;
+ }
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get encryption key
+ */
+static int wavelan_get_encode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
- case SIOCGIWENCODE:
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check if encryption is available */
+ if (!mmc_encr(ioaddr)) {
+ ret = -EOPNOTSUPP;
+ } else {
/* Read the encryption key */
- if (!mmc_encr(ioaddr)) {
- ret = -EOPNOTSUPP;
- break;
- }
+ psa_read(ioaddr, lp->hacr,
+ (char *) &psa.psa_encryption_select -
+ (char *) &psa,
+ (unsigned char *) &psa.
+ psa_encryption_select, 1 + 8);
+
+ /* encryption is enabled ? */
+ if (psa.psa_encryption_select)
+ wrqu->encoding.flags = IW_ENCODE_ENABLED;
+ else
+ wrqu->encoding.flags = IW_ENCODE_DISABLED;
+ wrqu->encoding.flags |= mmc_encr(ioaddr);
- /* only super-user can see encryption key */
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- break;
- }
+ /* Copy the key to the user buffer */
+ wrqu->encoding.length = 8;
+ memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
+ }
- /* Basic checking... */
- if (wrq->u.encoding.pointer != (caddr_t) 0) {
- /* Verify the user buffer */
- ret =
- verify_area(VERIFY_WRITE,
- wrq->u.encoding.pointer, 8);
- if (ret)
- break;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- psa_read(ioaddr, lp->hacr,
- (char *) &psa.psa_encryption_select -
- (char *) &psa,
- (unsigned char *) &psa.
- psa_encryption_select, 1 + 8);
+ return ret;
+}
- /* encryption is enabled ? */
- if (psa.psa_encryption_select)
- wrq->u.encoding.flags = IW_ENCODE_ENABLED;
- else
- wrq->u.encoding.flags = IW_ENCODE_DISABLED;
- wrq->u.encoding.flags |= mmc_encr(ioaddr);
-
- /* Copy the key to the user buffer */
- wrq->u.encoding.length = 8;
- wv_splx(lp, &flags);
- if (copy_to_user(wrq->u.encoding.pointer,
- psa.psa_encryption_key, 8))
- ret = -EFAULT;
- wv_splhi(lp, &flags);
- }
- break;
-
- case SIOCGIWRANGE:
- /* basic checking */
- if (wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_range range;
-
- /* Set the length (very important for backward
- * compatibility) */
- wrq->u.data.length = sizeof(struct iw_range);
-
- /* Set all the info we don't care or don't know
- * about to zero */
- memset(&range, 0, sizeof(range));
-
- /* Set the Wireless Extension versions */
- range.we_version_compiled = WIRELESS_EXT;
- range.we_version_source = 9;
-
- /* Set information in the range struct. */
- range.throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */
- range.min_nwid = 0x0000;
- range.max_nwid = 0xFFFF;
-
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
- if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
- range.num_channels = 10;
- range.num_frequency =
- wv_frequency_list(ioaddr, range.freq,
- IW_MAX_FREQUENCIES);
- } else
- range.num_channels = range.num_frequency =
- 0;
-
- range.sensitivity = 0x3F;
- range.max_qual.qual = MMR_SGNL_QUAL;
- range.max_qual.level = MMR_SIGNAL_LVL;
- range.max_qual.noise = MMR_SILENCE_LVL;
- range.avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
- /* Need to get better values for those two */
- range.avg_qual.level = 30;
- range.avg_qual.noise = 8;
-
- range.num_bitrates = 1;
- range.bitrate[0] = 2000000; /* 2 Mb/s */
-
- /* Encryption supported ? */
- if (mmc_encr(ioaddr)) {
- range.encoding_size[0] = 8; /* DES = 64 bits key */
- range.num_encoding_sizes = 1;
- range.max_encoding_tokens = 1; /* Only one key possible */
- } else {
- range.num_encoding_sizes = 0;
- range.max_encoding_tokens = 0;
- }
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get range info
+ */
+static int wavelan_get_range(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct iw_range *range = (struct iw_range *) extra;
+ unsigned long flags;
+ int ret = 0;
- /* Copy structure to the user buffer. */
- wv_splx(lp, &flags);
- if (copy_to_user(wrq->u.data.pointer,
- &range,
- sizeof(struct iw_range)))
- ret = -EFAULT;
- wv_splhi(lp, &flags);
- }
- break;
-
- case SIOCGIWPRIV:
- /* Basic checking */
- if (wrq->u.data.pointer != (caddr_t) 0) {
- struct iw_priv_args priv[] = {
- /* { cmd,
- set_args,
- get_args,
- name } */
- { SIOCSIPQTHR,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setqualthr" },
- { SIOCGIPQTHR,
- 0,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
- "getqualthr" },
- { SIOCSIPHISTO,
- IW_PRIV_TYPE_BYTE | 16,
- 0,
- "sethisto" },
- { SIOCGIPHISTO,
- 0,
- IW_PRIV_TYPE_INT | 16,
- "gethisto" },
- };
-
- /* Set the number of available ioctls. */
- wrq->u.data.length = 4;
-
- /* Copy structure to the user buffer. */
- wv_splx(lp, &flags);
- if (copy_to_user(wrq->u.data.pointer,
- (u8 *) priv,
- sizeof(priv)))
- ret = -EFAULT;
- wv_splhi(lp, &flags);
- }
- break;
+ /* Set the length (very important for backward compatibility) */
+ wrqu->data.length = sizeof(struct iw_range);
+
+ /* Set all the info we don't care or don't know about to zero */
+ memset(range, 0, sizeof(struct iw_range));
+
+ /* Set the Wireless Extension versions */
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 9;
+
+ /* Set information in the range struct. */
+ range->throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0xFFFF;
+
+ range->sensitivity = 0x3F;
+ range->max_qual.qual = MMR_SGNL_QUAL;
+ range->max_qual.level = MMR_SIGNAL_LVL;
+ range->max_qual.noise = MMR_SILENCE_LVL;
+ range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
+ /* Need to get better values for those two */
+ range->avg_qual.level = 30;
+ range->avg_qual.noise = 8;
+
+ range->num_bitrates = 1;
+ range->bitrate[0] = 2000000; /* 2 Mb/s */
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
+ if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
+ range->num_channels = 10;
+ range->num_frequency = wv_frequency_list(ioaddr, range->freq,
+ IW_MAX_FREQUENCIES);
+ } else
+ range->num_channels = range->num_frequency = 0;
+
+ /* Encryption supported ? */
+ if (mmc_encr(ioaddr)) {
+ range->encoding_size[0] = 8; /* DES = 64 bits key */
+ range->num_encoding_sizes = 1;
+ range->max_encoding_tokens = 1; /* Only one key possible */
+ } else {
+ range->num_encoding_sizes = 0;
+ range->max_encoding_tokens = 0;
+ }
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
#ifdef WIRELESS_SPY
- case SIOCSIWSPY:
- /* Set the spy list */
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set spy list
+ */
+static int wavelan_set_spy(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct sockaddr *address = (struct sockaddr *) extra;
+ int i;
+ int ret = 0;
- /* Check the number of addresses. */
- if (wrq->u.data.length > IW_MAX_SPY) {
- ret = -E2BIG;
- break;
- }
- lp->spy_number = wrq->u.data.length;
-
- /* Are there are addresses to copy? */
- if (lp->spy_number > 0) {
- struct sockaddr address[IW_MAX_SPY];
- int i;
-
- /* Copy addresses to the driver. */
- wv_splx(lp, &flags);
- err = copy_from_user(address,
- wrq->u.data.pointer,
- sizeof(struct sockaddr)
- * lp->spy_number);
- wv_splhi(lp, &flags);
- if (err) {
- ret = -EFAULT;
- break;
- }
+ /* Disable spy while we copy the addresses.
+ * As we don't disable interrupts, we need to do this */
+ lp->spy_number = 0;
- /* Copy addresses to the lp structure. */
- for (i = 0; i < lp->spy_number; i++) {
- memcpy(lp->spy_address[i],
- address[i].sa_data,
- WAVELAN_ADDR_SIZE);
- }
+ /* Are there are addresses to copy? */
+ if (wrqu->data.length > 0) {
+ /* Copy addresses to the lp structure. */
+ for (i = 0; i < wrqu->data.length; i++) {
+ memcpy(lp->spy_address[i], address[i].sa_data,
+ WAVELAN_ADDR_SIZE);
+ }
- /* Reset structure. */
- memset(lp->spy_stat, 0x00,
- sizeof(iw_qual) * IW_MAX_SPY);
+ /* Reset structure. */
+ memset(lp->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
#ifdef DEBUG_IOCTL_INFO
+ printk(KERN_DEBUG
+ "SetSpy: set of new addresses is: \n");
+ for (i = 0; i < wrqu->data.length; i++)
printk(KERN_DEBUG
- "SetSpy: set of new addresses is: \n");
- for (i = 0; i < wrq->u.data.length; i++)
- printk(KERN_DEBUG
- "%02X:%02X:%02X:%02X:%02X:%02X \n",
- lp->spy_address[i][0],
- lp->spy_address[i][1],
- lp->spy_address[i][2],
- lp->spy_address[i][3],
- lp->spy_address[i][4],
- lp->spy_address[i][5]);
-#endif /* DEBUG_IOCTL_INFO */
- }
+ "%02X:%02X:%02X:%02X:%02X:%02X \n",
+ lp->spy_address[i][0],
+ lp->spy_address[i][1],
+ lp->spy_address[i][2],
+ lp->spy_address[i][3],
+ lp->spy_address[i][4],
+ lp->spy_address[i][5]);
+#endif /* DEBUG_IOCTL_INFO */
+ }
+
+ /* Now we can set the number of addresses */
+ lp->spy_number = wrqu->data.length;
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get spy list
+ */
+static int wavelan_get_spy(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct sockaddr *address = (struct sockaddr *) extra;
+ int i;
- break;
+ /* Set the number of addresses */
+ wrqu->data.length = lp->spy_number;
- case SIOCGIWSPY:
- /* Get the spy list and spy stats. */
+ /* Copy addresses from the lp structure. */
+ for (i = 0; i < lp->spy_number; i++) {
+ memcpy(address[i].sa_data,
+ lp->spy_address[i],
+ WAVELAN_ADDR_SIZE);
+ address[i].sa_family = AF_UNIX;
+ }
+ /* Copy stats to the user buffer (just after). */
+ if(lp->spy_number > 0)
+ memcpy(extra + (sizeof(struct sockaddr) * lp->spy_number),
+ lp->spy_stat, sizeof(iw_qual) * lp->spy_number);
- /* Set the number of addresses */
- wrq->u.data.length = lp->spy_number;
+ /* Reset updated flags. */
+ for (i = 0; i < lp->spy_number; i++)
+ lp->spy_stat[i].updated = 0x0;
- /* Does the user want to have the addresses back? */
- if ((lp->spy_number > 0)
- && (wrq->u.data.pointer != (caddr_t) 0)) {
- struct sockaddr address[IW_MAX_SPY];
- int i;
+ return(0);
+}
+#endif /* WIRELESS_SPY */
- /* Copy addresses from the lp structure. */
- for (i = 0; i < lp->spy_number; i++) {
- memcpy(address[i].sa_data,
- lp->spy_address[i],
- WAVELAN_ADDR_SIZE);
- address[i].sa_family = AF_UNIX;
- }
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : set quality threshold
+ */
+static int wavelan_set_qthr(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
- /* Copy addresses to the user buffer. */
- wv_splx(lp, &flags);
- err = copy_to_user(wrq->u.data.pointer,
- address,
- sizeof(struct sockaddr)
- * lp->spy_number);
-
- /* Copy stats to the user buffer (just after). */
- err |= copy_to_user(wrq->u.data.pointer
- + (sizeof(struct sockaddr)
- * lp->spy_number),
- lp->spy_stat,
- sizeof(iw_qual) * lp->spy_number);
- wv_splhi(lp, &flags);
- if (err) {
- ret = -EFAULT;
- break;
- }
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ psa.psa_quality_thr = *(extra) & 0x0F;
+ psa_write(ioaddr, lp->hacr,
+ (char *) &psa.psa_quality_thr - (char *) &psa,
+ (unsigned char *) &psa.psa_quality_thr, 1);
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev, ioaddr, lp->hacr);
+ mmc_out(ioaddr, mmwoff(0, mmw_quality_thr),
+ psa.psa_quality_thr);
- /* Reset updated flags. */
- for (i = 0; i < lp->spy_number; i++)
- lp->spy_stat[i].updated = 0x0;
- }
- /* if(pointer != NULL) */
- break;
-#endif /* WIRELESS_SPY */
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- /* ------------------ PRIVATE IOCTL ------------------ */
+ return 0;
+}
- case SIOCSIPQTHR:
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- break;
- }
- psa.psa_quality_thr = *(wrq->u.name) & 0x0F;
- psa_write(ioaddr, lp->hacr,
- (char *) &psa.psa_quality_thr - (char *) &psa,
- (unsigned char *) &psa.psa_quality_thr, 1);
- /* update the Wavelan checksum */
- update_psa_checksum(dev, ioaddr, lp->hacr);
- mmc_out(ioaddr, mmwoff(0, mmw_quality_thr),
- psa.psa_quality_thr);
- break;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : get quality threshold
+ */
+static int wavelan_get_qthr(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ unsigned long ioaddr = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
- case SIOCGIPQTHR:
- psa_read(ioaddr, lp->hacr,
- (char *) &psa.psa_quality_thr - (char *) &psa,
- (unsigned char *) &psa.psa_quality_thr, 1);
- *(wrq->u.name) = psa.psa_quality_thr & 0x0F;
- break;
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ psa_read(ioaddr, lp->hacr,
+ (char *) &psa.psa_quality_thr - (char *) &psa,
+ (unsigned char *) &psa.psa_quality_thr, 1);
+ *(extra) = psa.psa_quality_thr & 0x0F;
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return 0;
+}
#ifdef HISTOGRAM
- case SIOCSIPHISTO:
- /* Verify that the user is root. */
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- break;
- }
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : set histogram
+ */
+static int wavelan_set_histo(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
- /* Check the number of intervals. */
- if (wrq->u.data.length > 16) {
- ret = -E2BIG;
- break;
- }
- lp->his_number = wrq->u.data.length;
-
- /* Are there addresses to copy? */
- if (lp->his_number > 0) {
- /* Copy interval ranges to the driver */
- wv_splx(lp, &flags);
- err = copy_from_user(lp->his_range,
- wrq->u.data.pointer,
- sizeof(char) * lp->his_number);
- wv_splhi(lp, &flags);
- if (err) {
- ret = -EFAULT;
- break;
- }
+ /* Check the number of intervals. */
+ if (wrqu->data.length > 16) {
+ return(-E2BIG);
+ }
+
+ /* Disable histo while we copy the addresses.
+ * As we don't disable interrupts, we need to do this */
+ lp->his_number = 0;
+
+ /* Are there ranges to copy? */
+ if (wrqu->data.length > 0) {
+ /* Copy interval ranges to the driver */
+ memcpy(lp->his_range, extra, wrqu->data.length);
- /* Reset structure. */
- memset(lp->his_sum, 0x00, sizeof(long) * 16);
+ {
+ int i;
+ printk(KERN_DEBUG "Histo :");
+ for(i = 0; i < wrqu->data.length; i++)
+ printk(" %d", lp->his_range[i]);
+ printk("\n");
}
- break;
-
- case SIOCGIPHISTO:
- /* Set the number of intervals. */
- wrq->u.data.length = lp->his_number;
-
- /* Give back the distribution statistics */
- if ((lp->his_number > 0)
- && (wrq->u.data.pointer != (caddr_t) 0)) {
- /* Copy data to the user buffer. */
- wv_splx(lp, &flags);
- if (copy_to_user(wrq->u.data.pointer,
- lp->his_sum,
- sizeof(long) * lp->his_number);
- ret = -EFAULT;
- wv_splhi(lp, &flags);
-
- } /* if(pointer != NULL) */
- break;
-#endif /* HISTOGRAM */
- /* ------------------- OTHER IOCTL ------------------- */
+ /* Reset result structure. */
+ memset(lp->his_sum, 0x00, sizeof(long) * 16);
+ }
- default:
- ret = -EOPNOTSUPP;
- } /* switch (cmd) */
+ /* Now we can set the number of ranges */
+ lp->his_number = wrqu->data.length;
- /* Enable interrupts and restore flags. */
- wv_splx(lp, &flags);
+ return(0);
+}
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name);
-#endif
- return ret;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : get histogram
+ */
+static int wavelan_get_histo(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+
+ /* Set the number of intervals. */
+ wrqu->data.length = lp->his_number;
+
+ /* Give back the distribution statistics */
+ if(lp->his_number > 0)
+ memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
+
+ return(0);
}
+#endif /* HISTOGRAM */
+
+/*------------------------------------------------------------------*/
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+static const iw_handler wavelan_handler[] =
+{
+ NULL, /* SIOCSIWNAME */
+ wavelan_get_name, /* SIOCGIWNAME */
+ wavelan_set_nwid, /* SIOCSIWNWID */
+ wavelan_get_nwid, /* SIOCGIWNWID */
+ wavelan_set_freq, /* SIOCSIWFREQ */
+ wavelan_get_freq, /* SIOCGIWFREQ */
+ NULL, /* SIOCSIWMODE */
+ NULL, /* SIOCGIWMODE */
+ wavelan_set_sens, /* SIOCSIWSENS */
+ wavelan_get_sens, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE */
+ wavelan_get_range, /* SIOCGIWRANGE */
+ NULL, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+#ifdef WIRELESS_SPY
+ wavelan_set_spy, /* SIOCSIWSPY */
+ wavelan_get_spy, /* SIOCGIWSPY */
+#else /* WIRELESS_SPY */
+ NULL, /* SIOCSIWSPY */
+ NULL, /* SIOCGIWSPY */
+#endif /* WIRELESS_SPY */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWAP */
+ NULL, /* SIOCGIWAP */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCGIWAPLIST */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWESSID */
+ NULL, /* SIOCGIWESSID */
+ NULL, /* SIOCSIWNICKN */
+ NULL, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWRATE */
+ NULL, /* SIOCGIWRATE */
+ NULL, /* SIOCSIWRTS */
+ NULL, /* SIOCGIWRTS */
+ NULL, /* SIOCSIWFRAG */
+ NULL, /* SIOCGIWFRAG */
+ NULL, /* SIOCSIWTXPOW */
+ NULL, /* SIOCGIWTXPOW */
+ NULL, /* SIOCSIWRETRY */
+ NULL, /* SIOCGIWRETRY */
+ /* Bummer ! Why those are only at the end ??? */
+ wavelan_set_encode, /* SIOCSIWENCODE */
+ wavelan_get_encode, /* SIOCGIWENCODE */
+};
+
+static const iw_handler wavelan_private_handler[] =
+{
+ wavelan_set_qthr, /* SIOCIWFIRSTPRIV */
+ wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */
+#ifdef HISTOGRAM
+ wavelan_set_histo, /* SIOCIWFIRSTPRIV + 2 */
+ wavelan_get_histo, /* SIOCIWFIRSTPRIV + 3 */
+#endif /* HISTOGRAM */
+};
+
+static const struct iw_priv_args wavelan_private_args[] = {
+/*{ cmd, set_args, get_args, name } */
+ { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
+ { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
+ { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
+ { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
+};
+
+static const struct iw_handler_def wavelan_handler_def =
+{
+ num_standard: sizeof(wavelan_handler)/sizeof(iw_handler),
+ num_private: sizeof(wavelan_private_handler)/sizeof(iw_handler),
+ num_private_args: sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+ standard: (iw_handler *) wavelan_handler,
+ private: (iw_handler *) wavelan_private_handler,
+ private_args: (struct iw_priv_args *) wavelan_private_args,
+};
/*------------------------------------------------------------------*/
/*
@@ -2343,7 +2519,7 @@ static iw_stats *wavelan_get_wireless_stats(device * dev)
return (iw_stats *) NULL;
/* Disable interrupts and save flags. */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
wstats = &lp->wstats;
@@ -2371,7 +2547,7 @@ static iw_stats *wavelan_get_wireless_stats(device * dev)
wstats->discard.misc = 0L;
/* Enable interrupts and restore flags. */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_IOCTL_TRACE
printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n",
@@ -2705,7 +2881,7 @@ static inline int wv_packet_write(device * dev, void *buf, short length)
if (clen < ETH_ZLEN)
clen = ETH_ZLEN;
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Check nothing bad has happened */
if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
@@ -2713,7 +2889,7 @@ static inline int wv_packet_write(device * dev, void *buf, short length)
printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n",
dev->name);
#endif
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
return 1;
}
@@ -2791,7 +2967,7 @@ static inline int wv_packet_write(device * dev, void *buf, short length)
if (lp->tx_n_in_use < NTXBLOCKS - 1)
netif_wake_queue(dev);
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_TX_INFO
wv_packet_info((u8 *) buf, length, dev->name,
@@ -2832,9 +3008,9 @@ static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
* we can do it now.
*/
if (lp->reconfig_82586) {
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
wv_82586_config(dev);
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
/* Check that we can continue */
if (lp->tx_n_in_use == (NTXBLOCKS - 1))
return 1;
@@ -3694,7 +3870,7 @@ static void wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Prevent reentrancy. We need to do that because we may have
* multiple interrupt handler running concurrently.
- * It is safe because wv_splhi() disables interrupts before acquiring
+ * It is safe because interrupts are disabled before acquiring
* the spinlock. */
spin_lock(&lp->spinlock);
@@ -3822,7 +3998,7 @@ static void wavelan_watchdog(device * dev)
return;
}
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Try to see if some buffers are not free (in case we missed
* an interrupt */
@@ -3862,7 +4038,7 @@ static void wavelan_watchdog(device * dev)
if (lp->tx_n_in_use < NTXBLOCKS - 1)
netif_wake_queue(dev);
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_INTERRUPT_TRACE
printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
@@ -3909,7 +4085,7 @@ static int wavelan_open(device * dev)
return -EAGAIN;
}
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
if (wv_hw_reset(dev) != -1) {
netif_start_queue(dev);
@@ -3920,10 +4096,10 @@ static int wavelan_open(device * dev)
"%s: wavelan_open(): impossible to start the card\n",
dev->name);
#endif
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
return -EAGAIN;
}
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
@@ -3951,9 +4127,9 @@ static int wavelan_close(device * dev)
/*
* Flush the Tx and disable Rx.
*/
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
wv_82586_stop(dev);
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
free_irq(dev->irq, dev);
@@ -4069,8 +4245,8 @@ static int __init wavelan_config(device * dev)
#endif /* SET_MAC_ADDRESS */
#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
- dev->do_ioctl = wavelan_ioctl;
dev->get_wireless_stats = wavelan_get_wireless_stats;
+ dev->wireless_handlers = (struct iw_handler_def *)&wavelan_handler_def;
#endif
dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 6bc145acc525..44deacab921f 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -345,6 +345,12 @@
* - Fix spinlock stupid bugs that I left in. The driver is now SMP
* compliant and doesn't lockup at startup.
*
+ * Changes made for release in 2.5.2 :
+ * ---------------------------------
+ * - Use new driver API for Wireless Extensions :
+ * o got rid of wavelan_ioctl()
+ * o use a bunch of iw_handler instead
+ *
* Wishes & dreams:
* ----------------
* - roaming (see Pcmcia driver)
@@ -379,6 +385,7 @@
#include <linux/init.h>
#include <linux/wireless.h> /* Wireless extensions */
+#include <net/iw_handler.h> /* Wireless handlers */
/* WaveLAN declarations */
#include "i82586.h"
@@ -436,7 +443,7 @@
/************************ CONSTANTS & MACROS ************************/
#ifdef DEBUG_VERSION_SHOW
-static const char *version = "wavelan.c : v23 (SMP + wireless extensions) 05/10/00\n";
+static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/01\n";
#endif
/* Watchdog temporisation */
@@ -449,11 +456,9 @@ static const char *version = "wavelan.c : v23 (SMP + wireless extensions) 05/10/
#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */
-#define SIOCSIPLTHR SIOCIWFIRSTPRIV + 2 /* Set level threshold */
-#define SIOCGIPLTHR SIOCIWFIRSTPRIV + 3 /* Get level threshold */
-#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 6 /* Set histogram ranges */
-#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 7 /* Get histogram values */
+#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 2 /* Set histogram ranges */
+#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 3 /* Get histogram values */
/****************************** TYPES ******************************/
@@ -516,12 +521,6 @@ struct net_local
/**************************** PROTOTYPES ****************************/
/* ----------------------- MISC. SUBROUTINES ------------------------ */
-static inline void
- wv_splhi(net_local *, /* Disable interrupts, lock driver */
- unsigned long *); /* flags */
-static inline void
- wv_splx(net_local *, /* Enable interrupts, unlock driver */
- unsigned long *); /* flags */
static u_char
wv_irq_to_psa(int);
static int
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 173f937c309e..ef423eadb981 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -66,34 +66,6 @@
/*------------------------------------------------------------------*/
/*
- * Wrapper for disabling interrupts.
- * (note : inline, so optimised away)
- */
-static inline void
-wv_splhi(net_local * lp,
- unsigned long * pflags)
-{
- spin_lock_irqsave(&lp->spinlock, *pflags);
- /* Note : above does the cli(); itself */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper for re-enabling interrupts.
- */
-static inline void
-wv_splx(net_local * lp,
- unsigned long * pflags)
-{
- spin_unlock_irqrestore(&lp->spinlock, *pflags);
-
- /* Note : enabling interrupts on the hardware is done in wv_ru_start()
- * via : outb(OP1_INT_ENABLE, LCCR(base));
- */
-}
-
-/*------------------------------------------------------------------*/
-/*
* Wrapper for reporting error to cardservices
*/
static void cs_error(client_handle_t handle, int func, int ret)
@@ -591,7 +563,7 @@ void wv_nwid_filter(unsigned char mode, net_local *lp)
#endif
/* Disable interrupts & save flags */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
@@ -602,7 +574,7 @@ void wv_nwid_filter(unsigned char mode, net_local *lp)
lp->cell_search=0;
/* ReEnable interrupts & restore flags */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
}
/* Find a record in the WavePoint table matching a given NWID */
@@ -771,7 +743,7 @@ void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
#endif
/* Disable interrupts & save flags */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
@@ -779,7 +751,7 @@ void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
/* ReEnable interrupts & restore flags */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
wv_nwid_filter(!NWID_PROMISC,lp);
lp->curr_point=wavepoint;
@@ -1049,9 +1021,9 @@ wv_82593_reconfig(device * dev)
/* Check if we can do it now ! */
if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
{
- wv_splhi(lp, &flags); /* Disable interrupts */
+ spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
wv_82593_config(dev);
- wv_splx(lp, &flags); /* Re-enable interrupts */
+ spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */
}
else
{
@@ -1179,7 +1151,7 @@ wv_mmc_show(device * dev)
return;
}
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Read the mmc */
mmc_out(base, mmwoff(0, mmw_freeze), 1);
@@ -1191,7 +1163,7 @@ wv_mmc_show(device * dev)
lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
#endif /* WIRELESS_EXT */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
#ifdef DEBUG_SHOW_UNUSED
@@ -1884,557 +1856,1234 @@ wl_his_gather(device * dev,
/*------------------------------------------------------------------*/
/*
- * Perform ioctl : config & info stuff
- * This is here that are treated the wireless extensions (iwconfig)
+ * Wireless Handler : get protocol name
*/
-static int
-wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
- struct ifreq * rq, /* Data passed */
- int cmd) /* Ioctl number */
+static int wavelan_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
{
- ioaddr_t base = dev->base_addr;
- net_local * lp = (net_local *)dev->priv; /* lp is not unused */
- struct iwreq * wrq = (struct iwreq *) rq;
- psa_t psa;
- mm_t m;
- unsigned long flags;
- int ret = 0;
-
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name, cmd);
-#endif
-
- /* Disable interrupts & save flags */
- wv_splhi(lp, &flags);
-
- /* Look what is the request */
- switch(cmd)
- {
- /* --------------- WIRELESS EXTENSIONS --------------- */
-
- case SIOCGIWNAME:
- strcpy(wrq->u.name, "Wavelan");
- break;
+ strcpy(wrqu->name, "WaveLAN");
+ return 0;
+}
- case SIOCSIWNWID:
- /* Set NWID in wavelan */
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set NWID
+ */
+static int wavelan_set_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ mm_t m;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Set NWID in WaveLAN. */
#if WIRELESS_EXT > 8
- if(!wrq->u.nwid.disabled)
- {
- /* Set NWID in psa */
- psa.psa_nwid[0] = (wrq->u.nwid.value & 0xFF00) >> 8;
- psa.psa_nwid[1] = wrq->u.nwid.value & 0xFF;
+ if (!wrqu->nwid.disabled) {
+ /* Set NWID in psa */
+ psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
+ psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
#else /* WIRELESS_EXT > 8 */
- if(wrq->u.nwid.on)
- {
- /* Set NWID in psa */
- psa.psa_nwid[0] = (wrq->u.nwid.nwid & 0xFF00) >> 8;
- psa.psa_nwid[1] = wrq->u.nwid.nwid & 0xFF;
+ if(wrq->u.nwid.on) {
+ /* Set NWID in psa */
+ psa.psa_nwid[0] = (wrq->u.nwid.nwid & 0xFF00) >> 8;
+ psa.psa_nwid[1] = wrq->u.nwid.nwid & 0xFF;
#endif /* WIRELESS_EXT > 8 */
- psa.psa_nwid_select = 0x01;
- psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
- (unsigned char *)psa.psa_nwid, 3);
-
- /* Set NWID in mmc */
- m.w.mmw_netw_id_l = psa.psa_nwid[1];
- m.w.mmw_netw_id_h = psa.psa_nwid[0];
- mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m,
- (unsigned char *)&m.w.mmw_netw_id_l, 2);
- mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
+ psa.psa_nwid_select = 0x01;
+ psa_write(dev,
+ (char *) psa.psa_nwid - (char *) &psa,
+ (unsigned char *) psa.psa_nwid, 3);
+
+ /* Set NWID in mmc. */
+ m.w.mmw_netw_id_l = psa.psa_nwid[1];
+ m.w.mmw_netw_id_h = psa.psa_nwid[0];
+ mmc_write(base,
+ (char *) &m.w.mmw_netw_id_l -
+ (char *) &m,
+ (unsigned char *) &m.w.mmw_netw_id_l, 2);
+ mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
+ } else {
+ /* Disable NWID in the psa. */
+ psa.psa_nwid_select = 0x00;
+ psa_write(dev,
+ (char *) &psa.psa_nwid_select -
+ (char *) &psa,
+ (unsigned char *) &psa.psa_nwid_select,
+ 1);
+
+ /* Disable NWID in the mmc (no filtering). */
+ mmc_out(base, mmwoff(0, mmw_loopt_sel),
+ MMW_LOOPT_SEL_DIS_NWID);
}
- else
- {
- /* Disable nwid in the psa */
- psa.psa_nwid_select = 0x00;
- psa_write(dev, (char *)&psa.psa_nwid_select - (char *)&psa,
- (unsigned char *)&psa.psa_nwid_select, 1);
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev);
- /* Disable nwid in the mmc (no filtering) */
- mmc_out(base, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);
- }
- /* update the Wavelan checksum */
- update_psa_checksum(dev);
- break;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- case SIOCGIWNWID:
- /* Read the NWID */
- psa_read(dev, (char *)psa.psa_nwid - (char *)&psa,
- (unsigned char *)psa.psa_nwid, 3);
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get NWID
+ */
+static int wavelan_get_nwid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Read the NWID. */
+ psa_read(dev,
+ (char *) psa.psa_nwid - (char *) &psa,
+ (unsigned char *) psa.psa_nwid, 3);
#if WIRELESS_EXT > 8
- wrq->u.nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
- wrq->u.nwid.disabled = !(psa.psa_nwid_select);
- wrq->u.nwid.fixed = 1; /* Superfluous */
+ wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
+ wrqu->nwid.disabled = !(psa.psa_nwid_select);
+ wrqu->nwid.fixed = 1; /* Superfluous */
#else /* WIRELESS_EXT > 8 */
- wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
- wrq->u.nwid.on = psa.psa_nwid_select;
+ wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
+ wrq->u.nwid.on = psa.psa_nwid_select;
#endif /* WIRELESS_EXT > 8 */
- break;
- case SIOCSIWFREQ:
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */
- if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
- ret = wv_set_frequency(base, &(wrq->u.freq));
- else
- ret = -EOPNOTSUPP;
- break;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- case SIOCGIWFREQ:
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
- * (does it work for everybody ? - especially old cards...) */
- if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
- {
- unsigned short freq;
+ return ret;
+}
- /* Ask the EEprom to read the frequency from the first area */
- fee_read(base, 0x00 /* 1st area - frequency... */,
- &freq, 1);
- wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
- wrq->u.freq.e = 1;
- }
- else
- {
- psa_read(dev, (char *)&psa.psa_subband - (char *)&psa,
- (unsigned char *)&psa.psa_subband, 1);
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set frequency
+ */
+static int wavelan_set_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ int ret;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
+ if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
+ ret = wv_set_frequency(base, &(wrqu->freq));
+ else
+ ret = -EOPNOTSUPP;
- if(psa.psa_subband <= 4)
- {
- wrq->u.freq.m = fixed_bands[psa.psa_subband];
- wrq->u.freq.e = (psa.psa_subband != 0);
- }
- else
- ret = -EOPNOTSUPP;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get frequency
+ */
+static int wavelan_get_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
+ * Does it work for everybody, especially old cards? */
+ if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
+ unsigned short freq;
+
+ /* Ask the EEPROM to read the frequency from the first area. */
+ fee_read(base, 0x00, &freq, 1);
+ wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
+ wrqu->freq.e = 1;
+ } else {
+ psa_read(dev,
+ (char *) &psa.psa_subband - (char *) &psa,
+ (unsigned char *) &psa.psa_subband, 1);
+
+ if (psa.psa_subband <= 4) {
+ wrqu->freq.m = fixed_bands[psa.psa_subband];
+ wrqu->freq.e = (psa.psa_subband != 0);
+ } else
+ ret = -EOPNOTSUPP;
}
- break;
- case SIOCSIWSENS:
- /* Set the level threshold */
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set level threshold
+ */
+static int wavelan_set_sens(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Set the level threshold. */
#if WIRELESS_EXT > 7
- /* We should complain loudly if wrq->u.sens.fixed = 0, because we
- * can't set auto mode... */
- psa.psa_thr_pre_set = wrq->u.sens.value & 0x3F;
+ /* We should complain loudly if wrqu->sens.fixed = 0, because we
+ * can't set auto mode... */
+ psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
#else /* WIRELESS_EXT > 7 */
- psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;
+ psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;
#endif /* WIRELESS_EXT > 7 */
- psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
- (unsigned char *)&psa.psa_thr_pre_set, 1);
- /* update the Wavelan checksum */
- update_psa_checksum(dev);
- mmc_out(base, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set);
- break;
+ psa_write(dev,
+ (char *) &psa.psa_thr_pre_set - (char *) &psa,
+ (unsigned char *) &psa.psa_thr_pre_set, 1);
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev);
+ mmc_out(base, mmwoff(0, mmw_thr_pre_set),
+ psa.psa_thr_pre_set);
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
- case SIOCGIWSENS:
- /* Read the level threshold */
- psa_read(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
- (unsigned char *)&psa.psa_thr_pre_set, 1);
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get level threshold
+ */
+static int wavelan_get_sens(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Read the level threshold. */
+ psa_read(dev,
+ (char *) &psa.psa_thr_pre_set - (char *) &psa,
+ (unsigned char *) &psa.psa_thr_pre_set, 1);
#if WIRELESS_EXT > 7
- wrq->u.sens.value = psa.psa_thr_pre_set & 0x3F;
- wrq->u.sens.fixed = 1;
+ wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
+ wrqu->sens.fixed = 1;
#else /* WIRELESS_EXT > 7 */
- wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;
+ wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;
#endif /* WIRELESS_EXT > 7 */
- break;
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
#if WIRELESS_EXT > 8
- case SIOCSIWENCODE:
- /* Set encryption key */
- if(!mmc_encr(base))
- {
- ret = -EOPNOTSUPP;
- break;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set encryption key
+ */
+static int wavelan_set_encode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ psa_t psa;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check if capable of encryption */
+ if (!mmc_encr(base)) {
+ ret = -EOPNOTSUPP;
}
- /* Basic checking... */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- /* Check the size of the key */
- if(wrq->u.encoding.length != 8)
- {
- ret = -EINVAL;
- break;
- }
+ /* Check the size of the key */
+ if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
+ ret = -EINVAL;
+ }
- /* Copy the key in the driver */
- if(copy_from_user(psa.psa_encryption_key, wrq->u.encoding.pointer,
- wrq->u.encoding.length))
- {
- ret = -EFAULT;
- break;
- }
+ if(!ret) {
+ /* Basic checking... */
+ if (wrqu->encoding.length == 8) {
+ /* Copy the key in the driver */
+ memcpy(psa.psa_encryption_key, extra,
+ wrqu->encoding.length);
+ psa.psa_encryption_select = 1;
+
+ psa_write(dev,
+ (char *) &psa.psa_encryption_select -
+ (char *) &psa,
+ (unsigned char *) &psa.
+ psa_encryption_select, 8 + 1);
+
+ mmc_out(base, mmwoff(0, mmw_encr_enable),
+ MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
+ mmc_write(base, mmwoff(0, mmw_encr_key),
+ (unsigned char *) &psa.
+ psa_encryption_key, 8);
+ }
- psa.psa_encryption_select = 1;
- psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
- (unsigned char *) &psa.psa_encryption_select, 8+1);
+ /* disable encryption */
+ if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
+ psa.psa_encryption_select = 0;
+ psa_write(dev,
+ (char *) &psa.psa_encryption_select -
+ (char *) &psa,
+ (unsigned char *) &psa.
+ psa_encryption_select, 1);
- mmc_out(base, mmwoff(0, mmw_encr_enable),
- MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
- mmc_write(base, mmwoff(0, mmw_encr_key),
- (unsigned char *) &psa.psa_encryption_key, 8);
+ mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
+ }
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev);
}
- if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
- { /* disable encryption */
- psa.psa_encryption_select = 0;
- psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
- (unsigned char *) &psa.psa_encryption_select, 1);
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
- }
- /* update the Wavelan checksum */
- update_psa_checksum(dev);
- break;
-
- case SIOCGIWENCODE:
- /* Read the encryption key */
- if(!mmc_encr(base))
- {
- ret = -EOPNOTSUPP;
- break;
- }
+ return ret;
+}
- /* only super-user can see encryption key */
- if(!capable(CAP_NET_ADMIN))
- {
- ret = -EPERM;
- break;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get encryption key
+ */
+static int wavelan_get_encode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check if encryption is available */
+ if (!mmc_encr(base)) {
+ ret = -EOPNOTSUPP;
+ } else {
+ /* Read the encryption key */
+ psa_read(dev,
+ (char *) &psa.psa_encryption_select -
+ (char *) &psa,
+ (unsigned char *) &psa.
+ psa_encryption_select, 1 + 8);
+
+ /* encryption is enabled ? */
+ if (psa.psa_encryption_select)
+ wrqu->encoding.flags = IW_ENCODE_ENABLED;
+ else
+ wrqu->encoding.flags = IW_ENCODE_DISABLED;
+ wrqu->encoding.flags |= mmc_encr(base);
+
+ /* Copy the key to the user buffer */
+ wrqu->encoding.length = 8;
+ memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
}
- /* Basic checking... */
- if(wrq->u.encoding.pointer != (caddr_t) 0)
- {
- psa_read(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
- (unsigned char *) &psa.psa_encryption_select, 1+8);
-
- /* encryption is enabled ? */
- if(psa.psa_encryption_select)
- wrq->u.encoding.flags = IW_ENCODE_ENABLED;
- else
- wrq->u.encoding.flags = IW_ENCODE_DISABLED;
- wrq->u.encoding.flags |= mmc_encr(base);
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- /* Copy the key to the user buffer */
- wrq->u.encoding.length = 8;
- if(copy_to_user(wrq->u.encoding.pointer, psa.psa_encryption_key, 8))
- ret = -EFAULT;
- }
- break;
+ return ret;
+}
#endif /* WIRELESS_EXT > 8 */
#ifdef WAVELAN_ROAMING_EXT
#if WIRELESS_EXT > 5
- case SIOCSIWESSID:
- /* Check if disable */
- if(wrq->u.data.flags == 0)
- lp->filter_domains = 0;
- else
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0)
- {
- char essid[IW_ESSID_MAX_SIZE + 1];
- char * endp;
-
- /* Check the size of the string */
- if(wrq->u.data.length > IW_ESSID_MAX_SIZE + 1)
- {
- ret = -E2BIG;
- break;
- }
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set ESSID (domain)
+ */
+static int wavelan_set_essid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check if disable */
+ if(wrqu->data.flags == 0)
+ lp->filter_domains = 0;
+ else {
+ char essid[IW_ESSID_MAX_SIZE + 1];
+ char * endp;
- /* Copy the string in the driver */
- if(copy_from_user(essid, wrq->u.data.pointer, wrq->u.data.length))
- {
- ret = -EFAULT;
- break;
- }
- essid[IW_ESSID_MAX_SIZE] = '\0';
+ /* Terminate the string */
+ memcpy(essid, extra, wrqu->data.length);
+ essid[IW_ESSID_MAX_SIZE] = '\0';
#ifdef DEBUG_IOCTL_INFO
- printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
+ printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
#endif /* DEBUG_IOCTL_INFO */
- /* Convert to a number (note : Wavelan specific) */
- lp->domain_id = simple_strtoul(essid, &endp, 16);
- /* Has it worked ? */
- if(endp > essid)
- lp->filter_domains = 1;
- else
- {
- lp->filter_domains = 0;
- ret = -EINVAL;
- }
- }
- break;
+ /* Convert to a number (note : Wavelan specific) */
+ lp->domain_id = simple_strtoul(essid, &endp, 16);
+ /* Has it worked ? */
+ if(endp > essid)
+ lp->filter_domains = 1;
+ else {
+ lp->filter_domains = 0;
+ ret = -EINVAL;
+ }
+ }
- case SIOCGIWESSID:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0)
- {
- char essid[IW_ESSID_MAX_SIZE + 1];
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
- /* Is the domain ID active ? */
- wrq->u.data.flags = lp->filter_domains;
+ return ret;
+}
- /* Copy Domain ID into a string (Wavelan specific) */
- /* Sound crazy, be we can't have a snprintf in the kernel !!! */
- sprintf(essid, "%lX", lp->domain_id);
- essid[IW_ESSID_MAX_SIZE] = '\0';
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get ESSID (domain)
+ */
+static int wavelan_get_essid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
- /* Set the length */
- wrq->u.data.length = strlen(essid) + 1;
+ /* Is the domain ID active ? */
+ wrqu->data.flags = lp->filter_domains;
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, essid, wrq->u.data.length))
- ret = -EFAULT;
- }
- break;
+ /* Copy Domain ID into a string (Wavelan specific) */
+ /* Sound crazy, be we can't have a snprintf in the kernel !!! */
+ sprintf(extra, "%lX", lp->domain_id);
+ extra[IW_ESSID_MAX_SIZE] = '\0';
- case SIOCSIWAP:
+ /* Set the length */
+ wrqu->data.length = strlen(extra) + 1;
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set AP address
+ */
+static int wavelan_set_wap(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
#ifdef DEBUG_IOCTL_INFO
- printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02X\n",
- wrq->u.ap_addr.sa_data[0],
- wrq->u.ap_addr.sa_data[1],
- wrq->u.ap_addr.sa_data[2],
- wrq->u.ap_addr.sa_data[3],
- wrq->u.ap_addr.sa_data[4],
- wrq->u.ap_addr.sa_data[5]);
+ printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02X\n",
+ wrqu->ap_addr.sa_data[0],
+ wrqu->ap_addr.sa_data[1],
+ wrqu->ap_addr.sa_data[2],
+ wrqu->ap_addr.sa_data[3],
+ wrqu->ap_addr.sa_data[4],
+ wrqu->ap_addr.sa_data[5]);
#endif /* DEBUG_IOCTL_INFO */
- ret = -EOPNOTSUPP; /* Not supported yet */
- break;
+ return -EOPNOTSUPP;
+}
- case SIOCGIWAP:
- /* Should get the real McCoy instead of own Ethernet address */
- memcpy(wrq->u.ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
- wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get AP address
+ */
+static int wavelan_get_wap(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ /* Should get the real McCoy instead of own Ethernet address */
+ memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- ret = -EOPNOTSUPP; /* Not supported yet */
- break;
+ return -EOPNOTSUPP;
+}
#endif /* WIRELESS_EXT > 5 */
#endif /* WAVELAN_ROAMING_EXT */
#if WIRELESS_EXT > 8
#ifdef WAVELAN_ROAMING
- case SIOCSIWMODE:
- switch(wrq->u.mode)
- {
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set mode
+ */
+static int wavelan_set_mode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+ int ret = 0;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Check mode */
+ switch(wrqu->mode) {
case IW_MODE_ADHOC:
- if(do_roaming)
- {
- wv_roam_cleanup(dev);
- do_roaming = 0;
- }
- break;
+ if(do_roaming) {
+ wv_roam_cleanup(dev);
+ do_roaming = 0;
+ }
+ break;
case IW_MODE_INFRA:
- if(!do_roaming)
- {
- wv_roam_init(dev);
- do_roaming = 1;
- }
- break;
+ if(!do_roaming) {
+ wv_roam_init(dev);
+ do_roaming = 1;
+ }
+ break;
default:
- ret = -EINVAL;
+ ret = -EINVAL;
}
- break;
- case SIOCGIWMODE:
- if(do_roaming)
- wrq->u.mode = IW_MODE_INFRA;
- else
- wrq->u.mode = IW_MODE_ADHOC;
- break;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get mode
+ */
+static int wavelan_get_mode(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ if(do_roaming)
+ wrqu->mode = IW_MODE_INFRA;
+ else
+ wrqu->mode = IW_MODE_ADHOC;
+
+ return 0;
+}
#endif /* WAVELAN_ROAMING */
#endif /* WIRELESS_EXT > 8 */
- case SIOCGIWRANGE:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0)
- {
- struct iw_range range;
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get range info
+ */
+static int wavelan_get_range(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct iw_range *range = (struct iw_range *) extra;
+ unsigned long flags;
+ int ret = 0;
- /* Set the length (very important for backward compatibility) */
- wrq->u.data.length = sizeof(struct iw_range);
+ /* Set the length (very important for backward compatibility) */
+ wrqu->data.length = sizeof(struct iw_range);
- /* Set all the info we don't care or don't know about to zero */
- memset(&range, 0, sizeof(range));
+ /* Set all the info we don't care or don't know about to zero */
+ memset(range, 0, sizeof(struct iw_range));
#if WIRELESS_EXT > 10
- /* Set the Wireless Extension versions */
- range.we_version_compiled = WIRELESS_EXT;
- range.we_version_source = 9; /* Nothing for us in v10 and v11 */
+ /* Set the Wireless Extension versions */
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 9;
#endif /* WIRELESS_EXT > 10 */
- /* Set information in the range struct */
- range.throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */
- range.min_nwid = 0x0000;
- range.max_nwid = 0xFFFF;
-
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */
- if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
- (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
- {
- range.num_channels = 10;
- range.num_frequency = wv_frequency_list(base, range.freq,
- IW_MAX_FREQUENCIES);
- }
- else
- range.num_channels = range.num_frequency = 0;
+ /* Set information in the range struct. */
+ range->throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0xFFFF;
- range.sensitivity = 0x3F;
- range.max_qual.qual = MMR_SGNL_QUAL;
- range.max_qual.level = MMR_SIGNAL_LVL;
- range.max_qual.noise = MMR_SILENCE_LVL;
+ range->sensitivity = 0x3F;
+ range->max_qual.qual = MMR_SGNL_QUAL;
+ range->max_qual.level = MMR_SIGNAL_LVL;
+ range->max_qual.noise = MMR_SILENCE_LVL;
#if WIRELESS_EXT > 11
- range.avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
- /* Need to get better values for those two */
- range.avg_qual.level = 30;
- range.avg_qual.noise = 8;
+ range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
+ /* Need to get better values for those two */
+ range->avg_qual.level = 30;
+ range->avg_qual.noise = 8;
#endif /* WIRELESS_EXT > 11 */
#if WIRELESS_EXT > 7
- range.num_bitrates = 1;
- range.bitrate[0] = 2000000; /* 2 Mb/s */
+ range->num_bitrates = 1;
+ range->bitrate[0] = 2000000; /* 2 Mb/s */
#endif /* WIRELESS_EXT > 7 */
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
+ if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
+ (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
+ range->num_channels = 10;
+ range->num_frequency = wv_frequency_list(base, range->freq,
+ IW_MAX_FREQUENCIES);
+ } else
+ range->num_channels = range->num_frequency = 0;
+
#if WIRELESS_EXT > 8
- /* Encryption supported ? */
- if(mmc_encr(base))
- {
- range.encoding_size[0] = 8; /* DES = 64 bits key */
- range.num_encoding_sizes = 1;
- range.max_encoding_tokens = 1; /* Only one key possible */
- }
- else
- {
- range.num_encoding_sizes = 0;
- range.max_encoding_tokens = 0;
- }
+ /* Encryption supported ? */
+ if (mmc_encr(base)) {
+ range->encoding_size[0] = 8; /* DES = 64 bits key */
+ range->num_encoding_sizes = 1;
+ range->max_encoding_tokens = 1; /* Only one key possible */
+ } else {
+ range->num_encoding_sizes = 0;
+ range->max_encoding_tokens = 0;
+ }
#endif /* WIRELESS_EXT > 8 */
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, &range,
- sizeof(struct iw_range)))
- ret = -EFAULT;
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return ret;
+}
+
+#ifdef WIRELESS_SPY
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set spy list
+ */
+static int wavelan_set_spy(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct sockaddr *address = (struct sockaddr *) extra;
+ int i;
+ int ret = 0;
+
+ /* Disable spy while we copy the addresses.
+ * As we don't disable interrupts, we need to do this */
+ lp->spy_number = 0;
+
+ /* Are there are addresses to copy? */
+ if (wrqu->data.length > 0) {
+ /* Copy addresses to the lp structure. */
+ for (i = 0; i < wrqu->data.length; i++) {
+ memcpy(lp->spy_address[i], address[i].sa_data,
+ WAVELAN_ADDR_SIZE);
+ }
+
+ /* Reset structure. */
+ memset(lp->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
+
+#ifdef DEBUG_IOCTL_INFO
+ printk(KERN_DEBUG
+ "SetSpy: set of new addresses is: \n");
+ for (i = 0; i < wrqu->data.length; i++)
+ printk(KERN_DEBUG
+ "%02X:%02X:%02X:%02X:%02X:%02X \n",
+ lp->spy_address[i][0],
+ lp->spy_address[i][1],
+ lp->spy_address[i][2],
+ lp->spy_address[i][3],
+ lp->spy_address[i][4],
+ lp->spy_address[i][5]);
+#endif /* DEBUG_IOCTL_INFO */
}
+
+ /* Now we can set the number of addresses */
+ lp->spy_number = wrqu->data.length;
+
+ return ret;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get spy list
+ */
+static int wavelan_get_spy(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ struct sockaddr *address = (struct sockaddr *) extra;
+ int i;
+
+ /* Set the number of addresses */
+ wrqu->data.length = lp->spy_number;
+
+ /* Copy addresses from the lp structure. */
+ for (i = 0; i < lp->spy_number; i++) {
+ memcpy(address[i].sa_data,
+ lp->spy_address[i],
+ WAVELAN_ADDR_SIZE);
+ address[i].sa_family = AF_UNIX;
+ }
+ /* Copy stats to the user buffer (just after). */
+ if(lp->spy_number > 0)
+ memcpy(extra + (sizeof(struct sockaddr) * lp->spy_number),
+ lp->spy_stat, sizeof(iw_qual) * lp->spy_number);
+
+ /* Reset updated flags. */
+ for (i = 0; i < lp->spy_number; i++)
+ lp->spy_stat[i].updated = 0x0;
+
+ return(0);
+}
+#endif /* WIRELESS_SPY */
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : set quality threshold
+ */
+static int wavelan_set_qthr(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ ioaddr_t base = dev->base_addr;
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ psa.psa_quality_thr = *(extra) & 0x0F;
+ psa_write(dev,
+ (char *) &psa.psa_quality_thr - (char *) &psa,
+ (unsigned char *) &psa.psa_quality_thr, 1);
+ /* update the Wavelan checksum */
+ update_psa_checksum(dev);
+ mmc_out(base, mmwoff(0, mmw_quality_thr),
+ psa.psa_quality_thr);
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : get quality threshold
+ */
+static int wavelan_get_qthr(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ psa_t psa;
+ unsigned long flags;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ psa_read(dev,
+ (char *) &psa.psa_quality_thr - (char *) &psa,
+ (unsigned char *) &psa.psa_quality_thr, 1);
+ *(extra) = psa.psa_quality_thr & 0x0F;
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return 0;
+}
+
+#ifdef WAVELAN_ROAMING
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : set roaming
+ */
+static int wavelan_set_roam(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+ unsigned long flags;
+
+ /* Disable interrupts and save flags. */
+ spin_lock_irqsave(&lp->spinlock, flags);
+
+ /* Note : should check if user == root */
+ if(do_roaming && (*extra)==0)
+ wv_roam_cleanup(dev);
+ else if(do_roaming==0 && (*extra)!=0)
+ wv_roam_init(dev);
+
+ do_roaming = (*extra);
+
+ /* Enable interrupts and restore flags. */
+ spin_unlock_irqrestore(&lp->spinlock, flags);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : get quality threshold
+ */
+static int wavelan_get_roam(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ *(extra) = do_roaming;
+
+ return 0;
+}
+#endif /* WAVELAN_ROAMING */
+
+#ifdef HISTOGRAM
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : set histogram
+ */
+static int wavelan_set_histo(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+
+ /* Check the number of intervals. */
+ if (wrqu->data.length > 16) {
+ return(-E2BIG);
+ }
+
+ /* Disable histo while we copy the addresses.
+ * As we don't disable interrupts, we need to do this */
+ lp->his_number = 0;
+
+ /* Are there ranges to copy? */
+ if (wrqu->data.length > 0) {
+ /* Copy interval ranges to the driver */
+ memcpy(lp->his_range, extra, wrqu->data.length);
+
+ {
+ int i;
+ printk(KERN_DEBUG "Histo :");
+ for(i = 0; i < wrqu->data.length; i++)
+ printk(" %d", lp->his_range[i]);
+ printk("\n");
+ }
+
+ /* Reset result structure. */
+ memset(lp->his_sum, 0x00, sizeof(long) * 16);
+ }
+
+ /* Now we can set the number of ranges */
+ lp->his_number = wrqu->data.length;
+
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Private Handler : get histogram
+ */
+static int wavelan_get_histo(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ net_local *lp = (net_local *) dev->priv; /* lp is not unused */
+
+ /* Set the number of intervals. */
+ wrqu->data.length = lp->his_number;
+
+ /* Give back the distribution statistics */
+ if(lp->his_number > 0)
+ memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
+
+ return(0);
+}
+#endif /* HISTOGRAM */
+
+/*------------------------------------------------------------------*/
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+static const struct iw_priv_args wavelan_private_args[] = {
+/*{ cmd, set_args, get_args, name } */
+ { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
+ { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
+ { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" },
+ { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
+ { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
+ { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
+};
+
+#if WIRELESS_EXT > 12
+
+static const iw_handler wavelan_handler[] =
+{
+ NULL, /* SIOCSIWNAME */
+ wavelan_get_name, /* SIOCGIWNAME */
+ wavelan_set_nwid, /* SIOCSIWNWID */
+ wavelan_get_nwid, /* SIOCGIWNWID */
+ wavelan_set_freq, /* SIOCSIWFREQ */
+ wavelan_get_freq, /* SIOCGIWFREQ */
+#ifdef WAVELAN_ROAMING
+ wavelan_set_mode, /* SIOCSIWMODE */
+ wavelan_get_mode, /* SIOCGIWMODE */
+#else /* WAVELAN_ROAMING */
+ NULL, /* SIOCSIWMODE */
+ NULL, /* SIOCGIWMODE */
+#endif /* WAVELAN_ROAMING */
+ wavelan_set_sens, /* SIOCSIWSENS */
+ wavelan_get_sens, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE */
+ wavelan_get_range, /* SIOCGIWRANGE */
+ NULL, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+#ifdef WIRELESS_SPY
+ wavelan_set_spy, /* SIOCSIWSPY */
+ wavelan_get_spy, /* SIOCGIWSPY */
+#else /* WIRELESS_SPY */
+ NULL, /* SIOCSIWSPY */
+ NULL, /* SIOCGIWSPY */
+#endif /* WIRELESS_SPY */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+#ifdef WAVELAN_ROAMING_EXT
+ wavelan_set_wap, /* SIOCSIWAP */
+ wavelan_get_wap, /* SIOCGIWAP */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCGIWAPLIST */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ wavelan_set_essid, /* SIOCSIWESSID */
+ wavelan_get_essid, /* SIOCGIWESSID */
+#else /* WAVELAN_ROAMING_EXT */
+ NULL, /* SIOCSIWAP */
+ NULL, /* SIOCGIWAP */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCGIWAPLIST */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWESSID */
+ NULL, /* SIOCGIWESSID */
+#endif /* WAVELAN_ROAMING_EXT */
+#if WIRELESS_EXT > 8
+ NULL, /* SIOCSIWNICKN */
+ NULL, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ NULL, /* SIOCSIWRATE */
+ NULL, /* SIOCGIWRATE */
+ NULL, /* SIOCSIWRTS */
+ NULL, /* SIOCGIWRTS */
+ NULL, /* SIOCSIWFRAG */
+ NULL, /* SIOCGIWFRAG */
+ NULL, /* SIOCSIWTXPOW */
+ NULL, /* SIOCGIWTXPOW */
+ NULL, /* SIOCSIWRETRY */
+ NULL, /* SIOCGIWRETRY */
+ wavelan_set_encode, /* SIOCSIWENCODE */
+ wavelan_get_encode, /* SIOCGIWENCODE */
+#endif /* WIRELESS_EXT > 8 */
+};
+
+static const iw_handler wavelan_private_handler[] =
+{
+ wavelan_set_qthr, /* SIOCIWFIRSTPRIV */
+ wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */
+#ifdef WAVELAN_ROAMING
+ wavelan_set_roam, /* SIOCIWFIRSTPRIV + 2 */
+ wavelan_get_roam, /* SIOCIWFIRSTPRIV + 3 */
+#else /* WAVELAN_ROAMING */
+ NULL, /* SIOCIWFIRSTPRIV + 2 */
+ NULL, /* SIOCIWFIRSTPRIV + 3 */
+#endif /* WAVELAN_ROAMING */
+#ifdef HISTOGRAM
+ wavelan_set_histo, /* SIOCIWFIRSTPRIV + 4 */
+ wavelan_get_histo, /* SIOCIWFIRSTPRIV + 5 */
+#endif /* HISTOGRAM */
+};
+
+static const struct iw_handler_def wavelan_handler_def =
+{
+ num_standard: sizeof(wavelan_handler)/sizeof(iw_handler),
+ num_private: sizeof(wavelan_private_handler)/sizeof(iw_handler),
+ num_private_args: sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+ standard: (iw_handler *) wavelan_handler,
+ private: (iw_handler *) wavelan_private_handler,
+ private_args: (struct iw_priv_args *) wavelan_private_args,
+};
+
+#else /* WIRELESS_EXT > 12 */
+/*------------------------------------------------------------------*/
+/*
+ * Perform ioctl : config & info stuff
+ * This is here that are treated the wireless extensions (iwconfig)
+ */
+static int
+wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
+ struct ifreq * rq, /* Data passed */
+ int cmd) /* Ioctl number */
+{
+ struct iwreq * wrq = (struct iwreq *) rq;
+ int ret = 0;
+
+#ifdef DEBUG_IOCTL_TRACE
+ printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name, cmd);
+#endif
+
+ /* Look what is the request */
+ switch(cmd)
+ {
+ /* --------------- WIRELESS EXTENSIONS --------------- */
+
+ case SIOCGIWNAME:
+ wavelan_get_name(dev, NULL, &(wrq->u), NULL);
break;
- case SIOCGIWPRIV:
- /* Basic checking... */
- if(wrq->u.data.pointer != (caddr_t) 0)
- {
- struct iw_priv_args priv[] =
- { /* cmd, set_args, get_args, name */
- { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
- { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
- { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
- { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
- { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1 , 0, "setroam" },
- { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
- };
+ case SIOCSIWNWID:
+ ret = wavelan_set_nwid(dev, NULL, &(wrq->u), NULL);
+ break;
- /* Set the number of ioctl available */
- wrq->u.data.length = 6;
+ case SIOCGIWNWID:
+ ret = wavelan_get_nwid(dev, NULL, &(wrq->u), NULL);
+ break;
- /* Copy structure to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
- sizeof(priv)))
+ case SIOCSIWFREQ:
+ ret = wavelan_set_freq(dev, NULL, &(wrq->u), NULL);
+ break;
+
+ case SIOCGIWFREQ:
+ ret = wavelan_get_freq(dev, NULL, &(wrq->u), NULL);
+ break;
+
+ case SIOCSIWSENS:
+ ret = wavelan_set_sens(dev, NULL, &(wrq->u), NULL);
+ break;
+
+ case SIOCGIWSENS:
+ ret = wavelan_get_sens(dev, NULL, &(wrq->u), NULL);
+ break;
+
+#if WIRELESS_EXT > 8
+ case SIOCSIWENCODE:
+ {
+ char keybuf[8];
+ if (wrq->u.encoding.pointer) {
+ /* We actually have a key to set */
+ if (wrq->u.encoding.length != 8) {
+ ret = -EINVAL;
+ break;
+ }
+ if (copy_from_user(keybuf,
+ wrq->u.encoding.pointer,
+ wrq->u.encoding.length)) {
ret = -EFAULT;
+ break;
+ }
+ } else if (wrq->u.encoding.length != 0) {
+ ret = -EINVAL;
+ break;
}
+ ret = wavelan_set_encode(dev, NULL, &(wrq->u), keybuf);
+ }
break;
-#ifdef WIRELESS_SPY
- case SIOCSIWSPY:
- /* Set the spy list */
+ case SIOCGIWENCODE:
+ if (! capable(CAP_NET_ADMIN)) {
+ ret = -EPERM;
+ break;
+ }
+ {
+ char keybuf[8];
+ ret = wavelan_get_encode(dev, NULL,
+ &(wrq->u),
+ keybuf);
+ if (wrq->u.encoding.pointer) {
+ if (copy_to_user(wrq->u.encoding.pointer,
+ keybuf,
+ wrq->u.encoding.length))
+ ret = -EFAULT;
+ }
+ }
+ break;
+#endif /* WIRELESS_EXT > 8 */
- /* Check the number of addresses */
- if(wrq->u.data.length > IW_MAX_SPY)
- {
+#ifdef WAVELAN_ROAMING_EXT
+#if WIRELESS_EXT > 5
+ case SIOCSIWESSID:
+ {
+ char essidbuf[IW_ESSID_MAX_SIZE+1];
+ if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
ret = -E2BIG;
break;
}
- lp->spy_number = wrq->u.data.length;
-
- /* If there is some addresses to copy */
- if(lp->spy_number > 0)
- {
- struct sockaddr address[IW_MAX_SPY];
- int i;
-
- /* Copy addresses to the driver */
- if(copy_from_user(address, wrq->u.data.pointer,
- sizeof(struct sockaddr) * lp->spy_number))
- {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(essidbuf, wrq->u.essid.pointer,
+ wrq->u.essid.length)) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = wavelan_set_essid(dev, NULL,
+ &(wrq->u),
+ essidbuf);
+ }
+ break;
- /* Copy addresses to the lp structure */
- for(i = 0; i < lp->spy_number; i++)
- {
- memcpy(lp->spy_address[i], address[i].sa_data,
- WAVELAN_ADDR_SIZE);
- }
+ case SIOCGIWESSID:
+ {
+ char essidbuf[IW_ESSID_MAX_SIZE+1];
+ ret = wavelan_get_essid(dev, NULL,
+ &(wrq->u),
+ essidbuf);
+ if (wrq->u.essid.pointer)
+ if ( copy_to_user(wrq->u.essid.pointer,
+ essidbuf,
+ wrq->u.essid.length) )
+ ret = -EFAULT;
+ }
+ break;
- /* Reset structure... */
- memset(lp->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
+ case SIOCSIWAP:
+ ret = wavelan_set_wap(dev, NULL, &(wrq->u), NULL);
+ break;
-#ifdef DEBUG_IOCTL_INFO
- printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n");
- for(i = 0; i < wrq->u.data.length; i++)
- printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n",
- lp->spy_address[i][0],
- lp->spy_address[i][1],
- lp->spy_address[i][2],
- lp->spy_address[i][3],
- lp->spy_address[i][4],
- lp->spy_address[i][5]);
-#endif /* DEBUG_IOCTL_INFO */
- }
+ case SIOCGIWAP:
+ ret = wavelan_get_wap(dev, NULL, &(wrq->u), NULL);
+ break;
+#endif /* WIRELESS_EXT > 5 */
+#endif /* WAVELAN_ROAMING_EXT */
+#if WIRELESS_EXT > 8
+#ifdef WAVELAN_ROAMING
+ case SIOCSIWMODE:
+ ret = wavelan_set_mode(dev, NULL, &(wrq->u), NULL);
break;
- case SIOCGIWSPY:
- /* Get the spy list and spy stats */
+ case SIOCGIWMODE:
+ ret = wavelan_get_mode(dev, NULL, &(wrq->u), NULL);
+ break;
+#endif /* WAVELAN_ROAMING */
+#endif /* WIRELESS_EXT > 8 */
- /* Set the number of addresses */
- wrq->u.data.length = lp->spy_number;
+ case SIOCGIWRANGE:
+ {
+ struct iw_range range;
+ ret = wavelan_get_range(dev, NULL,
+ &(wrq->u),
+ (char *) &range);
+ if (copy_to_user(wrq->u.data.pointer, &range,
+ sizeof(struct iw_range)))
+ ret = -EFAULT;
+ }
+ break;
- /* If the user want to have the addresses back... */
- if((lp->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
+ case SIOCGIWPRIV:
+ /* Basic checking... */
+ if(wrq->u.data.pointer != (caddr_t) 0)
{
- struct sockaddr address[IW_MAX_SPY];
- int i;
-
- /* Copy addresses from the lp structure */
- for(i = 0; i < lp->spy_number; i++)
- {
- memcpy(address[i].sa_data, lp->spy_address[i],
- WAVELAN_ADDR_SIZE);
- address[i].sa_family = ARPHRD_ETHER;
- }
-
- /* Copy addresses to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, address,
- sizeof(struct sockaddr) * lp->spy_number))
- {
- ret = -EFAULT;
- break;
- }
+ /* Set the number of ioctl available */
+ wrq->u.data.length = sizeof(wavelan_private_args) / sizeof(wavelan_private_args[0]);
- /* Copy stats to the user buffer (just after) */
- if(copy_to_user(wrq->u.data.pointer +
- (sizeof(struct sockaddr) * lp->spy_number),
- lp->spy_stat, sizeof(iw_qual) * lp->spy_number))
- {
- ret = -EFAULT;
- break;
- }
+ /* Copy structure to the user buffer */
+ if(copy_to_user(wrq->u.data.pointer, (u_char *) wavelan_private_args,
+ sizeof(wavelan_private_args)))
+ ret = -EFAULT;
+ }
+ break;
- /* Reset updated flags */
- for(i = 0; i < lp->spy_number; i++)
- lp->spy_stat[i].updated = 0x0;
- } /* if(pointer != NULL) */
+#ifdef WIRELESS_SPY
+ case SIOCSIWSPY:
+ {
+ struct sockaddr address[IW_MAX_SPY];
+ /* Check the number of addresses */
+ if (wrq->u.data.length > IW_MAX_SPY) {
+ ret = -E2BIG;
+ break;
+ }
+ /* Get the data in the driver */
+ if (wrq->u.data.pointer) {
+ if (copy_from_user((char *) address,
+ wrq->u.data.pointer,
+ sizeof(struct sockaddr) *
+ wrq->u.data.length)) {
+ ret = -EFAULT;
+ break;
+ }
+ } else if (wrq->u.data.length != 0) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = wavelan_set_spy(dev, NULL, &(wrq->u),
+ (char *) address);
+ }
+ break;
+ case SIOCGIWSPY:
+ {
+ char buffer[IW_MAX_SPY * (sizeof(struct sockaddr) +
+ sizeof(struct iw_quality))];
+ ret = wavelan_get_spy(dev, NULL, &(wrq->u),
+ buffer);
+ if (wrq->u.data.pointer) {
+ if (copy_to_user(wrq->u.data.pointer,
+ buffer,
+ (wrq->u.data.length *
+ (sizeof(struct sockaddr) +
+ sizeof(struct iw_quality)))
+ ))
+ ret = -EFAULT;
+ }
+ }
break;
#endif /* WIRELESS_SPY */
@@ -2446,34 +3095,21 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
ret = -EPERM;
break;
}
- psa.psa_quality_thr = *(wrq->u.name) & 0x0F;
- psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
- (unsigned char *)&psa.psa_quality_thr, 1);
- /* update the Wavelan checksum */
- update_psa_checksum(dev);
- mmc_out(base, mmwoff(0, mmw_quality_thr), psa.psa_quality_thr);
+ ret = wavelan_set_qthr(dev, NULL, &(wrq->u), NULL);
break;
case SIOCGIPQTHR:
- psa_read(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
- (unsigned char *)&psa.psa_quality_thr, 1);
- *(wrq->u.name) = psa.psa_quality_thr & 0x0F;
+ ret = wavelan_get_qthr(dev, NULL, &(wrq->u), NULL);
break;
#ifdef WAVELAN_ROAMING
case SIOCSIPROAM:
/* Note : should check if user == root */
- if(do_roaming && (*wrq->u.name)==0)
- wv_roam_cleanup(dev);
- else if(do_roaming==0 && (*wrq->u.name)!=0)
- wv_roam_init(dev);
-
- do_roaming = (*wrq->u.name);
-
+ ret = wavelan_set_roam(dev, NULL, &(wrq->u), NULL);
break;
case SIOCGIPROAM:
- *(wrq->u.name) = do_roaming;
+ ret = wavelan_get_roam(dev, NULL, &(wrq->u), NULL);
break;
#endif /* WAVELAN_ROAMING */
@@ -2484,44 +3120,44 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
{
ret = -EPERM;
}
-
- /* Check the number of intervals */
- if(wrq->u.data.length > 16)
- {
- ret = -E2BIG;
- break;
+ {
+ char buffer[16];
+ /* Check the number of intervals */
+ if(wrq->u.data.length > 16)
+ {
+ ret = -E2BIG;
+ break;
}
- lp->his_number = wrq->u.data.length;
-
- /* If there is some addresses to copy */
- if(lp->his_number > 0)
- {
- /* Copy interval ranges to the driver */
- if(copy_from_user(lp->his_range, wrq->u.data.pointer,
- sizeof(char) * lp->his_number))
- {
- ret = -EFAULT;
- break;
- }
-
- /* Reset structure... */
- memset(lp->his_sum, 0x00, sizeof(long) * 16);
+ /* Get the data in the driver */
+ if (wrq->u.data.pointer) {
+ if (copy_from_user(buffer,
+ wrq->u.data.pointer,
+ sizeof(struct sockaddr) *
+ wrq->u.data.length)) {
+ ret = -EFAULT;
+ break;
+ }
+ } else if (wrq->u.data.length != 0) {
+ ret = -EINVAL;
+ break;
}
+ ret = wavelan_set_histo(dev, NULL, &(wrq->u),
+ buffer);
+ }
break;
case SIOCGIPHISTO:
- /* Set the number of intervals */
- wrq->u.data.length = lp->his_number;
-
- /* Give back the distribution statistics */
- if((lp->his_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
- {
- /* Copy data to the user buffer */
- if(copy_to_user(wrq->u.data.pointer, lp->his_sum,
- sizeof(long) * lp->his_number))
+ {
+ long buffer[16];
+ ret = wavelan_get_histo(dev, NULL, &(wrq->u),
+ (char *) buffer);
+ if (wrq->u.data.pointer) {
+ if (copy_to_user(wrq->u.data.pointer,
+ buffer,
+ (wrq->u.data.length * sizeof(long))))
ret = -EFAULT;
-
- } /* if(pointer != NULL) */
+ }
+ }
break;
#endif /* HISTOGRAM */
@@ -2531,14 +3167,12 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
ret = -EOPNOTSUPP;
}
- /* ReEnable interrupts & restore flags */
- wv_splx(lp, &flags);
-
#ifdef DEBUG_IOCTL_TRACE
printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name);
#endif
return ret;
}
+#endif /* WIRELESS_EXT > 12 */
/*------------------------------------------------------------------*/
/*
@@ -2559,7 +3193,7 @@ wavelan_get_wireless_stats(device * dev)
#endif
/* Disable interrupts & save flags */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
wstats = &lp->wstats;
@@ -2585,7 +3219,7 @@ wavelan_get_wireless_stats(device * dev)
wstats->discard.misc = 0L;
/* ReEnable interrupts & restore flags */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_IOCTL_TRACE
printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
@@ -2921,7 +3555,7 @@ wv_packet_write(device * dev,
printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
#endif
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Check if we need some padding */
if(clen < ETH_ZLEN)
@@ -2951,7 +3585,7 @@ wv_packet_write(device * dev,
/* Keep stats up to date */
lp->stats.tx_bytes += length;
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_TX_INFO
wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
@@ -2991,9 +3625,9 @@ wavelan_packet_xmit(struct sk_buff * skb,
* we can do it now */
if(lp->reconfig_82593)
{
- wv_splhi(lp, &flags); /* Disable interrupts */
+ spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
wv_82593_config(dev);
- wv_splx(lp, &flags); /* Re-enable interrupts */
+ spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */
/* Note : the configure procedure was totally synchronous,
* so the Tx buffer is now free */
}
@@ -3230,7 +3864,7 @@ wv_ru_stop(device * dev)
printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
#endif
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* First, send the LAN controller a stop receive command */
wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
@@ -3255,7 +3889,7 @@ wv_ru_stop(device * dev)
}
while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
/* If there was a problem */
if(spin <= 0)
@@ -3299,7 +3933,7 @@ wv_ru_start(device * dev)
if(!wv_ru_stop(dev))
return FALSE;
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Now we know that no command is being executed. */
@@ -3354,7 +3988,7 @@ wv_ru_start(device * dev)
}
#endif
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
@@ -3630,7 +4264,7 @@ wv_hw_config(device * dev)
return FALSE;
/* Disable interrupts */
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Disguised goto ;-) */
do
@@ -3695,7 +4329,7 @@ wv_hw_config(device * dev)
while(0);
/* Re-enable interrupts */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
@@ -4021,7 +4655,7 @@ wavelan_interrupt(int irq,
/* Prevent reentrancy. We need to do that because we may have
* multiple interrupt handler running concurently.
- * It is safe because wv_splhi() disable interrupts before aquiring
+ * It is safe because interrupts are disabled before aquiring
* the spinlock. */
spin_lock(&lp->spinlock);
@@ -4254,7 +4888,7 @@ wavelan_watchdog(device * dev)
dev->name);
#endif
- wv_splhi(lp, &flags);
+ spin_lock_irqsave(&lp->spinlock, flags);
/* Ask to abort the current command */
outb(OP0_ABORT, LCCR(base));
@@ -4265,7 +4899,7 @@ wavelan_watchdog(device * dev)
aborted = TRUE;
/* Release spinlock here so that wv_hw_reset() can grab it */
- wv_splx(lp, &flags);
+ spin_unlock_irqrestore(&lp->spinlock, flags);
/* Check if we were successful in aborting it */
if(!aborted)
@@ -4530,7 +5164,11 @@ wavelan_attach(void)
dev->watchdog_timeo = WATCHDOG_JIFFIES;
#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
+#if WIRELESS_EXT > 12
+ dev->wireless_handlers = (struct iw_handler_def *)&wavelan_handler_def;
+#else /* WIRELESS_EXT > 12 */
dev->do_ioctl = wavelan_ioctl; /* wireless extensions */
+#endif /* WIRELESS_EXT > 12 */
dev->get_wireless_stats = wavelan_get_wireless_stats;
#endif
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 67b19932aed4..99564233fb49 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -394,6 +394,12 @@
* o control first busy loop in wv_82593_cmd()
* o Extend spinlock protection in wv_hw_config()
*
+ * Changes made for release in 3.1.33 :
+ * ----------------------------------
+ * - Optional use new driver API for Wireless Extensions :
+ * o got rid of wavelan_ioctl()
+ * o use a bunch of iw_handler instead
+ *
* Wishes & dreams:
* ----------------
* - Cleanup and integrate the roaming code
@@ -430,6 +436,9 @@
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h> /* Wireless extensions */
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif /* WIRELESS_EXT > 12 */
#endif
/* Pcmcia headers that we need */
@@ -498,7 +507,7 @@
/************************ CONSTANTS & MACROS ************************/
#ifdef DEBUG_VERSION_SHOW
-static const char *version = "wavelan_cs.c : v23 (SMP + wireless extensions) 20/12/00\n";
+static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/1/02\n";
#endif
/* Watchdog temporisation */
@@ -523,8 +532,8 @@ static const char *version = "wavelan_cs.c : v23 (SMP + wireless extensions) 20/
#define SIOCSIPROAM SIOCIWFIRSTPRIV + 2 /* Set roaming state */
#define SIOCGIPROAM SIOCIWFIRSTPRIV + 3 /* Get roaming state */
-#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 6 /* Set histogram ranges */
-#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 7 /* Get histogram values */
+#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 4 /* Set histogram ranges */
+#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 5 /* Get histogram values */
/*************************** WaveLAN Roaming **************************/
#ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */
@@ -589,6 +598,16 @@ typedef struct iw_freq iw_freq;
typedef struct net_local net_local;
typedef struct timer_list timer_list;
+#if WIRELESS_EXT <= 12
+/* Wireless extensions backward compatibility */
+/* Part of iw_handler prototype we need */
+struct iw_request_info
+{
+ __u16 cmd; /* Wireless Extension command */
+ __u16 flags; /* More to come ;-) */
+};
+#endif /* WIRELESS_EXT <= 12 */
+
/* Basic types */
typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
@@ -661,12 +680,6 @@ void wv_roam_cleanup(struct net_device *dev);
#endif /* WAVELAN_ROAMING */
/* ----------------------- MISC SUBROUTINES ------------------------ */
-static inline void
- wv_splhi(net_local *, /* Disable interrupts */
- unsigned long *); /* flags */
-static inline void
- wv_splx(net_local *, /* ReEnable interrupts */
- unsigned long *); /* flags */
static void
cs_error(client_handle_t, /* Report error to cardmgr */
int,
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 47cf83a5bf39..5ccf3c055315 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -1487,7 +1487,7 @@ static struct pci_driver yellowfin_driver = {
name: DRV_NAME,
id_table: yellowfin_pci_tbl,
probe: yellowfin_init_one,
- remove: yellowfin_remove_one,
+ remove: __devexit_p(yellowfin_remove_one),
};
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 6eb80f07f2ef..52649275cc9e 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -331,7 +331,7 @@ static struct pci_driver parport_serial_pci_driver = {
name: "parport_serial",
id_table: parport_serial_pci_tbl,
probe: parport_serial_pci_probe,
- remove: parport_serial_pci_remove,
+ remove: __devexit_p(parport_serial_pci_remove),
};
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 147cffd53d61..7160e06e38fe 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -3952,6 +3952,7 @@
9511 16PCI954 Function 1
15ed 2000 Macrolink MCCR Serial p4-7 of 8
15ed 2001 Macrolink MCCR Serial p4-15 of 16
+ 9521 Oxford Semi OX16PCI952 PCI/dual 16950 UART
1416 Multiwave Innovation pte Ltd
1417 Convergenet Technologies Inc
1418 Kyushu electronics systems Inc
diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c
index 7c6615a64160..d30df9b4203a 100644
--- a/drivers/pcmcia/pci_socket.c
+++ b/drivers/pcmcia/pci_socket.c
@@ -249,7 +249,7 @@ static struct pci_driver pci_cardbus_driver = {
name: "cardbus",
id_table: cardbus_table,
probe: cardbus_probe,
- remove: cardbus_remove,
+ remove: __devexit_p(cardbus_remove),
suspend: cardbus_suspend,
resume: cardbus_resume,
};
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index 50f1395efd95..27cda3b515f6 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1,6 +1,13 @@
/*
* eata.c - Low-level driver for EATA/DMA SCSI host adapters.
*
+ * 20 Feb 2002 Rev. 7.22 for linux 2.5.5
+ * + Remove any reference to virt_to_bus().
+ * + Fix pio hang while detecting multiple HBAs.
+ * + Fixed a board detection bug: in a system with
+ * multiple ISA/EISA boards, all but the first one
+ * were erroneously detected as PCI.
+ *
* 01 Jan 2002 Rev. 7.20 for linux 2.5.1
* + Use the dynamic DMA mapping API.
*
@@ -29,7 +36,7 @@
* boot time.
* + Improved boot messages: all tagged capable device are
* indicated as "tagged" or "soft-tagged" :
- * - "soft-tagged" means that the driver is trying to do its
+ * - "soft-tagged" means that the driver is trying to do its
* own tagging (i.e. the tc:y option is in effect);
* - "tagged" means that the device supports tagged commands,
* but the driver lets the HBA be responsible for tagging
@@ -40,7 +47,7 @@
* + When loaded as a module, accepts the new parameter boot_options
* which value is a string with the same format of the kernel boot
* command line options. A valid example is:
- * modprobe eata boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\"
+ * modprobe eata 'boot_options="0x7410,0x230,lc:y,tc:n,mq:4"'
*
* 9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17
* + 64bit cleanup for Linux/Alpha platform support
@@ -401,8 +408,6 @@
* the driver sets host->wish_block = TRUE for all ISA boards.
*/
-#error Please convert me to Documentation/DMA-mapping.txt
-
#include <linux/version.h>
#ifndef LinuxVersionCode
@@ -454,7 +459,7 @@ MODULE_AUTHOR("Dario Ballabio");
#define ISA 0
#define ESA 1
-#undef FORCE_CONFIG
+#undef FORCE_CONFIG
#undef DEBUG_LINKED_COMMANDS
#undef DEBUG_DETECT
@@ -645,11 +650,18 @@ struct mscp {
u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */
u_int32_t sp_dma_addr; /* Address where sp is DMA'ed when cp completes */
u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */
+
/* Additional fields begin here. */
Scsi_Cmnd *SCpnt;
- struct sg_list *sglist;
+
+ /* All the cp structure is zero filled by queuecommand except the
+ following CP_TAIL_SIZE bytes, initialized by detect */
+ dma_addr_t cp_dma_addr; /* dma handle for this cp structure */
+ struct sg_list *sglist; /* pointer to the allocated SG list */
};
+#define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
+
struct hostdata {
struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */
unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
@@ -657,7 +669,6 @@ struct hostdata {
unsigned int iocount; /* Total i/o done for this board */
int board_number; /* Number of this board */
char board_name[16]; /* Name of this board */
- char board_id[256]; /* data from INQUIRY on this board */
int in_reset; /* True if board is doing a reset */
int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
@@ -675,6 +686,7 @@ struct hostdata {
static struct Scsi_Host *sh[MAX_BOARDS + 1];
static const char *driver_name = "EATA";
static char sha[MAX_BOARDS];
+static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
/* Initialize num_boards so that ihdlr can work while detect is in progress */
static unsigned int num_boards = MAX_BOARDS;
@@ -710,8 +722,6 @@ static unsigned long io_port[] = {
#define H2DEV(x) cpu_to_be32(x)
#define DEV2H(x) be32_to_cpu(x)
-#define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
-
static void do_interrupt_handler(int, void *, struct pt_regs *);
static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
static int do_trace = FALSE;
@@ -813,7 +823,7 @@ static inline int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return TRUE;
- if ((addr = V2DEV(addr))) {
+ if ((addr = H2DEV(addr))) {
outb((char) (addr >> 24), iobase + REG_LOW);
outb((char) (addr >> 16), iobase + REG_LM);
outb((char) (addr >> 8), iobase + REG_MID);
@@ -919,7 +929,8 @@ static inline int port_detect \
else
protocol_rev = 'C';
- if (!setup_done && j > 0 && j <= MAX_PCI) {
+ if (protocol_rev != 'A' && info.forcaddr) {
+ printk("%s: warning, port address has been forced.\n", name);
bus_type = "PCI";
is_pci = TRUE;
subversion = ESA;
@@ -982,7 +993,7 @@ static inline int port_detect \
if (is_pci) {
pdev = get_pci_dev(port_base);
- if (!pdev)
+ if (!pdev)
printk("%s: warning, failed to get pci_dev structure.\n", name);
}
else
@@ -1012,18 +1023,29 @@ static inline int port_detect \
#if defined(FORCE_CONFIG)
{
- struct eata_config config;
+ struct eata_config *cf;
+ dma_addr_t cf_dma_addr;
+
+ cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr);
+
+ if (!cf) {
+ printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);
+ release_region(port_base, REGION_SIZE);
+ return FALSE;
+ }
/* Set board configuration */
- memset((char *)&config, 0, sizeof(struct eata_config));
- config.len = (ushort) cpu_to_be16((ushort)510);
- config.ocena = TRUE;
+ memset((char *)cf, 0, sizeof(struct eata_config));
+ cf->len = (ushort) cpu_to_be16((ushort)510);
+ cf->ocena = TRUE;
- if (do_dma(port_base, (unsigned long)&config, SET_CONFIG_DMA)) {
+ if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
printk("%s: busy timeout sending configuration, detaching.\n", name);
+ pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);
release_region(port_base, REGION_SIZE);
return FALSE;
}
+
}
#endif
@@ -1111,6 +1133,10 @@ static inline int port_detect \
else sprintf(dma_name, "DMA %u", dma_channel);
for (i = 0; i < sh[j]->can_queue; i++)
+ HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
+ &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
+ for (i = 0; i < sh[j]->can_queue; i++)
if (! ((&HD(j)->cp[i])->sglist = kmalloc(
sh[j]->sg_tablesize * sizeof(struct sg_list),
(sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
@@ -1119,7 +1145,7 @@ static inline int port_detect \
return FALSE;
}
- if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
+ if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
eata2x_release(sh[j]);
@@ -1279,6 +1305,9 @@ static void add_pci_ports(void) {
int eata2x_detect(Scsi_Host_Template *tpnt) {
unsigned int j = 0, k;
+ unsigned long spin_flags;
+
+ spin_lock_irqsave(&driver_lock, spin_flags);
tpnt->proc_name = "eata2x";
@@ -1304,6 +1333,7 @@ int eata2x_detect(Scsi_Host_Template *tpnt) {
}
num_boards = j;
+ spin_unlock_irqrestore(&driver_lock, spin_flags);
return j;
}
@@ -1324,10 +1354,10 @@ static inline void map_dma(unsigned int i, unsigned int j) {
if (!SCpnt->use_sg) {
- if (!SCpnt->request_bufflen)
- cpp->data_address = V2DEV(SCpnt->request_buffer);
+ /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
+ if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL;
- else if (SCpnt->request_buffer)
+ if (SCpnt->request_buffer)
cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
@@ -1344,7 +1374,8 @@ static inline void map_dma(unsigned int i, unsigned int j) {
}
cpp->sg = TRUE;
- cpp->data_address = V2DEV(cpp->sglist);
+ cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
+ SCpnt->use_sg * sizeof(struct sg_list), pci_dir));
cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
}
@@ -1360,13 +1391,14 @@ static void unmap_dma(unsigned int i, unsigned int j) {
pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
- if (SCpnt->use_sg)
+ if (SCpnt->use_sg)
pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
- else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
- pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
- DEV2H(cpp->data_len), pci_dir);
+ if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
+ if (DEV2H(cpp->data_address))
+ pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
+ DEV2H(cpp->data_len), pci_dir);
}
static void sync_dma(unsigned int i, unsigned int j) {
@@ -1381,14 +1413,15 @@ static void sync_dma(unsigned int i, unsigned int j) {
pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
- if (SCpnt->use_sg)
- pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer,
+ if (SCpnt->use_sg)
+ pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer,
SCpnt->use_sg, pci_dir);
- else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
- pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address),
- DEV2H(cpp->data_len), pci_dir);
+ if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
+ if (DEV2H(cpp->data_address))
+ pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address),
+ DEV2H(cpp->data_len), pci_dir);
}
static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
@@ -1409,8 +1442,7 @@ static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
struct mscp *cpp;
Scsi_Cmnd *SCpnt;
- cpp = &HD(j)->cp[i];
- SCpnt = cpp->SCpnt;
+ cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
if (SCpnt->sc_data_direction == SCSI_DATA_READ) {
cpp->din = TRUE;
@@ -1428,7 +1460,7 @@ static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
return;
}
- if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN)
+ if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN)
panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
@@ -1479,7 +1511,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
/* Set pointer to control packet structure */
cpp = &HD(j)->cp[i];
- memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *));
+ memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
/* Set pointer to status packet structure, Big Endian format */
cpp->sp_dma_addr = H2DEV(HD(j)->sp_dma_addr);
@@ -1536,7 +1568,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
}
/* Send control packet to the board */
- if (do_dma(sh[j]->io_port, (unsigned long) cpp, SEND_CP_DMA)) {
+ if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
unmap_dma(i, j);
SCpnt->host_scribble = NULL;
printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
@@ -1935,7 +1967,7 @@ static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j,
for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
- if (do_dma(sh[j]->io_port, (unsigned long) cpp, SEND_CP_DMA)) {
+ if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
" busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k);
@@ -1985,7 +2017,7 @@ static inline void ihdlr(int irq, unsigned int j) {
reg = inb(sh[j]->io_port + REG_STATUS);
/* Reject any sp with supspect data */
- if (spp->eoc == FALSE)
+ if (spp->eoc == FALSE && HD(j)->iocount > 1)
printk("%s: ihdlr, spp->eoc == FALSE, irq %d, reg 0x%x, count %d.\n",
BN(j), irq, reg, HD(j)->iocount);
if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue)
@@ -2191,10 +2223,14 @@ int eata2x_release(struct Scsi_Host *shpnt) {
for (i = 0; i < sh[j]->can_queue; i++)
if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
- if (HD(j)->sp_cpu_addr)
+ for (i = 0; i < sh[j]->can_queue; i++)
+ pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
+ sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
+ if (HD(j)->sp_cpu_addr)
pci_free_consistent(HD(j)->pdev, sizeof(struct mssp),
HD(j)->sp_cpu_addr, HD(j)->sp_dma_addr);
-
+
free_irq(sh[j]->irq, &sha[j]);
if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
diff --git a/drivers/scsi/eata.h b/drivers/scsi/eata.h
index 45d5cdaba88e..f1c5e5b84b91 100644
--- a/drivers/scsi/eata.h
+++ b/drivers/scsi/eata.h
@@ -13,7 +13,7 @@ int eata2x_abort(Scsi_Cmnd *);
int eata2x_reset(Scsi_Cmnd *);
int eata2x_biosparam(Disk *, kdev_t, int *);
-#define EATA_VERSION "7.20.00"
+#define EATA_VERSION "7.22.00"
#define EATA { \
name: "EATA/DMA 2.0x rev. " EATA_VERSION " ", \
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 525544d8a5a6..161cf9799a40 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -1007,7 +1007,7 @@ static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd)
cmd->SCp.this_residual = cmd->request_bufflen;
cmd->SCp.ptr = cmd->request_buffer;
}
- cmd->SCp.buffers_residual = cmd->use_sg;
+ cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.phase++;
if (cmd->SCp.this_residual & 0x01)
cmd->SCp.this_residual++;
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 27fe3de505b5..fdcbca13cf53 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -738,7 +738,7 @@ static int ppa_completion(Scsi_Cmnd * cmd)
if (cmd->SCp.buffers_residual--) {
cmd->SCp.buffer++;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
+ cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
}
}
/* Now check to see if the drive is ready to comunicate */
@@ -923,14 +923,14 @@ static int ppa_engine(ppa_struct * tmp, Scsi_Cmnd * cmd)
/* if many buffers are available, start filling the first */
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
+ cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
} else {
/* else fill the only available buffer */
cmd->SCp.buffer = NULL;
cmd->SCp.this_residual = cmd->request_bufflen;
cmd->SCp.ptr = cmd->request_buffer;
}
- cmd->SCp.buffers_residual = cmd->use_sg;
+ cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.phase++;
case 5: /* Phase 5 - Data transfer stage */
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 945939bcdfbb..0948ed466431 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1,6 +1,10 @@
/*
* u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
*
+ * 20 Feb 2002 Rev. 7.22 for linux 2.5.5
+ * + Remove any reference to virt_to_bus().
+ * + Fix pio hang while detecting multiple HBAs.
+ *
* 01 Jan 2002 Rev. 7.20 for linux 2.5.1
* + Use the dynamic DMA mapping API.
*
@@ -30,7 +34,7 @@
* + When loaded as a module, accepts the new parameter boot_options
* which value is a string with the same format of the kernel boot
* command line options. A valid example is:
- * modprobe u14-34f boot_options=\"0x230,0x340,lc:y,mq:4\"
+ * modprobe u14-34f 'boot_options="0x230,0x340,lc:y,mq:4"'
*
* 22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11
* + Removed pre-2.2 source code compatibility.
@@ -496,11 +500,19 @@ struct mscp {
unsigned char adapter_status; /* non-zero indicates HA error */
unsigned char target_status; /* non-zero indicates target error */
unsigned int sense_addr PACKED;
+
+ /* Additional fields begin here. */
Scsi_Cmnd *SCpnt;
unsigned int cpp_index; /* cp index */
- struct sg_list *sglist;
+
+ /* All the cp structure is zero filled by queuecommand except the
+ following CP_TAIL_SIZE bytes, initialized by detect */
+ dma_addr_t cp_dma_addr; /* dma handle for this cp structure */
+ struct sg_list *sglist; /* pointer to the allocated SG list */
};
+#define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
+
struct hostdata {
struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */
unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
@@ -508,7 +520,6 @@ struct hostdata {
unsigned int iocount; /* Total i/o done for this board */
int board_number; /* Number of this board */
char board_name[16]; /* Name of this board */
- char board_id[256]; /* data from INQUIRY on this board */
int in_reset; /* True if board is doing a reset */
int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
@@ -518,14 +529,13 @@ struct hostdata {
struct pci_dev *pdev; /* Always NULL */
unsigned char heads;
unsigned char sectors;
-
- /* slot != 0 for the U24F, slot == 0 for both the U14F and U34F */
- unsigned char slot;
+ char board_id[256]; /* data from INQUIRY on this board */
};
static struct Scsi_Host *sh[MAX_BOARDS + 1];
static const char *driver_name = "Ux4F";
static char sha[MAX_BOARDS];
+static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
/* Initialize num_boards so that ihdlr can work while detect is in progress */
static unsigned int num_boards = MAX_BOARDS;
@@ -550,8 +560,6 @@ static unsigned long io_port[] = {
#define H2DEV(x) cpu_to_le32(x)
#define DEV2H(x) le32_to_cpu(x)
-#define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
-
static void do_interrupt_handler(int, void *, struct pt_regs *);
static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
static int do_trace = FALSE;
@@ -644,13 +652,18 @@ static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {
static int board_inquiry(unsigned int j) {
struct mscp *cpp;
+ dma_addr_t id_dma_addr;
unsigned int time, limit = 0;
+ id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id,
+ sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL);
cpp = &HD(j)->cp[0];
- memset(cpp, 0, sizeof(struct mscp));
+ cpp->cp_dma_addr = pci_map_single(HD(j)->pdev, cpp, sizeof(struct mscp),
+ PCI_DMA_BIDIRECTIONAL);
+ memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
cpp->opcode = OP_HOST_ADAPTER;
cpp->xdir = DTD_IN;
- cpp->data_address = V2DEV(HD(j)->board_id);
+ cpp->data_address = H2DEV(id_dma_addr);
cpp->data_len = H2DEV(sizeof(HD(j)->board_id));
cpp->cdb_len = 6;
cpp->cdb[0] = HA_CMD_INQUIRY;
@@ -666,13 +679,15 @@ static int board_inquiry(unsigned int j) {
outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
/* Store pointer in OGM address bytes */
- outl(V2DEV(cpp), sh[j]->io_port + REG_OGM);
+ outl(H2DEV(cpp->cp_dma_addr), sh[j]->io_port + REG_OGM);
/* Issue OGM interrupt */
outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
+ spin_unlock_irq(&driver_lock);
time = jiffies;
while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L);
+ spin_lock_irq(&driver_lock);
if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) {
HD(j)->cp_stat[0] = FREE;
@@ -680,6 +695,10 @@ static int board_inquiry(unsigned int j) {
return TRUE;
}
+ pci_unmap_single(HD(j)->pdev, cpp->cp_dma_addr, sizeof(struct mscp),
+ PCI_DMA_BIDIRECTIONAL);
+ pci_unmap_single(HD(j)->pdev, id_dma_addr, sizeof(HD(j)->board_id),
+ PCI_DMA_BIDIRECTIONAL);
return FALSE;
}
@@ -817,6 +836,7 @@ static inline int port_detect \
HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors;
HD(j)->subversion = subversion;
+ HD(j)->pdev = NULL;
HD(j)->board_number = j;
if (have_old_firmware) sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
@@ -864,6 +884,10 @@ static inline int port_detect \
else sprintf(dma_name, "DMA %u", dma_channel);
for (i = 0; i < sh[j]->can_queue; i++)
+ HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
+ &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
+ for (i = 0; i < sh[j]->can_queue; i++)
if (! ((&HD(j)->cp[i])->sglist = kmalloc(
sh[j]->sg_tablesize * sizeof(struct sg_list),
(sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
@@ -950,6 +974,9 @@ static int option_setup(char *str) {
int u14_34f_detect(Scsi_Host_Template *tpnt) {
unsigned int j = 0, k;
+ unsigned long spin_flags;
+
+ spin_lock_irqsave(&driver_lock, spin_flags);
tpnt->proc_name = "u14-34f";
@@ -973,6 +1000,7 @@ int u14_34f_detect(Scsi_Host_Template *tpnt) {
}
num_boards = j;
+ spin_unlock_irqrestore(&driver_lock, spin_flags);
return j;
}
@@ -994,10 +1022,10 @@ static inline void map_dma(unsigned int i, unsigned int j) {
if (!SCpnt->use_sg) {
- if (!SCpnt->request_bufflen)
- cpp->data_address = V2DEV(SCpnt->request_buffer);
+ /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
+ if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL;
- else if (SCpnt->request_buffer)
+ if (SCpnt->request_buffer)
cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
@@ -1016,7 +1044,8 @@ static inline void map_dma(unsigned int i, unsigned int j) {
cpp->sg = TRUE;
cpp->use_sg = SCpnt->use_sg;
- cpp->data_address = V2DEV(cpp->sglist);
+ cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
+ SCpnt->use_sg * sizeof(struct sg_list), pci_dir));
cpp->data_len = H2DEV(data_len);
}
@@ -1032,13 +1061,14 @@ static void unmap_dma(unsigned int i, unsigned int j) {
pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
- if (SCpnt->use_sg)
+ if (SCpnt->use_sg)
pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
- else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
- pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
- DEV2H(cpp->data_len), pci_dir);
+ if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
+ if (DEV2H(cpp->data_address))
+ pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
+ DEV2H(cpp->data_len), pci_dir);
}
static void sync_dma(unsigned int i, unsigned int j) {
@@ -1053,14 +1083,15 @@ static void sync_dma(unsigned int i, unsigned int j) {
pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
- if (SCpnt->use_sg)
- pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer,
+ if (SCpnt->use_sg)
+ pci_dma_sync_sg(HD(j)->pdev, SCpnt->request_buffer,
SCpnt->use_sg, pci_dir);
- else if (DEV2H(cpp->data_address) && DEV2H(cpp->data_len))
- pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address),
- DEV2H(cpp->data_len), pci_dir);
+ if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
+ if (DEV2H(cpp->data_address))
+ pci_dma_sync_single(HD(j)->pdev, DEV2H(cpp->data_address),
+ DEV2H(cpp->data_len), pci_dir);
}
static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
@@ -1096,7 +1127,7 @@ static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
return;
}
- if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN)
+ if (SCpnt->sc_data_direction != SCSI_DATA_UNKNOWN)
panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
cpp->xdir = DTD_IN;
@@ -1149,7 +1180,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
/* Set pointer to control packet structure */
cpp = &HD(j)->cp[i];
- memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *));
+ memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
SCpnt->scsi_done = done;
cpp->cpp_index = i;
SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
@@ -1188,7 +1219,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
}
/* Store pointer in OGM address bytes */
- outl(V2DEV(cpp), sh[j]->io_port + REG_OGM);
+ outl(H2DEV(cpp->cp_dma_addr), sh[j]->io_port + REG_OGM);
/* Issue OGM interrupt */
outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
@@ -1598,7 +1629,7 @@ static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j,
continue;
}
- outl(V2DEV(cpp), sh[j]->io_port + REG_OGM);
+ outl(H2DEV(cpp->cp_dma_addr), sh[j]->io_port + REG_OGM);
outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
HD(j)->cp_stat[k] = IN_USE;
}
@@ -1636,11 +1667,11 @@ static inline void ihdlr(int irq, unsigned int j) {
/* Find the mailbox to be serviced on this board */
for (i = 0; i < sh[j]->can_queue; i++)
- if (V2DEV(&(HD(j)->cp[i])) == ret) break;
+ if (H2DEV(HD(j)->cp[i].cp_dma_addr) == ret) break;
if (i >= sh[j]->can_queue)
panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", BN(j),
- (void *)ret, (void *)V2DEV(HD(j)->cp));
+ (void *)ret, (void *)H2DEV(HD(j)->cp[0].cp_dma_addr));
cpp = &(HD(j)->cp[i]);
spp = cpp;
@@ -1840,6 +1871,10 @@ int u14_34f_release(struct Scsi_Host *shpnt) {
for (i = 0; i < sh[j]->can_queue; i++)
if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
+ for (i = 0; i < sh[j]->can_queue; i++)
+ pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
+ sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
free_irq(sh[j]->irq, &sha[j]);
if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
diff --git a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
index a044c2b45ddb..c5dfe2d80f55 100644
--- a/drivers/scsi/u14-34f.h
+++ b/drivers/scsi/u14-34f.h
@@ -13,7 +13,7 @@ int u14_34f_abort(Scsi_Cmnd *);
int u14_34f_reset(Scsi_Cmnd *);
int u14_34f_biosparam(Disk *, kdev_t, int *);
-#define U14_34F_VERSION "7.20.00"
+#define U14_34F_VERSION "7.22.00"
#define ULTRASTOR_14_34F { \
name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
diff --git a/drivers/usb/hcd/Config.help b/drivers/usb/hcd/Config.help
index c25152b48718..3412fb5d1874 100644
--- a/drivers/usb/hcd/Config.help
+++ b/drivers/usb/hcd/Config.help
@@ -21,7 +21,6 @@ CONFIG_USB_EHCI_HCD
The module will be called ehci-hcd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-OHCI (most USB hosts except VIA, Intel PIIX) support
CONFIG_USB_OHCI_HCD
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c
index bc89ba970163..91bdb6345587 100644
--- a/drivers/usb/hub.c
+++ b/drivers/usb/hub.c
@@ -644,6 +644,49 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
port + 1, hub->devpath, ret);
}
+/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
+ *
+ * Between connect detection and reset signaling there must be a delay
+ * of 100ms at least for debounce and power-settling. The corresponding
+ * timer shall restart whenever the downstream port detects a disconnect.
+ *
+ * Apparently there are some bluetooth and irda-dongles and a number
+ * of low-speed devices which require longer delays of about 200-400ms.
+ * Not covered by the spec - but easy to deal with.
+ *
+ * This implementation uses 400ms minimum debounce timeout and checks
+ * every 10ms for transient disconnects to restart the delay.
+ */
+
+#define HUB_DEBOUNCE_TIMEOUT 400
+#define HUB_DEBOUNCE_STEP 10
+
+/* return: -1 on error, 0 on success, 1 on disconnect. */
+static int usb_hub_port_debounce(struct usb_device *hub, int port)
+{
+ int ret;
+ unsigned delay_time;
+ u16 portchange, portstatus;
+
+ for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; /* empty */ ) {
+
+ /* wait debounce step increment */
+ wait_ms(HUB_DEBOUNCE_STEP);
+
+ ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
+ if (ret < 0)
+ return -1;
+
+ if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
+ usb_clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+ delay_time = 0;
+ }
+ else
+ delay_time += HUB_DEBOUNCE_STEP;
+ }
+ return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
+}
+
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
u16 portstatus, u16 portchange)
{
@@ -671,12 +714,16 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
return;
}
+ if (usb_hub_port_debounce(hub, port)) {
+ err("connect-debounce failed, port %d disabled", port+1);
+ usb_hub_port_disable(hub, port);
+ return;
+ }
+
/* Some low speed devices have problems with the quick delay, so */
/* be a bit pessimistic with those devices. RHbug #23670 */
- if (portstatus & USB_PORT_STAT_LOW_SPEED) {
- wait_ms(400);
+ if (portstatus & USB_PORT_STAT_LOW_SPEED)
delay = HUB_LONG_RESET_TIME;
- }
down(&usb_address0_sem);
diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c
index 0957c2b8246b..e74388fd64f0 100644
--- a/drivers/usb/ov511.c
+++ b/drivers/usb/ov511.c
@@ -58,7 +58,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.48a for Linux 2.4"
+#define DRIVER_VERSION "v1.49 for Linux 2.5"
#define EMAIL "mmcclell@bigfoot.com"
#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
@@ -309,7 +309,7 @@ static int ov51x_check_snapshot(struct usb_ov511 *);
static inline int sensor_get_picture(struct usb_ov511 *,
struct video_picture *);
static int sensor_get_exposure(struct usb_ov511 *, unsigned char *);
-static int ov511_control_ioctl(struct inode *, struct file *, unsigned int,
+static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
/**********************************************************************
@@ -332,6 +332,7 @@ static struct cam_list clist[] = {
{ 100, "Lifeview RoboCam" },
{ 102, "AverMedia InterCam Elite" },
{ 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */
+ { 192, "Webeye 2000B" },
{ -1, NULL }
};
@@ -373,6 +374,10 @@ static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
+/**********************************************************************
+ * Memory management
+ **********************************************************************/
+
/* Here we want the physical address of the memory.
* This is used when initializing the contents of the
* area and marking the pages as reserved.
@@ -451,7 +456,7 @@ static struct proc_dir_entry *ov511_proc_entry = NULL;
extern struct proc_dir_entry *video_proc_entry;
static struct file_operations ov511_control_fops = {
- ioctl: ov511_control_ioctl,
+ ioctl: ov51x_control_ioctl,
};
#define YES_NO(x) ((x) ? "yes" : "no")
@@ -463,29 +468,29 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
{
char *out = page;
int i, j, len;
- struct usb_ov511 *ov511 = data;
+ struct usb_ov511 *ov = data;
struct video_picture p;
unsigned char exp;
- if (!ov511 || !ov511->dev)
+ if (!ov || !ov->dev)
return -ENODEV;
- sensor_get_picture(ov511, &p);
- sensor_get_exposure(ov511, &exp);
+ sensor_get_picture(ov, &p);
+ sensor_get_exposure(ov, &exp);
/* IMPORTANT: This output MUST be kept under PAGE_SIZE
* or we need to get more sophisticated. */
out += sprintf(out, "driver_version : %s\n", DRIVER_VERSION);
- out += sprintf(out, "custom_id : %d\n", ov511->customid);
- out += sprintf(out, "model : %s\n", ov511->desc ?
- clist[ov511->desc].description : "unknown");
- out += sprintf(out, "streaming : %s\n", YES_NO(ov511->streaming));
- out += sprintf(out, "grabbing : %s\n", YES_NO(ov511->grabbing));
- out += sprintf(out, "compress : %s\n", YES_NO(ov511->compress));
- out += sprintf(out, "subcapture : %s\n", YES_NO(ov511->sub_flag));
+ out += sprintf(out, "custom_id : %d\n", ov->customid);
+ out += sprintf(out, "model : %s\n", ov->desc ?
+ clist[ov->desc].description : "unknown");
+ out += sprintf(out, "streaming : %s\n", YES_NO(ov->streaming));
+ out += sprintf(out, "grabbing : %s\n", YES_NO(ov->grabbing));
+ out += sprintf(out, "compress : %s\n", YES_NO(ov->compress));
+ out += sprintf(out, "subcapture : %s\n", YES_NO(ov->sub_flag));
out += sprintf(out, "sub_size : %d %d %d %d\n",
- ov511->subx, ov511->suby, ov511->subw, ov511->subh);
+ ov->subx, ov->suby, ov->subw, ov->subh);
out += sprintf(out, "data_format : %s\n",
force_rgb ? "RGB" : "BGR");
out += sprintf(out, "brightness : %d\n", p.brightness >> 8);
@@ -497,12 +502,12 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
for (i = 0; i < OV511_NUMFRAMES; i++) {
out += sprintf(out, "frame : %d\n", i);
out += sprintf(out, " depth : %d\n",
- ov511->frame[i].depth);
+ ov->frame[i].depth);
out += sprintf(out, " size : %d %d\n",
- ov511->frame[i].width, ov511->frame[i].height);
+ ov->frame[i].width, ov->frame[i].height);
out += sprintf(out, " format : ");
for (j = 0; plist[j].num >= 0; j++) {
- if (plist[j].num == ov511->frame[i].format) {
+ if (plist[j].num == ov->frame[i].format) {
out += sprintf(out, "%s\n", plist[j].name);
break;
}
@@ -510,29 +515,28 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
if (plist[j].num < 0)
out += sprintf(out, "unknown\n");
out += sprintf(out, " data_buffer : 0x%p\n",
- ov511->frame[i].data);
+ ov->frame[i].data);
}
- out += sprintf(out, "snap_enabled : %s\n",
- YES_NO(ov511->snap_enabled));
+ out += sprintf(out, "snap_enabled : %s\n", YES_NO(ov->snap_enabled));
out += sprintf(out, "bridge : %s\n",
- ov511->bridge == BRG_OV511 ? "OV511" :
- ov511->bridge == BRG_OV511PLUS ? "OV511+" :
- ov511->bridge == BRG_OV518 ? "OV518" :
- ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+ ov->bridge == BRG_OV511 ? "OV511" :
+ ov->bridge == BRG_OV511PLUS ? "OV511+" :
+ ov->bridge == BRG_OV518 ? "OV518" :
+ ov->bridge == BRG_OV518PLUS ? "OV518+" :
"unknown");
out += sprintf(out, "sensor : %s\n",
- ov511->sensor == SEN_OV6620 ? "OV6620" :
- ov511->sensor == SEN_OV6630 ? "OV6630" :
- ov511->sensor == SEN_OV7610 ? "OV7610" :
- ov511->sensor == SEN_OV7620 ? "OV7620" :
- ov511->sensor == SEN_OV7620AE ? "OV7620AE" :
- ov511->sensor == SEN_OV8600 ? "OV8600" :
- ov511->sensor == SEN_KS0127 ? "KS0127" :
- ov511->sensor == SEN_KS0127B ? "KS0127B" :
- ov511->sensor == SEN_SAA7111A ? "SAA7111A" :
+ ov->sensor == SEN_OV6620 ? "OV6620" :
+ ov->sensor == SEN_OV6630 ? "OV6630" :
+ ov->sensor == SEN_OV7610 ? "OV7610" :
+ ov->sensor == SEN_OV7620 ? "OV7620" :
+ ov->sensor == SEN_OV7620AE ? "OV7620AE" :
+ ov->sensor == SEN_OV8600 ? "OV8600" :
+ ov->sensor == SEN_KS0127 ? "KS0127" :
+ ov->sensor == SEN_KS0127B ? "KS0127B" :
+ ov->sensor == SEN_SAA7111A ? "SAA7111A" :
"unknown");
- out += sprintf(out, "packet_size : %d\n", ov511->packet_size);
- out += sprintf(out, "framebuffer : 0x%p\n", ov511->fbuf);
+ out += sprintf(out, "packet_size : %d\n", ov->packet_size);
+ out += sprintf(out, "framebuffer : 0x%p\n", ov->fbuf);
len = out - page;
len -= off;
@@ -565,16 +569,16 @@ ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
{
char *out = page;
int len, status;
- struct usb_ov511 *ov511 = data;
+ struct usb_ov511 *ov = data;
- if (!ov511 || !ov511->dev)
+ if (!ov || !ov->dev)
return -ENODEV;
- status = ov51x_check_snapshot(ov511);
+ status = ov51x_check_snapshot(ov);
out += sprintf(out, "%d", status);
if (status)
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
len = out - page;
len -= off;
@@ -716,18 +720,22 @@ proc_ov511_destroy(void)
*
**********************************************************************/
+/* Write an OV51x register */
static int
-ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
+reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
{
int rc;
PDEBUG(5, "0x%02X:0x%02X", reg, value);
- rc = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
+ down(&ov->cbuf_lock);
+ ov->cbuf[0] = value;
+ rc = usb_control_msg(ov->dev,
+ usb_sndctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, &value, 1, HZ);
+ 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
+ up(&ov->cbuf_lock);
if (rc < 0)
err("reg write: error %d", rc);
@@ -735,45 +743,48 @@ ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
return rc;
}
+/* Read from an OV51x register */
/* returns: negative is error, pos or zero is data */
static int
-ov511_reg_read(struct usb_device *dev, unsigned char reg)
+reg_r(struct usb_ov511 *ov, unsigned char reg)
{
int rc;
- unsigned char buffer[1];
- rc = usb_control_msg(dev,
- usb_rcvctrlpipe(dev, 0),
+ down(&ov->cbuf_lock);
+ rc = usb_control_msg(ov->dev,
+ usb_rcvctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, buffer, 1, HZ);
+ 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
- PDEBUG(5, "0x%02X:0x%02X", reg, buffer[0]);
+ PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
- if (rc < 0) {
+ if (rc < 0)
err("reg read: error %d", rc);
- return rc;
- } else {
- return buffer[0];
- }
+ else
+ rc = ov->cbuf[0];
+
+ up(&ov->cbuf_lock);
+
+ return rc;
}
/*
- * Writes bits at positions specified by mask to a reg. Bits that are in
+ * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
* the same position as 1's in "mask" are cleared and set to "value". Bits
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
static int
-ov511_reg_write_mask(struct usb_device *dev,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+reg_w_mask(struct usb_ov511 *ov,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int ret;
unsigned char oldval, newval;
- ret = ov511_reg_read(dev, reg);
+ ret = reg_r(ov, reg);
if (ret < 0)
return ret;
@@ -782,31 +793,30 @@ ov511_reg_write_mask(struct usb_device *dev,
value &= mask; /* Enforce mask on value */
newval = oldval | value; /* Set the desired bits */
- return (ov511_reg_write(dev, reg, newval));
+ return (reg_w(ov, reg, newval));
}
-/* Writes multiple (n) values to a single register. Only valid with certain
- * registers (0x30 and 0xc4 - 0xce). Used for writing 16 and 24-bit values. */
+/*
+ * Writes multiple (n) byte value to a single register. Only valid with certain
+ * registers (0x30 and 0xc4 - 0xce).
+ */
static int
-ov518_reg_write_multi(struct usb_device *dev,
- unsigned char reg,
- unsigned char *values,
- int n)
+ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
{
int rc;
- PDEBUG(5, "0x%02X:[multiple], n=%d", reg, n); // FIXME
+ PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
- if (values == NULL) {
- err("reg write multiple: NULL buffer");
- return -EINVAL;
- }
+ down(&ov->cbuf_lock);
+
+ *((u32 *)ov->cbuf) = __cpu_to_le32(val);
- rc = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
+ rc = usb_control_msg(ov->dev,
+ usb_sndctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, values, n, HZ);
+ 0, (__u16)reg, ov->cbuf, n, HZ);
+ up(&ov->cbuf_lock);
if (rc < 0)
err("reg write multiple: error %d", rc);
@@ -815,12 +825,12 @@ ov518_reg_write_multi(struct usb_device *dev,
}
static int
-ov511_upload_quan_tables(struct usb_device *dev)
+ov511_upload_quan_tables(struct usb_ov511 *ov)
{
unsigned char *pYTable = yQuanTable511;
unsigned char *pUVTable = uvQuanTable511;
unsigned char val0, val1;
- int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+ int i, rc, reg = R511_COMP_LUT_BEGIN;
PDEBUG(4, "Uploading quantization tables");
@@ -833,7 +843,7 @@ ov511_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg, val0);
+ rc = reg_w(ov, reg, val0);
if (rc < 0)
return rc;
}
@@ -845,8 +855,7 @@ ov511_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg + OV511_QUANTABLESIZE / 2,
- val0);
+ rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
if (rc < 0)
return rc;
}
@@ -859,12 +868,12 @@ ov511_upload_quan_tables(struct usb_device *dev)
/* OV518 quantization tables are 8x4 (instead of 8x8) */
static int
-ov518_upload_quan_tables(struct usb_device *dev)
+ov518_upload_quan_tables(struct usb_ov511 *ov)
{
unsigned char *pYTable = yQuanTable518;
unsigned char *pUVTable = uvQuanTable518;
unsigned char val0, val1;
- int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+ int i, rc, reg = R511_COMP_LUT_BEGIN;
PDEBUG(4, "Uploading quantization tables");
@@ -877,7 +886,7 @@ ov518_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg, val0);
+ rc = reg_w(ov, reg, val0);
if (rc < 0)
return rc;
}
@@ -889,8 +898,7 @@ ov518_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg + OV518_QUANTABLESIZE / 2,
- val0);
+ rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
if (rc < 0)
return rc;
}
@@ -901,13 +909,39 @@ ov518_upload_quan_tables(struct usb_device *dev)
return 0;
}
+static int
+ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
+{
+ int rc;
+
+ /* Setting bit 0 not allowed on 518/518Plus */
+ if (ov->bclass == BCL_OV518)
+ reset_type &= 0xfe;
+
+ PDEBUG(4, "Reset: type=0x%X", reset_type);
+
+ rc = reg_w(ov, R51x_SYS_RESET, reset_type);
+ rc = reg_w(ov, R51x_SYS_RESET, 0);
+
+ if (rc < 0)
+ err("reset: command failed");
+
+ return rc;
+}
+
+/**********************************************************************
+ *
+ * I2C (sensor) I/O
+ *
+ **********************************************************************/
+
/* NOTE: Do not call this function directly!
* The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_write(). Note that this function
+ * This is normally only called from i2c_w(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
static int
-ov518_i2c_write_internal(struct usb_device *dev,
+ov518_i2c_write_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value)
{
@@ -916,15 +950,15 @@ ov518_i2c_write_internal(struct usb_device *dev,
PDEBUG(5, "0x%02X:0x%02X", reg, value);
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
if (rc < 0) goto error;
/* Write "value" to I2C data port of OV511 */
- rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+ rc = reg_w(ov, R51x_I2C_DATA, value);
if (rc < 0) goto error;
/* Initiate 3-byte write cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x01);
+ rc = reg_w(ov, R518_I2C_CTL, 0x01);
if (rc < 0) goto error;
return 0;
@@ -936,7 +970,7 @@ error:
/* NOTE: Do not call this function directly! */
static int
-ov511_i2c_write_internal(struct usb_device *dev,
+ov511_i2c_write_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value)
{
@@ -947,19 +981,18 @@ ov511_i2c_write_internal(struct usb_device *dev,
/* Three byte write cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE,
- reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
if (rc < 0) goto error;
/* Write "value" to I2C data port of OV511 */
- rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+ rc = reg_w(ov, R51x_I2C_DATA, value);
if (rc < 0) goto error;
/* Initiate 3-byte write cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
+ rc = reg_w(ov, R511_I2C_CTL, 0x01);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -967,7 +1000,7 @@ ov511_i2c_write_internal(struct usb_device *dev,
break;
#if 0
/* I2C abort */
- ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ reg_w(ov, R511_I2C_CTL, 0x10);
#endif
if (--retries < 0) {
err("i2c write retries exhausted");
@@ -985,27 +1018,27 @@ error:
/* NOTE: Do not call this function directly!
* The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_read(). Note that this function
+ * This is normally only called from i2c_r(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
static int
-ov518_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
{
int rc, value;
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
if (rc < 0) goto error;
/* Initiate 2-byte write cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x03);
+ rc = reg_w(ov, R518_I2C_CTL, 0x03);
if (rc < 0) goto error;
/* Initiate 2-byte read cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x05);
+ rc = reg_w(ov, R518_I2C_CTL, 0x05);
if (rc < 0) goto error;
- value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ value = reg_r(ov, R51x_I2C_DATA);
PDEBUG(5, "0x%02X:0x%02X", reg, value);
@@ -1019,22 +1052,21 @@ error:
/* NOTE: Do not call this function directly!
* returns: negative is error, pos or zero is data */
static int
-ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
{
int rc, value, retries;
/* Two byte write cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE,
- reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
if (rc < 0) goto error;
/* Initiate 2-byte write cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
+ rc = reg_w(ov, R511_I2C_CTL, 0x03);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -1042,7 +1074,7 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
break;
/* I2C abort */
- ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ reg_w(ov, R511_I2C_CTL, 0x10);
if (--retries < 0) {
err("i2c write retries exhausted");
@@ -1054,10 +1086,10 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
/* Two byte read cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Initiate 2-byte read cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ rc = reg_w(ov, R511_I2C_CTL, 0x05);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -1065,7 +1097,7 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
break;
/* I2C abort */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ rc = reg_w(ov, R511_I2C_CTL, 0x10);
if (rc < 0) goto error;
if (--retries < 0) {
@@ -1075,12 +1107,12 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
}
}
- value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ value = reg_r(ov, R51x_I2C_DATA);
PDEBUG(5, "0x%02X:0x%02X", reg, value);
- /* This is needed to make ov51x_i2c_write() work */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ /* This is needed to make i2c_w() work */
+ rc = reg_w(ov, R511_I2C_CTL, 0x05);
if (rc < 0)
goto error;
@@ -1093,48 +1125,42 @@ error:
/* returns: negative is error, pos or zero is data */
static int
-ov51x_i2c_read(struct usb_ov511 *ov511, unsigned char reg)
+i2c_r(struct usb_ov511 *ov, unsigned char reg)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
static int
-ov51x_i2c_write(struct usb_ov511 *ov511,
- unsigned char reg,
- unsigned char value)
+i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_write_internal(dev, reg, value);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_write_internal(ov, reg, value);
else
- rc = ov511_i2c_write_internal(dev, reg, value);
+ rc = ov511_i2c_write_internal(ov, reg, value);
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
/* Do not call this function directly! */
static int
-ov51x_i2c_write_mask_internal(struct usb_device *dev,
+ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value,
unsigned char mask)
@@ -1145,11 +1171,10 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
if (mask == 0xff) {
newval = value;
} else {
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
if (rc < 0)
return rc;
@@ -1159,11 +1184,10 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
newval = oldval | value; /* Set the desired bits */
}
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- return (ov518_i2c_write_internal(dev, reg, newval));
+ if (ov->bclass == BCL_OV518)
+ return (ov518_i2c_write_internal(ov, reg, newval));
else
- return (ov511_i2c_write_internal(dev, reg, newval));
+ return (ov511_i2c_write_internal(ov, reg, newval));
}
/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1172,126 +1196,138 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
* of their respective state in "value".
*/
static int
-ov51x_i2c_write_mask(struct usb_ov511 *ov511,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+i2c_w_mask(struct usb_ov511 *ov,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
- rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
- up(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
+ rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
+ up(&ov->i2c_lock);
return rc;
}
/* Write to a specific I2C slave ID and register, using the specified mask */
static int
-ov51x_i2c_write_slave(struct usb_ov511 *ov511,
- unsigned char slave,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+i2c_w_slave(struct usb_ov511 *ov,
+ unsigned char slave,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int rc = 0;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
/* Set new slave IDs */
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
- rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
+ rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
/* Don't bail out yet if error; IDs must be restored */
/* Restore primary IDs */
- slave = ov511->primary_i2c_slave;
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ slave = ov->primary_i2c_slave;
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
out:
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
/* Read from a specific I2C slave ID and register */
static int
-ov51x_i2c_read_slave(struct usb_ov511 *ov511,
- unsigned char slave,
- unsigned char reg)
+i2c_r_slave(struct usb_ov511 *ov,
+ unsigned char slave,
+ unsigned char reg)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
/* Set new slave IDs */
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
/* Don't bail out yet if error; IDs must be restored */
/* Restore primary IDs */
- slave = ov511->primary_i2c_slave;
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ slave = ov->primary_i2c_slave;
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
out:
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
+/* Sets I2C read and write slave IDs. Returns <0 for error */
+static int
+ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
+{
+ down(&ov->i2c_lock);
+
+ if (reg_w(ov, R51x_I2C_W_SID, sid) < 0)
+ return -EIO;
+
+ if (reg_w(ov, R51x_I2C_R_SID, sid + 1) < 0)
+ return -EIO;
+
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
+ return -EIO;
+
+ up(&ov->i2c_lock);
+
+ return 0;
+}
+
static int
-ov511_write_regvals(struct usb_ov511 *ov511,
- struct ov511_regvals * pRegvals)
+write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
{
int rc;
- struct usb_device *dev = ov511->dev;
while (pRegvals->bus != OV511_DONE_BUS) {
if (pRegvals->bus == OV511_REG_BUS) {
- if ((rc = ov511_reg_write(dev, pRegvals->reg,
- pRegvals->val)) < 0)
+ if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
goto error;
} else if (pRegvals->bus == OV511_I2C_BUS) {
- if ((rc = ov51x_i2c_write(ov511, pRegvals->reg,
- pRegvals->val)) < 0)
+ if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
goto error;
} else {
err("Bad regval array");
@@ -1309,57 +1345,60 @@ error:
#ifdef OV511_DEBUG
static void
-ov511_dump_i2c_range(struct usb_ov511 *ov511, int reg1, int regn)
+dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
{
int i;
int rc;
+
for (i = reg1; i <= regn; i++) {
- rc = ov51x_i2c_read(ov511, i);
+ rc = i2c_r(ov, i);
info("OV7610[0x%X] = 0x%X", i, rc);
}
}
static void
-ov51x_dump_i2c_regs(struct usb_ov511 *ov511)
+dump_i2c_regs(struct usb_ov511 *ov)
{
info("I2C REGS");
- ov511_dump_i2c_range(ov511, 0x00, 0x7C);
+ dump_i2c_range(ov, 0x00, 0x7C);
}
static void
-ov511_dump_reg_range(struct usb_device *dev, int reg1, int regn)
+dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
{
int i;
int rc;
+
for (i = reg1; i <= regn; i++) {
- rc = ov511_reg_read(dev, i);
- info("OV511[0x%X] = 0x%X", i, rc);
+ rc = reg_r(ov, i);
+ info("OV511[0x%X] = 0x%X", i, rc);
}
}
+/* FIXME: Should there be an OV518 version of this? */
static void
-ov511_dump_regs(struct usb_device *dev)
+ov511_dump_regs(struct usb_ov511 *ov)
{
info("CAMERA INTERFACE REGS");
- ov511_dump_reg_range(dev, 0x10, 0x1f);
+ dump_reg_range(ov, 0x10, 0x1f);
info("DRAM INTERFACE REGS");
- ov511_dump_reg_range(dev, 0x20, 0x23);
+ dump_reg_range(ov, 0x20, 0x23);
info("ISO FIFO REGS");
- ov511_dump_reg_range(dev, 0x30, 0x31);
+ dump_reg_range(ov, 0x30, 0x31);
info("PIO REGS");
- ov511_dump_reg_range(dev, 0x38, 0x39);
- ov511_dump_reg_range(dev, 0x3e, 0x3e);
+ dump_reg_range(ov, 0x38, 0x39);
+ dump_reg_range(ov, 0x3e, 0x3e);
info("I2C REGS");
- ov511_dump_reg_range(dev, 0x40, 0x49);
+ dump_reg_range(ov, 0x40, 0x49);
info("SYSTEM CONTROL REGS");
- ov511_dump_reg_range(dev, 0x50, 0x55);
- ov511_dump_reg_range(dev, 0x5e, 0x5f);
+ dump_reg_range(ov, 0x50, 0x55);
+ dump_reg_range(ov, 0x5e, 0x5f);
info("OmniCE REGS");
- ov511_dump_reg_range(dev, 0x70, 0x79);
+ dump_reg_range(ov, 0x70, 0x79);
/* NOTE: Quantization tables are not readable. You will get the value
* in reg. 0x79 for every table register */
- ov511_dump_reg_range(dev, 0x80, 0x9f);
- ov511_dump_reg_range(dev, 0xa0, 0xbf);
+ dump_reg_range(ov, 0x80, 0x9f);
+ dump_reg_range(ov, 0xa0, 0xbf);
}
#endif
@@ -1372,7 +1411,7 @@ ov511_dump_regs(struct usb_device *dev)
/* For as-yet unimplemented I2C interface */
static void
-call_i2c_clients(struct usb_ov511 *ov511, unsigned int cmd,
+call_i2c_clients(struct usb_ov511 *ov, unsigned int cmd,
void *arg)
{
/* Do nothing */
@@ -1380,59 +1419,33 @@ call_i2c_clients(struct usb_ov511 *ov511, unsigned int cmd,
/*****************************************************************************/
-static int
-ov511_reset(struct usb_ov511 *ov511, unsigned char reset_type)
-{
- int rc;
-
- /* Setting bit 0 not allowed on 518/518Plus */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- reset_type &= 0xfe;
-
- PDEBUG(4, "Reset: type=0x%X", reset_type);
-
- rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, reset_type);
- rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0);
-
- if (rc < 0)
- err("reset: command failed");
-
- return rc;
-}
-
/* Temporarily stops OV511 from functioning. Must do this before changing
* registers while the camera is streaming */
static inline int
-ov511_stop(struct usb_ov511 *ov511)
+ov51x_stop(struct usb_ov511 *ov)
{
PDEBUG(4, "stopping");
- ov511->stopped = 1;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x3a));
+ ov->stopped = 1;
+ if (ov->bclass == BCL_OV518)
+ return (reg_w(ov, R51x_SYS_RESET, 0x3a));
else
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x3d));
+ return (reg_w(ov, R51x_SYS_RESET, 0x3d));
}
/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
* actually stopped (for performance). */
static inline int
-ov511_restart(struct usb_ov511 *ov511)
+ov51x_restart(struct usb_ov511 *ov)
{
- if (ov511->stopped) {
+ if (ov->stopped) {
PDEBUG(4, "restarting");
- ov511->stopped = 0;
+ ov->stopped = 0;
/* Reinitialize the stream */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_reg_write(ov511->dev, 0x2f, 0x80);
+ if (ov->bclass == BCL_OV518)
+ reg_w(ov, 0x2f, 0x80);
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x00));
+ return (reg_w(ov, R51x_SYS_RESET, 0x00));
}
return 0;
@@ -1440,14 +1453,13 @@ ov511_restart(struct usb_ov511 *ov511)
/* Resets the hardware snapshot button */
static void
-ov51x_clear_snapshot(struct usb_ov511 *ov511)
+ov51x_clear_snapshot(struct usb_ov511 *ov)
{
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ if (ov->bclass == BCL_OV511) {
+ reg_w(ov, R51x_SYS_SNAP, 0x01);
+ reg_w(ov, R51x_SYS_SNAP, 0x03);
+ reg_w(ov, R51x_SYS_SNAP, 0x01);
+ } else if (ov->bclass == BCL_OV518) {
warn("snapshot reset not supported yet on OV518(+)");
} else {
err("clear snap: invalid bridge type");
@@ -1458,19 +1470,18 @@ ov51x_clear_snapshot(struct usb_ov511 *ov511)
/* Checks the status of the snapshot button. Returns 1 if it was pressed since
* it was last cleared, and zero in all other cases (including errors) */
static int
-ov51x_check_snapshot(struct usb_ov511 *ov511)
+ov51x_check_snapshot(struct usb_ov511 *ov)
{
int ret, status = 0;
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
- ret = ov511_reg_read(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT);
+ if (ov->bclass == BCL_OV511) {
+ ret = reg_r(ov, R51x_SYS_SNAP);
if (ret < 0) {
err("Error checking snspshot status (%d)", ret);
} else if (ret & 0x08) {
status = 1;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
warn("snapshot check not supported yet on OV518(+)");
} else {
err("check snap: invalid bridge type");
@@ -1479,53 +1490,33 @@ ov51x_check_snapshot(struct usb_ov511 *ov511)
return status;
}
-/* Sets I2C read and write slave IDs. Returns <0 for error */
-static int
-ov51x_set_slave_ids(struct usb_ov511 *ov511,
- unsigned char write_id,
- unsigned char read_id)
-{
- struct usb_device *dev = ov511->dev;
-
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, write_id) < 0)
- return -EIO;
-
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, read_id) < 0)
- return -EIO;
-
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
- return -EIO;
-
- return 0;
-}
-
/* This does an initial reset of an OmniVision sensor and ensures that I2C
* is synchronized. Returns <0 for failure.
*/
static int
-ov51x_init_ov_sensor(struct usb_ov511 *ov511)
+init_ov_sensor(struct usb_ov511 *ov)
{
int i, success;
/* Reset the sensor */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
/* Wait for it to initialize */
schedule_timeout (1 + 150 * HZ / 1000);
for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
- if ((ov51x_i2c_read(ov511, OV7610_REG_ID_HIGH) == 0x7F) &&
- (ov51x_i2c_read(ov511, OV7610_REG_ID_LOW) == 0xA2)) {
+ if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
success = 1;
continue;
}
/* Reset the sensor */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
/* Wait for it to initialize */
schedule_timeout(1 + 150 * HZ / 1000);
/* Dummy read to sync I2C */
- if (ov51x_i2c_read(ov511, 0x00) < 0) return -EIO;
+ if (i2c_r(ov, 0x00) < 0) return -EIO;
}
if (!success)
@@ -1537,16 +1528,16 @@ ov51x_init_ov_sensor(struct usb_ov511 *ov511)
}
static int
-ov511_set_packet_size(struct usb_ov511 *ov511, int size)
+ov51x_set_packet_size(struct usb_ov511 *ov, int size)
{
int alt, mult;
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
mult = size >> 5;
- if (ov511->bridge == BRG_OV511) {
+ if (ov->bridge == BRG_OV511) {
if (size == 0) alt = OV511_ALT_SIZE_0;
else if (size == 257) alt = OV511_ALT_SIZE_257;
else if (size == 513) alt = OV511_ALT_SIZE_513;
@@ -1556,7 +1547,7 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
err("Set packet size: invalid size (%d)", size);
return -EINVAL;
}
- } else if (ov511->bridge == BRG_OV511PLUS) {
+ } else if (ov->bridge == BRG_OV511PLUS) {
if (size == 0) alt = OV511PLUS_ALT_SIZE_0;
else if (size == 33) alt = OV511PLUS_ALT_SIZE_33;
else if (size == 129) alt = OV511PLUS_ALT_SIZE_129;
@@ -1569,8 +1560,7 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
err("Set packet size: invalid size (%d)", size);
return -EINVAL;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (size == 0) alt = OV518_ALT_SIZE_0;
else if (size == 128) alt = OV518_ALT_SIZE_128;
else if (size == 256) alt = OV518_ALT_SIZE_256;
@@ -1591,32 +1581,30 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
PDEBUG(3, "set packet size: %d, mult=%d, alt=%d", size, mult, alt);
// FIXME: Don't know how to do this on OV518 yet
- if (ov511->bridge != BRG_OV518 &&
- ov511->bridge != BRG_OV518PLUS) {
- if (ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
+ if (ov->bclass == BCL_OV511) {
+ if (reg_w(ov, R51x_FIFO_PSIZE,
mult) < 0) {
return -EIO;
}
}
- if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
+ if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
err("Set packet size: set interface error");
return -EBUSY;
}
/* Initialize the stream */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- if (ov511_reg_write(ov511->dev, 0x2f, 0x80) < 0)
+ if (ov->bclass == BCL_OV518)
+ if (reg_w(ov, 0x2f, 0x80) < 0)
return -EIO;
// FIXME - Should we only reset the FIFO?
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
return -EIO;
- ov511->packet_size = size;
+ ov->packet_size = size;
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return 0;
@@ -1624,51 +1612,49 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
/* Upload compression params and quantization tables. Returns 0 for success. */
static int
-ov511_init_compression(struct usb_ov511 *ov511)
+ov511_init_compression(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int rc = 0;
- if (!ov511->compress_inited) {
+ if (!ov->compress_inited) {
- ov511_reg_write(dev, 0x70, phy);
- ov511_reg_write(dev, 0x71, phuv);
- ov511_reg_write(dev, 0x72, pvy);
- ov511_reg_write(dev, 0x73, pvuv);
- ov511_reg_write(dev, 0x74, qhy);
- ov511_reg_write(dev, 0x75, qhuv);
- ov511_reg_write(dev, 0x76, qvy);
- ov511_reg_write(dev, 0x77, qvuv);
+ reg_w(ov, 0x70, phy);
+ reg_w(ov, 0x71, phuv);
+ reg_w(ov, 0x72, pvy);
+ reg_w(ov, 0x73, pvuv);
+ reg_w(ov, 0x74, qhy);
+ reg_w(ov, 0x75, qhuv);
+ reg_w(ov, 0x76, qvy);
+ reg_w(ov, 0x77, qvuv);
- if (ov511_upload_quan_tables(dev) < 0) {
+ if (ov511_upload_quan_tables(ov) < 0) {
err("Error uploading quantization tables");
rc = -EIO;
goto out;
}
}
- ov511->compress_inited = 1;
+ ov->compress_inited = 1;
out:
return rc;
}
/* Upload compression params and quantization tables. Returns 0 for success. */
static int
-ov518_init_compression(struct usb_ov511 *ov511)
+ov518_init_compression(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int rc = 0;
- if (!ov511->compress_inited) {
+ if (!ov->compress_inited) {
- if (ov518_upload_quan_tables(dev) < 0) {
+ if (ov518_upload_quan_tables(ov) < 0) {
err("Error uploading quantization tables");
rc = -EIO;
goto out;
}
}
- ov511->compress_inited = 1;
+ ov->compress_inited = 1;
out:
return rc;
}
@@ -1677,22 +1663,22 @@ out:
/* Sets sensor's contrast setting to "val" */
static int
-sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
{
- rc = ov51x_i2c_write(ov511, OV7610_REG_CNT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
if (rc < 0)
goto out;
break;
@@ -1705,14 +1691,14 @@ sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
};
/* Use Y gamma control instead. Bit 0 enables it. */
- rc = ov51x_i2c_write(ov511, 0x64, ctab[val>>12]);
+ rc = i2c_w(ov, 0x64, ctab[val>>12]);
if (rc < 0)
goto out;
break;
}
case SEN_SAA7111A:
{
- rc = ov51x_i2c_write(ov511, 0x0b, val >> 9);
+ rc = i2c_w(ov, 0x0b, val >> 9);
if (rc < 0)
goto out;
break;
@@ -1726,9 +1712,9 @@ sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->contrast = val;
+ ov->contrast = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1736,15 +1722,15 @@ out:
/* Gets sensor's contrast setting */
static int
-sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_CNT);
+ rc = i2c_r(ov, OV7610_REG_CNT);
if (rc < 0)
return rc;
else
@@ -1752,14 +1738,14 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
break;
case SEN_OV7620:
/* Use Y gamma reg instead. Bit 0 is the enable bit. */
- rc = ov51x_i2c_read(ov511, 0x64);
+ rc = i2c_r(ov, 0x64);
if (rc < 0)
return rc;
else
*val = (rc & 0xfe) << 8;
break;
case SEN_SAA7111A:
- *val = ov511->contrast;
+ *val = ov->contrast;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1767,7 +1753,7 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->contrast = *val;
+ ov->contrast = *val;
return 0;
}
@@ -1776,35 +1762,35 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's brightness setting to "val" */
static int
-sensor_set_brightness(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(4, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
/* 7620 doesn't like manual changes when in auto mode */
- if (!ov511->auto_brt) {
- rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+ if (!ov->auto_brt) {
+ rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
if (rc < 0)
goto out;
}
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0a, val >> 8);
+ rc = i2c_w(ov, 0x0a, val >> 8);
if (rc < 0)
goto out;
break;
@@ -1815,9 +1801,9 @@ sensor_set_brightness(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->brightness = val;
+ ov->brightness = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1825,24 +1811,24 @@ out:
/* Gets sensor's brightness setting */
static int
-sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV7620:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_BRT);
+ rc = i2c_r(ov, OV7610_REG_BRT);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->brightness;
+ *val = ov->brightness;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1850,7 +1836,7 @@ sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->brightness = *val;
+ ov->brightness = *val;
return 0;
}
@@ -1859,36 +1845,36 @@ sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's saturation (color intensity) setting to "val" */
static int
-sensor_set_saturation(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
-// rc = ov511_i2c_write(ov511->dev, 0x62, (val >> 9) & 0x7e);
+// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
// if (rc < 0)
// goto out;
- rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0c, val >> 9);
+ rc = i2c_w(ov, 0x0c, val >> 9);
if (rc < 0)
goto out;
break;
@@ -1899,9 +1885,9 @@ sensor_set_saturation(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->colour = val;
+ ov->colour = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1909,16 +1895,16 @@ out:
/* Gets sensor's saturation (color intensity) setting */
static int
-sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+ rc = i2c_r(ov, OV7610_REG_SAT);
if (rc < 0)
return rc;
else
@@ -1926,19 +1912,19 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
break;
case SEN_OV7620:
// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
-// rc = ov51x_i2c_read(ov511, 0x62);
+// rc = i2c_r(ov, 0x62);
// if (rc < 0)
// return rc;
// else
// *val = (rc & 0x7e) << 9;
- rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+ rc = i2c_r(ov, OV7610_REG_SAT);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->colour;
+ *val = ov->colour;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1946,7 +1932,7 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->colour = *val;
+ ov->colour = *val;
return 0;
}
@@ -1955,44 +1941,42 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's hue (red/blue balance) setting to "val" */
static int
-sensor_set_hue(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_RED, 0xFF - (val >> 8));
+ rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
if (rc < 0)
goto out;
- rc = ov51x_i2c_write(ov511, OV7610_REG_BLUE, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
// Hue control is causing problems. I will enable it once it's fixed.
#if 0
- rc = ov51x_i2c_write(ov511, 0x7a,
- (unsigned char)(val >> 8) + 0xb);
+ rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
if (rc < 0)
goto out;
- rc = ov51x_i2c_write(ov511, 0x79,
- (unsigned char)(val >> 8) + 0xb);
+ rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
if (rc < 0)
goto out;
#endif
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0d, (val + 32768) >> 8);
+ rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
if (rc < 0)
goto out;
break;
@@ -2003,9 +1987,9 @@ sensor_set_hue(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->hue = val;
+ ov->hue = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2013,29 +1997,29 @@ out:
/* Gets sensor's hue (red/blue balance) setting */
static int
-sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_BLUE);
+ rc = i2c_r(ov, OV7610_REG_BLUE);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_OV7620:
- rc = ov51x_i2c_read(ov511, 0x7a);
+ rc = i2c_r(ov, 0x7a);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->hue;
+ *val = ov->hue;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -2043,7 +2027,7 @@ sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->hue = *val;
+ ov->hue = *val;
return 0;
}
@@ -2051,30 +2035,30 @@ sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
/* -------------------------------------------------------------------------- */
static inline int
-sensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
{
int rc;
PDEBUG(4, "sensor_set_picture");
- ov511->whiteness = p->whiteness;
+ ov->whiteness = p->whiteness;
/* Don't return error if a setting is unsupported, or rest of settings
* will not be performed */
- rc = sensor_set_contrast(ov511, p->contrast);
+ rc = sensor_set_contrast(ov, p->contrast);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_brightness(ov511, p->brightness);
+ rc = sensor_set_brightness(ov, p->brightness);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_saturation(ov511, p->colour);
+ rc = sensor_set_saturation(ov, p->colour);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_hue(ov511, p->hue);
+ rc = sensor_set_hue(ov, p->hue);
if (FATAL_ERROR(rc))
return rc;
@@ -2082,7 +2066,7 @@ sensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
}
static inline int
-sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
{
int rc;
@@ -2091,27 +2075,27 @@ sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
/* Don't return error if a setting is unsupported, or rest of settings
* will not be performed */
- rc = sensor_get_contrast(ov511, &(p->contrast));
+ rc = sensor_get_contrast(ov, &(p->contrast));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_brightness(ov511, &(p->brightness));
+ rc = sensor_get_brightness(ov, &(p->brightness));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_saturation(ov511, &(p->colour));
+ rc = sensor_get_saturation(ov, &(p->colour));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_hue(ov511, &(p->hue));
+ rc = sensor_get_hue(ov, &(p->hue));
if (FATAL_ERROR(rc))
return rc;
p->whiteness = 105 << 8;
/* Can we get these from frame[0]? -claudio? */
- p->depth = ov511->frame[0].depth;
- p->palette = ov511->frame[0].format;
+ p->depth = ov->frame[0].depth;
+ p->palette = ov->frame[0].format;
return 0;
}
@@ -2120,24 +2104,24 @@ sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
/* Sets current exposure for sensor. This only has an effect if auto-exposure
* is off */
static inline int
-sensor_set_exposure(struct usb_ov511 *ov511, unsigned char val)
+sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV6620:
case SEN_OV6630:
case SEN_OV7610:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- rc = ov51x_i2c_write(ov511, 0x10, val);
+ rc = i2c_w(ov, 0x10, val);
if (rc < 0)
goto out;
@@ -2153,9 +2137,9 @@ sensor_set_exposure(struct usb_ov511 *ov511, unsigned char val)
}
rc = 0; /* Success */
- ov511->exposure = val;
+ ov->exposure = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2164,18 +2148,18 @@ out:
/* Gets current exposure level from sensor, regardless of whether it is under
* manual control. */
static int
-sensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val)
+sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- rc = ov51x_i2c_read(ov511, 0x10);
+ rc = i2c_r(ov, 0x10);
if (rc < 0)
return rc;
else
@@ -2193,24 +2177,22 @@ sensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val)
}
PDEBUG(3, "%d", *val);
- ov511->exposure = *val;
+ ov->exposure = *val;
return 0;
}
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
static inline void
-ov51x_led_control(struct usb_ov511 *ov511, int enable)
+ov51x_led_control(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->bridge == BRG_OV511PLUS)
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_LED_CTL,
- enable ? 1 : 0);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_reg_write_mask(ov511->dev, OV518_REG_GPIO_OUT,
- enable ? 0x02 : 0x00, 0x02);
+ if (ov->bridge == BRG_OV511PLUS)
+ reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
+ else if (ov->bclass == BCL_OV518)
+ reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
+
return;
}
@@ -2224,7 +2206,7 @@ ov51x_led_control(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static int
-sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
+sensor_set_light_freq(struct usb_ov511 *ov, int freq)
{
int sixty;
@@ -2239,24 +2221,24 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
return -EINVAL;
}
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
- ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
- ov51x_i2c_write_mask(ov511, 0x13, 0x10, 0x10);
- ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x10);
+ i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+ i2c_w(ov, 0x2b, sixty?0x00:0xac);
+ i2c_w_mask(ov, 0x13, 0x10, 0x10);
+ i2c_w_mask(ov, 0x13, 0x00, 0x10);
break;
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
- ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
- ov51x_i2c_write_mask(ov511, 0x76, 0x01, 0x01);
+ i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+ i2c_w(ov, 0x2b, sixty?0x00:0xac);
+ i2c_w_mask(ov, 0x76, 0x01, 0x01);
break;
case SEN_OV6620:
case SEN_OV6630:
- ov51x_i2c_write(ov511, 0x2b, sixty?0xa8:0x28);
- ov51x_i2c_write(ov511, 0x2a, sixty?0x84:0xa4);
+ i2c_w(ov, 0x2b, sixty?0xa8:0x28);
+ i2c_w(ov, 0x2a, sixty?0x84:0xa4);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -2268,7 +2250,7 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
return -EINVAL;
}
- ov511->lightfreq = freq;
+ ov->lightfreq = freq;
return 0;
}
@@ -2283,23 +2265,23 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
* Returns: 0 for success
*/
static inline int
-sensor_set_banding_filter(struct usb_ov511 *ov511, int enable)
+sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
{
int rc;
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
- || ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+ || ov->sensor == SEN_SAA7111A) {
PDEBUG(5, "Unsupported with this sensor");
return -EPERM;
}
- rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x04:0x00, 0x04);
+ rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
if (rc < 0)
return rc;
- ov511->bandfilt = enable;
+ ov->bandfilt = enable;
return 0;
}
@@ -2311,23 +2293,23 @@ sensor_set_banding_filter(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static inline int
-sensor_set_auto_brightness(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
{
int rc;
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
- || ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+ || ov->sensor == SEN_SAA7111A) {
PDEBUG(5, "Unsupported with this sensor");
return -EPERM;
}
- rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x10:0x00, 0x10);
+ rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
if (rc < 0)
return rc;
- ov511->auto_brt = enable;
+ ov->auto_brt = enable;
return 0;
}
@@ -2339,22 +2321,22 @@ sensor_set_auto_brightness(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static inline int
-sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x00:0x80, 0x80);
+ i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
break;
case SEN_OV6620:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x13, enable?0x01:0x00, 0x01);
+ i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
break;
case SEN_OV6630:
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x00:0x10, 0x10);
+ i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -2366,7 +2348,7 @@ sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
return -EINVAL;
}
- ov511->auto_exp = enable;
+ ov->auto_exp = enable;
return 0;
}
@@ -2379,27 +2361,27 @@ sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static int
-sensor_set_backlight(struct usb_ov511 *ov511, int enable)
+sensor_set_backlight(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7620:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x68, enable?0xe0:0xc0, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+ i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
break;
case SEN_OV6620:
- ov51x_i2c_write_mask(ov511, 0x4e, enable?0xe0:0xc0, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x0e, enable?0x80:0x00, 0x80);
+ i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
break;
case SEN_OV6630:
- ov51x_i2c_write_mask(ov511, 0x4e, enable?0x80:0x60, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+ i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
break;
case SEN_OV7610:
case SEN_OV7620AE:
@@ -2413,7 +2395,7 @@ sensor_set_backlight(struct usb_ov511 *ov511, int enable)
return -EINVAL;
}
- ov511->backlight = enable;
+ ov->backlight = enable;
return 0;
}
@@ -2422,7 +2404,7 @@ sensor_set_backlight(struct usb_ov511 *ov511, int enable)
* planar or not), or zero for unsupported format.
*/
static inline int
-ov511_get_depth(int palette)
+get_depth(int palette)
{
switch (palette) {
case VIDEO_PALETTE_GREY: return 8;
@@ -2445,55 +2427,55 @@ get_frame_length(struct ov511_frame *frame)
return 0;
else
return ((frame->width * frame->height
- * ov511_get_depth(frame->format)) >> 3);
+ * get_depth(frame->format)) >> 3);
}
static int
-mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
+mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
int mode, int sub_flag, int qvga)
{
int clock;
/******** Mode (VGA/QVGA) and sensor specific regs ********/
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+ i2c_w(ov, 0x14, qvga?0x24:0x04);
// FIXME: Does this improve the image quality or frame rate?
#if 0
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, 0x10);
- ov51x_i2c_write(ov511, 0x25, qvga?0x40:0x8a);
- ov51x_i2c_write(ov511, 0x2f, qvga?0x30:0xb0);
- ov51x_i2c_write(ov511, 0x35, qvga?0x1c:0x9c);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, 0x10);
+ i2c_w(ov, 0x25, qvga?0x40:0x8a);
+ i2c_w(ov, 0x2f, qvga?0x30:0xb0);
+ i2c_w(ov, 0x35, qvga?0x1c:0x9c);
#endif
break;
case SEN_OV7620:
-// ov51x_i2c_write(ov511, 0x2b, 0x00);
- ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
- ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
- ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
- ov51x_i2c_write_mask(ov511, 0x67, qvga?0xf0:0x90, 0xf0);
- ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+// i2c_w(ov, 0x2b, 0x00);
+ i2c_w(ov, 0x14, qvga?0xa4:0x84);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, qvga?0x20:0x3a);
+ i2c_w(ov, 0x25, qvga?0x30:0x60);
+ i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+ i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
+ i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
break;
case SEN_OV7620AE:
-// ov51x_i2c_write(ov511, 0x2b, 0x00);
- ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
+// i2c_w(ov, 0x2b, 0x00);
+ i2c_w(ov, 0x14, qvga?0xa4:0x84);
// FIXME: Enable this once 7620AE uses 7620 initial settings
#if 0
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
- ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
- ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
- ov51x_i2c_write_mask(ov511, 0x67, qvga?0xb0:0x90, 0xf0);
- ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, qvga?0x20:0x3a);
+ i2c_w(ov, 0x25, qvga?0x30:0x60);
+ i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+ i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
+ i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
#endif
break;
case SEN_OV6620:
case SEN_OV6630:
- ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+ i2c_w(ov, 0x14, qvga?0x24:0x04);
/* No special settings yet */
break;
default:
@@ -2504,19 +2486,17 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
/******** Palette-specific regs ********/
if (mode == VIDEO_PALETTE_GREY) {
- if (ov511->sensor == SEN_OV7610
- || ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
/* these aren't valid on the OV6620/OV7620/6630? */
- ov51x_i2c_write_mask(ov511, 0x0e, 0x40, 0x40);
+ i2c_w_mask(ov, 0x0e, 0x40, 0x40);
}
- ov51x_i2c_write_mask(ov511, 0x13, 0x20, 0x20);
+ i2c_w_mask(ov, 0x13, 0x20, 0x20);
} else {
- if (ov511->sensor == SEN_OV7610
- || ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
/* not valid on the OV6620/OV7620/6630? */
- ov51x_i2c_write_mask(ov511, 0x0e, 0x00, 0x40);
+ i2c_w_mask(ov, 0x0e, 0x00, 0x40);
}
- ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x20);
+ i2c_w_mask(ov, 0x13, 0x00, 0x20);
}
/******** Clock programming ********/
@@ -2525,13 +2505,13 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
/* The OV6620 needs special handling. This prevents the
* severe banding that normally occurs */
- if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630)
+ if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
{
/* Clock down */
- ov51x_i2c_write(ov511, 0x2a, 0x04);
+ i2c_w(ov, 0x2a, 0x04);
- if (ov511->compress) {
+ if (ov->compress) {
// clock = 0; /* This ensures the highest frame rate */
clock = 3;
} else if (clockdiv == -1) { /* If user didn't override it */
@@ -2542,21 +2522,21 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
PDEBUG(4, "Setting clock divisor to %d", clock);
- ov51x_i2c_write(ov511, 0x11, clock);
+ i2c_w(ov, 0x11, clock);
- ov51x_i2c_write(ov511, 0x2a, 0x84);
+ i2c_w(ov, 0x2a, 0x84);
/* This next setting is critical. It seems to improve
* the gain or the contrast. The "reserved" bits seem
* to have some effect in this case. */
- ov51x_i2c_write(ov511, 0x2d, 0x85);
+ i2c_w(ov, 0x2d, 0x85);
}
else
{
- if (ov511->compress) {
+ if (ov->compress) {
clock = 1; /* This ensures the highest frame rate */
} else if (clockdiv == -1) { /* If user didn't override it */
/* Calculate and set the clock divisor */
- clock = ((sub_flag ? ov511->subw * ov511->subh
+ clock = ((sub_flag ? ov->subw * ov->subh
: width * height)
* (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
/ 66000;
@@ -2566,45 +2546,44 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
PDEBUG(4, "Setting clock divisor to %d", clock);
- ov51x_i2c_write(ov511, 0x11, clock);
+ i2c_w(ov, 0x11, clock);
}
/******** Special Features ********/
if (framedrop >= 0)
- ov51x_i2c_write(ov511, 0x16, framedrop);
+ i2c_w(ov, 0x16, framedrop);
/* We only have code to convert GBR -> RGB24 */
if ((mode == VIDEO_PALETTE_RGB24) && sensor_gbr)
- ov51x_i2c_write_mask(ov511, 0x12, 0x08, 0x08);
+ i2c_w_mask(ov, 0x12, 0x08, 0x08);
else
- ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x08);
+ i2c_w_mask(ov, 0x12, 0x00, 0x08);
/* Test Pattern */
- ov51x_i2c_write_mask(ov511, 0x12, (testpat?0x02:0x00), 0x02);
+ i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
/* Auto white balance */
// if (awb)
- ov51x_i2c_write_mask(ov511, 0x12, 0x04, 0x04);
+ i2c_w_mask(ov, 0x12, 0x04, 0x04);
// else
-// ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x04);
+// i2c_w_mask(ov, 0x12, 0x00, 0x04);
- // This will go away as soon as ov511_mode_init_sensor_regs()
+ // This will go away as soon as ov51x_mode_init_sensor_regs()
// is fully tested.
/* 7620/6620/6630? don't have register 0x35, so play it safe */
- if (ov511->sensor == SEN_OV7610 ||
- ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
if (width == 640 && height == 480)
- ov51x_i2c_write(ov511, 0x35, 0x9e);
+ i2c_w(ov, 0x35, 0x9e);
else
- ov51x_i2c_write(ov511, 0x35, 0x1e);
+ i2c_w(ov, 0x35, 0x1e);
}
return 0;
}
static int
-set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
+set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
int sub_flag)
{
int ret;
@@ -2613,7 +2592,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
/* The different sensor ICs handle setting up of window differently.
* IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
hwsbase = 0x38;
@@ -2637,9 +2616,9 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
return -EINVAL;
}
- if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630) {
+ if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
if (width > 176 && height > 144) { /* CIF */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 0);
if (ret < 0)
return ret;
@@ -2651,7 +2630,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
err("Illegal dimensions");
return -EINVAL;
} else { /* QCIF */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 1);
if (ret < 0)
return ret;
@@ -2660,7 +2639,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
}
} else {
if (width > 320 && height > 240) { /* VGA */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 0);
if (ret < 0)
return ret;
@@ -2672,7 +2651,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
err("Illegal dimensions");
return -EINVAL;
} else { /* QVGA */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 1);
if (ret < 0)
return ret;
@@ -2688,24 +2667,20 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
/* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
if (sub_flag) {
- ov51x_i2c_write(ov511, 0x17, hwsbase+(ov511->subx>>hwscale));
- ov51x_i2c_write(ov511, 0x18,
- hwebase+((ov511->subx+ov511->subw)>>hwscale));
- ov51x_i2c_write(ov511, 0x19, vwsbase+(ov511->suby>>vwscale));
- ov51x_i2c_write(ov511, 0x1a,
- vwebase+((ov511->suby+ov511->subh)>>vwscale));
+ i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
+ i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
+ i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
+ i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
} else {
- ov51x_i2c_write(ov511, 0x17, hwsbase + hoffset);
- ov51x_i2c_write(ov511, 0x18,
- hwebase + hoffset + (hwsize>>hwscale));
- ov51x_i2c_write(ov511, 0x19, vwsbase + voffset);
- ov51x_i2c_write(ov511, 0x1a,
- vwebase + voffset + (vwsize>>vwscale));
+ i2c_w(ov, 0x17, hwsbase + hoffset);
+ i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
+ i2c_w(ov, 0x19, vwsbase + voffset);
+ i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
}
#ifdef OV511_DEBUG
if (dump_sensor)
- ov51x_dump_i2c_regs(ov511);
+ dump_i2c_regs(ov);
#endif
return 0;
@@ -2716,18 +2691,14 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
static int
-ov511_mode_init_regs(struct usb_ov511 *ov511,
+ov511_mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int lncnt, pxcnt, rc = 0;
- struct usb_device *dev = ov511->dev;
-
- if (!ov511 || !dev)
- return -EFAULT;
if (sub_flag) {
- width = ov511->subw;
- height = ov511->subh;
+ width = ov->subw;
+ height = ov->subh;
}
PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
@@ -2735,7 +2706,7 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
// FIXME: This should be moved to a 7111a-specific function once
// subcapture is dealt with properly
- if (ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_SAA7111A) {
if (width == 320 && height == 240) {
/* No need to do anything special */
} else if (width == 640 && height == 480) {
@@ -2754,26 +2725,22 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
return -EINVAL;
}
- if (width < ov511->minwidth || height < ov511->minheight) {
+ if (width < ov->minwidth || height < ov->minheight) {
err("Requested dimensions are too small");
return -EINVAL;
}
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
if (mode == VIDEO_PALETTE_GREY) {
- ov511_reg_write(dev, 0x16, 0x00);
-
- /* For snapshot */
- ov511_reg_write(dev, 0x1e, 0x00);
- ov511_reg_write(dev, 0x1f, 0x01);
+ reg_w(ov, R511_CAM_UV_EN, 0x00);
+ reg_w(ov, R511_SNAP_UV_EN, 0x00);
+ reg_w(ov, R511_SNAP_OPTS, 0x01);
} else {
- ov511_reg_write(dev, 0x16, 0x01);
-
- /* For snapshot */
- ov511_reg_write(dev, 0x1e, 0x01);
- ov511_reg_write(dev, 0x1f, 0x03);
+ reg_w(ov, R511_CAM_UV_EN, 0x01);
+ reg_w(ov, R511_SNAP_UV_EN, 0x01);
+ reg_w(ov, R511_SNAP_OPTS, 0x03);
}
/* Here I'm assuming that snapshot size == image size.
@@ -2782,25 +2749,28 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
pxcnt = (width >> 3) - 1;
lncnt = (height >> 3) - 1;
- ov511_reg_write(dev, 0x12, pxcnt);
- ov511_reg_write(dev, 0x13, lncnt);
- ov511_reg_write(dev, 0x14, 0x00);
- ov511_reg_write(dev, 0x15, 0x00);
- ov511_reg_write(dev, 0x18, 0x03); /* YUV420, low pass filer on */
+ reg_w(ov, R511_CAM_PXCNT, pxcnt);
+ reg_w(ov, R511_CAM_LNCNT, lncnt);
+ reg_w(ov, R511_CAM_PXDIV, 0x00);
+ reg_w(ov, R511_CAM_LNDIV, 0x00);
+
+ /* YUV420, low pass filer on */
+ reg_w(ov, R511_CAM_OPTS, 0x03);
/* Snapshot additions */
- ov511_reg_write(dev, 0x1a, pxcnt);
- ov511_reg_write(dev, 0x1b, lncnt);
- ov511_reg_write(dev, 0x1c, 0x00);
- ov511_reg_write(dev, 0x1d, 0x00);
+ reg_w(ov, R511_SNAP_PXCNT, pxcnt);
+ reg_w(ov, R511_SNAP_LNCNT, lncnt);
+ reg_w(ov, R511_SNAP_PXDIV, 0x00);
+ reg_w(ov, R511_SNAP_LNDIV, 0x00);
- if (ov511->compress) {
- ov511_reg_write(dev, 0x78, 0x07); // Turn on Y & UV compression
- ov511_reg_write(dev, 0x79, 0x03); // Enable LUTs
- ov511_reset(ov511, OV511_RESET_OMNICE);
+ if (ov->compress) {
+ /* Enable Y and UV quantization and compression */
+ reg_w(ov, R511_COMP_EN, 0x07);
+ reg_w(ov, R511_COMP_LUT_EN, 0x03);
+ ov51x_reset(ov, OV511_RESET_OMNICE);
}
//out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2824,17 +2794,15 @@ static struct mode_list_518 mlist518[] = {
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
static int
-ov518_mode_init_regs(struct usb_ov511 *ov511,
+ov518_mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int i;
- struct usb_device *dev = ov511->dev;
- unsigned char b[3]; /* Multiple-value reg buffer */
PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
width, height, mode, sub_flag);
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
for (i = 0; mlist518[i].width; i++) {
@@ -2852,113 +2820,94 @@ ov518_mode_init_regs(struct usb_ov511 *ov511,
// pxcnt = sub_flag ? (ov511->subw >> 3) - 1 : mlist[i].pxcnt;
// lncnt = sub_flag ? (ov511->subh >> 3) - 1 : mlist[i].lncnt;
//
-// ov511_reg_write(dev, 0x12, pxcnt);
-// ov511_reg_write(dev, 0x13, lncnt);
+// reg_w(ov511, 0x12, pxcnt);
+// reg_w(ov511, 0x13, lncnt);
/******** Set the mode ********/
/* Mode independent regs */
- ov511_reg_write(dev, 0x2b, 0x00);
- ov511_reg_write(dev, 0x2d, 0x00);
- ov511_reg_write(dev, 0x3b, 0x00);
- ov511_reg_write(dev, 0x3d, 0x00);
+ reg_w(ov, 0x2b, 0x00);
+ reg_w(ov, 0x2d, 0x00);
+ reg_w(ov, 0x3b, 0x00);
+ reg_w(ov, 0x3d, 0x00);
/* Mode dependent regs. Regs 38 - 3e are always the same as
* regs 28 - 2e */
- ov511_reg_write_mask(dev, 0x28, mlist518[i].reg28
+ reg_w_mask(ov, 0x28, mlist518[i].reg28
| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
- ov511_reg_write(dev, 0x29, mlist518[i].reg29);
- ov511_reg_write(dev, 0x2a, mlist518[i].reg2a);
- ov511_reg_write(dev, 0x2c, mlist518[i].reg2c);
- ov511_reg_write(dev, 0x2e, mlist518[i].reg2e);
- ov511_reg_write_mask(dev, 0x38, mlist518[i].reg28
+ reg_w(ov, 0x29, mlist518[i].reg29);
+ reg_w(ov, 0x2a, mlist518[i].reg2a);
+ reg_w(ov, 0x2c, mlist518[i].reg2c);
+ reg_w(ov, 0x2e, mlist518[i].reg2e);
+ reg_w_mask(ov, 0x38, mlist518[i].reg28
| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
- ov511_reg_write(dev, 0x39, mlist518[i].reg29);
- ov511_reg_write(dev, 0x3a, mlist518[i].reg2a);
- ov511_reg_write(dev, 0x3c, mlist518[i].reg2c);
- ov511_reg_write(dev, 0x3e, mlist518[i].reg2e);
- ov511_reg_write(dev, 0x24, mlist518[i].reg24);
- ov511_reg_write(dev, 0x25, mlist518[i].reg25);
+ reg_w(ov, 0x39, mlist518[i].reg29);
+ reg_w(ov, 0x3a, mlist518[i].reg2a);
+ reg_w(ov, 0x3c, mlist518[i].reg2c);
+ reg_w(ov, 0x3e, mlist518[i].reg2e);
+ reg_w(ov, 0x24, mlist518[i].reg24);
+ reg_w(ov, 0x25, mlist518[i].reg25);
/* Windows driver does this here; who knows why */
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
/******** Set the framerate (to 15 FPS) ********/
/* Mode independent, but framerate dependent, regs */
/* These are for 15 FPS only */
- ov511_reg_write(dev, 0x51, 0x08);
- ov511_reg_write(dev, 0x22, 0x18);
- ov511_reg_write(dev, 0x23, 0xff);
- ov511_reg_write(dev, 0x71, 0x19); /* Compression-related? */
+ reg_w(ov, 0x51, 0x08);
+ reg_w(ov, 0x22, 0x18);
+ reg_w(ov, 0x23, 0xff);
+ reg_w(ov, 0x71, 0x19); /* Compression-related? */
// FIXME: Sensor-specific
/* Bit 5 is what matters here. Of course, it is "reserved" */
- ov51x_i2c_write(ov511, 0x54, 0x23);
+ i2c_w(ov, 0x54, 0x23);
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
/* Mode dependent regs */
if ((width == 352 && height == 288) ||
(width == 320 && height == 240)) {
- b[0]=0x80; b[1]=0x02;
- ov518_reg_write_multi(dev, 0x30, b, 2);
- b[0]=0x90; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc4, b, 2);
- b[0]=0xf4; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc6, b, 2);
- b[0]=0xf4; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc7, b, 2);
- b[0]=0x8e; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc8, b, 2);
- b[0]=0x1a; b[1]=0x00; b[2]=0x02;
- ov518_reg_write_multi(dev, 0xca, b, 3);
- b[0]=0x14; b[1]=0x02;
- ov518_reg_write_multi(dev, 0xcb, b, 2);
- b[0]=0xd0; b[1]=0x07;
- ov518_reg_write_multi(dev, 0xcc, b, 2);
- b[0]=0x20; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xcd, b, 2);
- b[0]=0x60; b[1]=0x02;
- ov518_reg_write_multi(dev, 0xce, b, 2);
-
+ /* 640 (280h) byte iso packets */
+ ov518_reg_w32(ov, 0x30, 640, 2); /* 280h */
+ ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
+ ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */
+ ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */
+ ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */
+ ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
+ ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
+ ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */
+ ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
+ ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
} else if ((width == 176 && height == 144) ||
(width == 160 && height == 120)) {
- b[0]=0x80; b[1]=0x01;
- ov518_reg_write_multi(dev, 0x30, b, 2);
- b[0]=0xc8; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc4, b, 2);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc6, b, 2);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc7, b, 2);
- b[0]=0x60; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc8, b, 2);
- b[0]=0x0f; b[1]=0x33; b[2]=0x01;
- ov518_reg_write_multi(dev, 0xca, b, 3);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xcb, b, 2);
- b[0]=0xec; b[1]=0x04;
- ov518_reg_write_multi(dev, 0xcc, b, 2);
- b[0]=0x13; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xcd, b, 2);
- b[0]=0x6d; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xce, b, 2);
+ /* 384 (180h) byte iso packets */
+ ov518_reg_w32(ov, 0x30, 384, 2); /* 180h */
+ ov518_reg_w32(ov, 0xc4, 200, 2); /* c8h */
+ ov518_reg_w32(ov, 0xc6, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xc7, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xc8, 96, 2); /* 60h */
+ ov518_reg_w32(ov, 0xca, 78607, 3); /* 1330fh */
+ ov518_reg_w32(ov, 0xcb, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xcc, 1260, 2); /* 4ech */
+ ov518_reg_w32(ov, 0xcd, 19, 2); /* 13h */
+ ov518_reg_w32(ov, 0xce, 365, 2); /* 16dh */
} else {
/* Can't happen, since we already handled this case */
err("ov518_mode_init_regs(): **** logic error ****");
}
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
break;
}
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
/* Reset it just for good measure */
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
return -EIO;
if (mlist518[i].width == 0) {
@@ -2971,29 +2920,31 @@ ov518_mode_init_regs(struct usb_ov511 *ov511,
/* This is a wrapper around the OV511, OV518, and sensor specific functions */
static int
-mode_init_regs(struct usb_ov511 *ov511,
+mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int rc = 0;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
- rc = ov518_mode_init_regs(ov511, width, height, mode, sub_flag);
+ if (!ov || !ov->dev)
+ return -EFAULT;
+
+ if (ov->bclass == BCL_OV518) {
+ rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
} else {
- rc = ov511_mode_init_regs(ov511, width, height, mode, sub_flag);
+ rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
}
if (FATAL_ERROR(rc))
return rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
case SEN_OV6620:
case SEN_OV6630:
- rc = set_ov_sensor_window(ov511, width, height, mode, sub_flag);
+ rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -3001,10 +2952,10 @@ mode_init_regs(struct usb_ov511 *ov511,
rc = -EINVAL;
break;
case SEN_SAA7111A:
-// rc = mode_init_saa_sensor_regs(ov511, width, height, mode,
+// rc = mode_init_saa_sensor_regs(ov, width, height, mode,
// sub_flag);
- PDEBUG(1, "SAA status = 0X%x", ov51x_i2c_read(ov511, 0x1f));
+ PDEBUG(1, "SAA status = 0X%x", i2c_r(ov, 0x1f));
break;
default:
err("Unknown sensor");
@@ -3015,25 +2966,25 @@ mode_init_regs(struct usb_ov511 *ov511,
return rc;
/* Sensor-independent settings */
- rc = sensor_set_auto_brightness(ov511, ov511->auto_brt);
+ rc = sensor_set_auto_brightness(ov, ov->auto_brt);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_auto_exposure(ov511, ov511->auto_exp);
+ rc = sensor_set_auto_exposure(ov, ov->auto_exp);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_banding_filter(ov511, bandingfilter);
+ rc = sensor_set_banding_filter(ov, bandingfilter);
if (FATAL_ERROR(rc))
return rc;
- if (ov511->lightfreq) {
- rc = sensor_set_light_freq(ov511, lightfreq);
+ if (ov->lightfreq) {
+ rc = sensor_set_light_freq(ov, lightfreq);
if (FATAL_ERROR(rc))
return rc;
}
- rc = sensor_set_backlight(ov511, ov511->backlight);
+ rc = sensor_set_backlight(ov, ov->backlight);
if (FATAL_ERROR(rc))
return rc;
@@ -3044,28 +2995,28 @@ mode_init_regs(struct usb_ov511 *ov511,
* useful for apps that use read() and do not set these.
*/
static int
-ov51x_set_default_params(struct usb_ov511 *ov511)
+ov51x_set_default_params(struct usb_ov511 *ov)
{
int i;
- PDEBUG(3, "%dx%d, RGB24", ov511->maxwidth, ov511->maxheight);
+ PDEBUG(3, "%dx%d, RGB24", ov->maxwidth, ov->maxheight);
/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
* (using read() instead). */
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].width = ov511->maxwidth;
- ov511->frame[i].height = ov511->maxheight;
- ov511->frame[i].bytes_read = 0;
+ ov->frame[i].width = ov->maxwidth;
+ ov->frame[i].height = ov->maxheight;
+ ov->frame[i].bytes_read = 0;
if (force_palette)
- ov511->frame[i].format = force_palette;
+ ov->frame[i].format = force_palette;
else
- ov511->frame[i].format = VIDEO_PALETTE_RGB24;
- ov511->frame[i].depth = ov511_get_depth(ov511->frame[i].format);
+ ov->frame[i].format = VIDEO_PALETTE_RGB24;
+ ov->frame[i].depth = get_depth(ov->frame[i].format);
}
/* Initialize to max width/height, RGB24 */
- if (mode_init_regs(ov511, ov511->maxwidth, ov511->maxheight,
- ov511->frame[0].format, 0) < 0)
+ if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
+ ov->frame[0].format, 0) < 0)
return -EINVAL;
return 0;
@@ -3079,18 +3030,17 @@ ov51x_set_default_params(struct usb_ov511 *ov511)
/* Set analog input port of decoder */
static int
-decoder_set_input(struct usb_ov511 *ov511, int input)
+decoder_set_input(struct usb_ov511 *ov, int input)
{
PDEBUG(4, "port %d", input);
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
/* Select mode */
- ov51x_i2c_write_mask(ov511, 0x02, input, 0x07);
+ i2c_w_mask(ov, 0x02, input, 0x07);
/* Bypass chrominance trap for modes 4..7 */
- ov51x_i2c_write_mask(ov511, 0x09,
- (input > 3) ? 0x80:0x00, 0x80);
+ i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
break;
}
default:
@@ -3102,9 +3052,9 @@ decoder_set_input(struct usb_ov511 *ov511, int input)
/* Get ASCII name of video input */
static int
-decoder_get_input_name(struct usb_ov511 *ov511, int input, char *name)
+decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
{
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
if (input < 0 || input > 7)
@@ -3125,11 +3075,11 @@ decoder_get_input_name(struct usb_ov511 *ov511, int input, char *name)
/* Set norm (NTSC, PAL, SECAM, AUTO) */
static int
-decoder_set_norm(struct usb_ov511 *ov511, int norm)
+decoder_set_norm(struct usb_ov511 *ov, int norm)
{
PDEBUG(4, "%d", norm);
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
int reg_8, reg_e;
@@ -3150,8 +3100,8 @@ decoder_set_norm(struct usb_ov511 *ov511, int norm)
return -EINVAL;
}
- ov51x_i2c_write_mask(ov511, 0x08, reg_8, 0xc0);
- ov51x_i2c_write_mask(ov511, 0x0e, reg_e, 0x70);
+ i2c_w_mask(ov, 0x08, reg_8, 0xc0);
+ i2c_w_mask(ov, 0x0e, reg_e, 0x70);
break;
}
default:
@@ -3198,8 +3148,8 @@ decoder_set_norm(struct usb_ov511 *ov511, int norm)
#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
static inline void
-ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
- int rowPixels, unsigned char * rgb, int bits)
+move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
+ int rowPixels, unsigned char * rgb, int bits)
{
const int rvScale = 91881;
const int guScale = -22553;
@@ -3269,10 +3219,10 @@ ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
**********************************************************************/
/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
- * array at pOut is specified by w.
+ * image at pOut is specified by w.
*/
static inline void
-ov511_make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
+make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
{
unsigned char *pOut1 = pOut;
int x, y;
@@ -3310,7 +3260,7 @@ yuv400raw_to_yuv400p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 8) {
- ov511_make_8x8(pIn, pOut, frame->rawwidth);
+ make_8x8(pIn, pOut, frame->rawwidth);
pIn += 64;
pOut += 8;
}
@@ -3369,8 +3319,8 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 16) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 16) {
- ov511_make_8x8(pIn, pOut, w);
- ov511_make_8x8(pIn + 64, pOut + a/4, w);
+ make_8x8(pIn, pOut, w);
+ make_8x8(pIn + 64, pOut + a/4, w);
pIn += 384;
pOut += 8;
}
@@ -3384,7 +3334,7 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 8) {
- ov511_make_8x8(pIn, pOut, frame->rawwidth);
+ make_8x8(pIn, pOut, frame->rawwidth);
pIn += 64;
pOut += 8;
if ((++k) > 3) {
@@ -3441,17 +3391,17 @@ fixFrameRGBoffset(struct ov511_frame *frame)
*
**********************************************************************/
-/* Chooses a decompression module, locks it, and sets ov511->decomp_ops
+/* Chooses a decompression module, locks it, and sets ov->decomp_ops
* accordingly. Returns -ENXIO if decompressor is not available, otherwise
* returns 0 if no other error.
*/
static int
-ov51x_request_decompressor(struct usb_ov511 *ov511)
+request_decompressor(struct usb_ov511 *ov)
{
- if (!ov511)
+ if (!ov)
return -ENODEV;
- if (ov511->decomp_ops) {
+ if (ov->decomp_ops) {
err("ERROR: Decompressor already requested!");
return -EINVAL;
}
@@ -3459,24 +3409,23 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
lock_kernel();
/* Try to get MMX, and fall back on no-MMX if necessary */
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
+ if (ov->bclass == BCL_OV511) {
if (ov511_mmx_decomp_ops) {
PDEBUG(3, "Using OV511 MMX decompressor");
- ov511->decomp_ops = ov511_mmx_decomp_ops;
+ ov->decomp_ops = ov511_mmx_decomp_ops;
} else if (ov511_decomp_ops) {
PDEBUG(3, "Using OV511 decompressor");
- ov511->decomp_ops = ov511_decomp_ops;
+ ov->decomp_ops = ov511_decomp_ops;
} else {
err("No decompressor available");
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (ov518_mmx_decomp_ops) {
PDEBUG(3, "Using OV518 MMX decompressor");
- ov511->decomp_ops = ov518_mmx_decomp_ops;
+ ov->decomp_ops = ov518_mmx_decomp_ops;
} else if (ov518_decomp_ops) {
PDEBUG(3, "Using OV518 decompressor");
- ov511->decomp_ops = ov518_decomp_ops;
+ ov->decomp_ops = ov518_decomp_ops;
} else {
err("No decompressor available");
}
@@ -3484,13 +3433,13 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
err("Unknown bridge");
}
- if (ov511->decomp_ops) {
- if (!ov511->decomp_ops->decomp_lock) {
- ov511->decomp_ops = NULL;
+ if (ov->decomp_ops) {
+ if (!ov->decomp_ops->decomp_lock) {
+ ov->decomp_ops = NULL;
unlock_kernel();
return -ENOSYS;
}
- ov511->decomp_ops->decomp_lock();
+ ov->decomp_ops->decomp_lock();
unlock_kernel();
return 0;
} else {
@@ -3499,25 +3448,25 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
}
}
-/* Unlocks decompression module and nulls ov511->decomp_ops. Safe to call even
- * if ov511->decomp_ops is NULL.
+/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
+ * if ov->decomp_ops is NULL.
*/
static void
-ov51x_release_decompressor(struct usb_ov511 *ov511)
+release_decompressor(struct usb_ov511 *ov)
{
int released = 0; /* Did we actually do anything? */
- if (!ov511)
+ if (!ov)
return;
lock_kernel();
- if (ov511->decomp_ops && ov511->decomp_ops->decomp_unlock) {
- ov511->decomp_ops->decomp_unlock();
+ if (ov->decomp_ops && ov->decomp_ops->decomp_unlock) {
+ ov->decomp_ops->decomp_unlock();
released = 1;
}
- ov511->decomp_ops = NULL;
+ ov->decomp_ops = NULL;
unlock_kernel();
@@ -3526,26 +3475,26 @@ ov51x_release_decompressor(struct usb_ov511 *ov511)
}
static void
-ov51x_decompress(struct usb_ov511 *ov511, struct ov511_frame *frame,
- unsigned char *pIn0, unsigned char *pOut0)
+decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
+ unsigned char *pIn0, unsigned char *pOut0)
{
- if (!ov511->decomp_ops)
- if (ov51x_request_decompressor(ov511))
+ if (!ov->decomp_ops)
+ if (request_decompressor(ov))
return;
PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
if (frame->format == VIDEO_PALETTE_GREY
- && ov511->decomp_ops->decomp_400) {
- int ret = ov511->decomp_ops->decomp_400(
+ && ov->decomp_ops->decomp_400) {
+ int ret = ov->decomp_ops->decomp_400(
pIn0,
pOut0,
frame->rawwidth,
frame->rawheight,
frame->bytes_recvd);
PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
- } else if (ov511->decomp_ops->decomp_420) {
- int ret = ov511->decomp_ops->decomp_420(
+ } else if (ov->decomp_ops->decomp_420) {
+ int ret = ov->decomp_ops->decomp_420(
pIn0,
pOut0,
frame->rawwidth,
@@ -3585,8 +3534,8 @@ yuv420p_to_rgb(struct ov511_frame *frame,
u = (*pU++) - 128;
v = (*pV++) - 128;
- ov511_move_420_block(y00, y01, y10, y11, u, v,
- frame->width, pOut, bits);
+ move_420_block(y00, y01, y10, y11, u, v,
+ frame->width, pOut, bits);
pY += 2;
pOut += 2 * bytes;
@@ -3741,11 +3690,11 @@ deinterlace(struct ov511_frame *frame, int rawformat,
* 4. Fix the RGB offset, if necessary
*/
static void
-ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
+ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
{
if (dumppix) {
memset(frame->data, 0,
- MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+ MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
memmove(frame->data, frame->rawdata, frame->bytes_recvd);
return;
@@ -3754,9 +3703,9 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
/* YUV400 must be handled separately */
if (frame->format == VIDEO_PALETTE_GREY) {
/* Deinterlace frame, if necessary */
- if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+ if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata,
+ decompress(ov, frame, frame->rawdata,
frame->tempdata);
else
yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3766,7 +3715,7 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
frame->data);
} else {
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata,
+ decompress(ov, frame, frame->rawdata,
frame->data);
else
yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3778,12 +3727,12 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
/* Process frame->data to frame->rawdata */
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata, frame->tempdata);
+ decompress(ov, frame, frame->rawdata, frame->tempdata);
else
yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata);
/* Deinterlace frame, if necessary */
- if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+ if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
memmove(frame->rawdata, frame->tempdata,
MAX_RAW_DATA_SIZE(frame->width, frame->height));
deinterlace(frame, RAWFMT_YUV420, frame->rawdata,
@@ -3837,7 +3786,7 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
**********************************************************************/
static int
-ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
+ov511_move_data(struct usb_ov511 *ov, struct urb *urb)
{
unsigned char *cdata;
int data_size, num, offset, i, totlen = 0;
@@ -3847,7 +3796,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
PDEBUG(5, "Moving %d packets", urb->number_of_packets);
- data_size = ov511->packet_size - 1;
+ data_size = ov->packet_size - 1;
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
@@ -3858,15 +3807,15 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;
+ aPackNum[i] = n ? cdata[ov->packet_size - 1] : -1;
- if (!n || ov511->curframe == -1)
+ if (!n || ov->curframe == -1)
continue;
if (st)
PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
- frame = &ov511->frame[ov511->curframe];
+ frame = &ov->frame[ov->curframe];
/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
* byte non-zero. The EOF packet has image width/height in the
@@ -3884,7 +3833,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
if (printph) {
info("packet header (%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
- cdata[ov511->packet_size - 1],
+ cdata[ov->packet_size - 1],
cdata[0], cdata[1], cdata[2], cdata[3], cdata[4], cdata[5],
cdata[6], cdata[7], cdata[8], cdata[9], cdata[10], cdata[11]);
}
@@ -3898,7 +3847,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
/* Frame end */
if (cdata[8] & 0x80) {
ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+ + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
do_gettimeofday(ts);
/* Get the actual frame size from the EOF header */
@@ -3906,21 +3855,21 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
frame->rawheight = ((int)(cdata[10]) + 1) * 8;
PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d, recvd=%d",
- ov511->curframe,
- (int)(cdata[ov511->packet_size - 1]),
+ ov->curframe,
+ (int)(cdata[ov->packet_size - 1]),
frame->rawwidth,
frame->rawheight,
frame->bytes_recvd);
/* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+ RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+ RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE(frame->bytes_recvd,
8,
- MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
if (frame->scanstate == STATE_LINES) {
int iFrameNext;
@@ -3934,20 +3883,20 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
/* If next frame is ready or grabbing,
* point to it */
- iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
- if (ov511->frame[iFrameNext].grabstate == FRAME_READY
- || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
- ov511->curframe = iFrameNext;
- ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
+ iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+ if (ov->frame[iFrameNext].grabstate == FRAME_READY
+ || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+ ov->curframe = iFrameNext;
+ ov->frame[iFrameNext].scanstate = STATE_SCANNING;
} else {
if (frame->grabstate == FRAME_DONE) {
PDEBUG(4, "Frame done! congratulations");
} else {
PDEBUG(4, "Frame not ready? state = %d",
- ov511->frame[iFrameNext].grabstate);
+ ov->frame[iFrameNext].grabstate);
}
- ov511->curframe = -1;
+ ov->curframe = -1;
}
} else {
PDEBUG(5, "Frame done, but not scanning");
@@ -3957,7 +3906,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
*/
} else {
/* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+ PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
/* Check to see if it's a snapshot frame */
/* FIXME?? Should the snapshot reset go here? Performance? */
@@ -4006,24 +3955,24 @@ check_middle:
/* Dump all data exactly as received */
if (dumppix == 2) {
frame->bytes_recvd += n - 1;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - (n - 1),
&cdata[0], n - 1);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else if (!frame->compressed && !remove_zeros) {
frame->bytes_recvd += num;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - num,
&cdata[offset], num);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
int b, in = 0, allzero, copied=0;
if (offset) {
@@ -4046,7 +3995,7 @@ check_middle:
/* Don't copy it */
} else {
if (frame->bytes_recvd + copied + 32
- <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+ <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
memmove(frame->rawdata + frame->bytes_recvd + copied,
&cdata[in], 32);
copied += 32;
@@ -4070,7 +4019,7 @@ check_middle:
}
static int
-ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
+ov518_move_data(struct usb_ov511 *ov, struct urb *urb)
{
unsigned char *cdata;
int i, data_size, totlen = 0;
@@ -4080,7 +4029,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
PDEBUG(5, "Moving %d packets", urb->number_of_packets);
/* OV518(+) has no packet numbering */
- data_size = ov511->packet_size;
+ data_size = ov->packet_size;
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
@@ -4096,7 +4045,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
continue;
}
- if (ov511->curframe == -1) {
+ if (ov->curframe == -1) {
PDEBUG(4, "No frame currently active");
continue;
}
@@ -4104,21 +4053,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
if (st)
PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
- frame = &ov511->frame[ov511->curframe];
-
-#if 0
- {
- int d;
- /* Print all data */
- for (d = 0; d <= data_size - 16; d += 16) {
- info("%4x: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", d,
- cdata[d], cdata[d+1], cdata[d+2], cdata[d+3],
- cdata[d+4], cdata[d+5], cdata[d+6], cdata[d+7],
- cdata[d+8], cdata[d+9], cdata[d+10], cdata[d+11],
- cdata[d+12], cdata[d+13], cdata[d+14], cdata[d+15]);
- }
- }
-#endif
+ frame = &ov->frame[ov->curframe];
if (printph) {
info("packet header: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
@@ -4136,7 +4071,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
goto eof;
} else { //scanstate == STATE_SCANNING
/* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+ PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
goto sof;
}
} else {
@@ -4145,11 +4080,11 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
eof:
ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+ + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
do_gettimeofday(ts);
PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
- ov511->curframe,
+ ov->curframe,
(int)(cdata[9]), (int)(cdata[10]), frame->bytes_recvd);
// FIXME: Since we don't know the header formats yet,
@@ -4158,13 +4093,13 @@ eof:
frame->rawheight = frame->height;
/* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+ RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+ RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE(frame->bytes_recvd,
8,
- MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+ MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight));
if (frame->scanstate == STATE_LINES) {
int iFrameNext;
@@ -4178,21 +4113,21 @@ eof:
/* If next frame is ready or grabbing,
* point to it */
- iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
- if (ov511->frame[iFrameNext].grabstate == FRAME_READY
- || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
- ov511->curframe = iFrameNext;
- ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
- frame = &ov511->frame[iFrameNext];
+ iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+ if (ov->frame[iFrameNext].grabstate == FRAME_READY
+ || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+ ov->curframe = iFrameNext;
+ ov->frame[iFrameNext].scanstate = STATE_SCANNING;
+ frame = &ov->frame[iFrameNext];
} else {
if (frame->grabstate == FRAME_DONE) {
PDEBUG(4, "Frame done! congratulations");
} else {
PDEBUG(4, "Frame not ready? state = %d",
- ov511->frame[iFrameNext].grabstate);
+ ov->frame[iFrameNext].grabstate);
}
- ov511->curframe = -1;
+ ov->curframe = -1;
PDEBUG(4, "SOF dropped (no active frame)");
continue; /* Nowhere to store this frame */
}
@@ -4225,31 +4160,26 @@ check_middle:
/* Dump all data exactly as received */
if (dumppix == 2) {
frame->bytes_recvd += n;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - n,
&cdata[0], n);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else {
/* All incoming data are divided into 8-byte segments. If the
* segment contains all zero bytes, it must be skipped. These
* zero-segments allow the OV518 to mainain a constant data rate
* regardless of the effectiveness of the compression. Segments
* are aligned relative to the beginning of each isochronous
- * packet. The first segment is a header.
+ * packet. The first segment is a header (the decompressor
+ * skips it later).
*/
int b, in = 0, allzero, copied=0;
-// Decompressor expects the header
-#if 0
- if (frame->bytes_recvd == 0)
- in += 8; /* Skip header */
-#endif
-
while (in < n) {
allzero = 1;
for (b = 0; b < 8; b++) {
@@ -4263,7 +4193,7 @@ check_middle:
/* Don't copy it */
} else {
if (frame->bytes_recvd + copied + 8
- <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+ <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
memmove(frame->rawdata + frame->bytes_recvd + copied,
&cdata[in], 8);
copied += 8;
@@ -4281,43 +4211,41 @@ check_middle:
}
static void
-ov511_isoc_irq(struct urb *urb)
+ov51x_isoc_irq(struct urb *urb)
{
int len;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
if (!urb->context) {
PDEBUG(4, "no context");
return;
}
- ov511 = (struct usb_ov511 *) urb->context;
+ ov = (struct usb_ov511 *) urb->context;
- if (!ov511->dev || !ov511->user) {
+ if (!ov || !ov->dev || !ov->user) {
PDEBUG(4, "no device, or not open");
return;
}
- if (!ov511->streaming) {
+ if (!ov->streaming) {
PDEBUG(4, "hmmm... not streaming, but got interrupt");
return;
}
/* Copy the data received into our frame buffer */
- if (ov511->curframe >= 0) {
- if (ov511->bridge == BRG_OV511 ||
- ov511->bridge == BRG_OV511PLUS)
- len = ov511_move_data(ov511, urb);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- len = ov518_move_data(ov511, urb);
+ if (ov->curframe >= 0) {
+ if (ov->bclass == BCL_OV511)
+ len = ov511_move_data(ov, urb);
+ else if (ov->bclass == BCL_OV518)
+ len = ov518_move_data(ov, urb);
else
- err("Unknown bridge device (%d)", ov511->bridge);
- } else if (waitqueue_active(&ov511->wq)) {
- wake_up_interruptible(&ov511->wq);
+ err("Unknown bridge device (%d)", ov->bridge);
+ } else if (waitqueue_active(&ov->wq)) {
+ wake_up_interruptible(&ov->wq);
}
- urb->dev = ov511->dev;
+ urb->dev = ov->dev;
return;
}
@@ -4329,16 +4257,16 @@ ov511_isoc_irq(struct urb *urb)
***************************************************************************/
static int
-ov511_init_isoc(struct usb_ov511 *ov511)
+ov51x_init_isoc(struct usb_ov511 *ov)
{
struct urb *urb;
int fx, err, n, size;
PDEBUG(3, "*** Initializing capture ***");
- ov511->curframe = -1;
+ ov->curframe = -1;
- if (ov511->bridge == BRG_OV511) {
+ if (ov->bridge == BRG_OV511) {
if (cams == 1) size = 993;
else if (cams == 2) size = 513;
else if (cams == 3 || cams == 4) size = 257;
@@ -4346,7 +4274,7 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("\"cams\" parameter too high!");
return -1;
}
- } else if (ov511->bridge == BRG_OV511PLUS) {
+ } else if (ov->bridge == BRG_OV511PLUS) {
if (cams == 1) size = 961;
else if (cams == 2) size = 513;
else if (cams == 3 || cams == 4) size = 257;
@@ -4356,8 +4284,7 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("\"cams\" parameter too high!");
return -1;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (cams == 1) size = 896;
else if (cams == 2) size = 512;
else if (cams == 3 || cams == 4) size = 256;
@@ -4373,14 +4300,13 @@ ov511_init_isoc(struct usb_ov511 *ov511)
if (packetsize == -1) {
// FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_set_packet_size(ov511, 640);
+ if (ov->bclass == BCL_OV518)
+ ov51x_set_packet_size(ov, 640);
else
- ov511_set_packet_size(ov511, size);
+ ov51x_set_packet_size(ov, size);
} else {
info("Forcing packet size to %d", packetsize);
- ov511_set_packet_size(ov511, packetsize);
+ ov51x_set_packet_size(ov, packetsize);
}
for (n = 0; n < OV511_NUMSBUF; n++) {
@@ -4390,32 +4316,30 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("init isoc: usb_alloc_urb ret. NULL");
return -ENOMEM;
}
- ov511->sbuf[n].urb = urb;
- urb->dev = ov511->dev;
- urb->context = ov511;
- urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
+ ov->sbuf[n].urb = urb;
+ urb->dev = ov->dev;
+ urb->context = ov;
+ urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
urb->transfer_flags = USB_ISO_ASAP;
- urb->transfer_buffer = ov511->sbuf[n].data;
- urb->complete = ov511_isoc_irq;
+ urb->transfer_buffer = ov->sbuf[n].data;
+ urb->complete = ov51x_isoc_irq;
urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length =
- ov511->packet_size * FRAMES_PER_DESC;
+ urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset =
- ov511->packet_size * fx;
- urb->iso_frame_desc[fx].length = ov511->packet_size;
+ urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
+ urb->iso_frame_desc[fx].length = ov->packet_size;
}
}
- ov511->streaming = 1;
+ ov->streaming = 1;
- ov511->sbuf[OV511_NUMSBUF - 1].urb->next = ov511->sbuf[0].urb;
+ ov->sbuf[OV511_NUMSBUF - 1].urb->next = ov->sbuf[0].urb;
for (n = 0; n < OV511_NUMSBUF - 1; n++)
- ov511->sbuf[n].urb->next = ov511->sbuf[n+1].urb;
+ ov->sbuf[n].urb->next = ov->sbuf[n+1].urb;
for (n = 0; n < OV511_NUMSBUF; n++) {
- ov511->sbuf[n].urb->dev = ov511->dev;
- err = usb_submit_urb(ov511->sbuf[n].urb, GFP_KERNEL);
+ ov->sbuf[n].urb->dev = ov->dev;
+ err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL);
if (err)
err("init isoc: usb_submit_urb(%d) ret %d", n, err);
}
@@ -4424,51 +4348,51 @@ ov511_init_isoc(struct usb_ov511 *ov511)
}
static void
-ov511_stop_isoc(struct usb_ov511 *ov511)
+ov51x_stop_isoc(struct usb_ov511 *ov)
{
int n;
- if (!ov511->streaming || !ov511->dev)
+ if (!ov->streaming || !ov->dev)
return;
PDEBUG(3, "*** Stopping capture ***");
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->streaming = 0;
+ ov->streaming = 0;
/* Unschedule all of the iso td's */
for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
- if (ov511->sbuf[n].urb) {
- ov511->sbuf[n].urb->next = NULL;
- usb_unlink_urb(ov511->sbuf[n].urb);
- usb_free_urb(ov511->sbuf[n].urb);
- ov511->sbuf[n].urb = NULL;
+ if (ov->sbuf[n].urb) {
+ ov->sbuf[n].urb->next = NULL;
+ usb_unlink_urb(ov->sbuf[n].urb);
+ usb_free_urb(ov->sbuf[n].urb);
+ ov->sbuf[n].urb = NULL;
}
}
}
static int
-ov511_new_frame(struct usb_ov511 *ov511, int framenum)
+ov51x_new_frame(struct usb_ov511 *ov, int framenum)
{
struct ov511_frame *frame;
int newnum;
- PDEBUG(4, "ov511->curframe = %d, framenum = %d", ov511->curframe,
- framenum);
- if (!ov511->dev)
+ PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
+
+ if (!ov->dev)
return -1;
/* If we're not grabbing a frame right now and the other frame is */
/* ready to be grabbed into, then use it instead */
- if (ov511->curframe == -1) {
+ if (ov->curframe == -1) {
newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
- if (ov511->frame[newnum].grabstate == FRAME_READY)
+ if (ov->frame[newnum].grabstate == FRAME_READY)
framenum = newnum;
} else
return 0;
- frame = &ov511->frame[framenum];
+ frame = &ov->frame[framenum];
PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
frame->width, frame->height);
@@ -4477,16 +4401,16 @@ ov511_new_frame(struct usb_ov511 *ov511, int framenum)
frame->scanstate = STATE_SCANNING;
frame->snapshot = 0;
- ov511->curframe = framenum;
+ ov->curframe = framenum;
/* Make sure it's not too big */
- if (frame->width > ov511->maxwidth)
- frame->width = ov511->maxwidth;
+ if (frame->width > ov->maxwidth)
+ frame->width = ov->maxwidth;
frame->width &= ~7L; /* Multiple of 8 */
- if (frame->height > ov511->maxheight)
- frame->height = ov511->maxheight;
+ if (frame->height > ov->maxheight)
+ frame->height = ov->maxheight;
frame->height &= ~3L; /* Multiple of 4 */
@@ -4498,84 +4422,86 @@ ov511_new_frame(struct usb_ov511 *ov511, int framenum)
* Buffer management
*
***************************************************************************/
+
static int
-ov511_alloc(struct usb_ov511 *ov511)
+ov51x_alloc(struct usb_ov511 *ov)
{
int i;
- int w = ov511->maxwidth;
- int h = ov511->maxheight;
+ const int w = ov->maxwidth;
+ const int h = ov->maxheight;
+ const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
+ const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
- del_timer(&ov511->buf_timer);
+ if (ov->buf_state == BUF_PEND_DEALLOC) {
+ ov->buf_state = BUF_ALLOCATED;
+ del_timer(&ov->buf_timer);
}
- if (ov511->buf_state == BUF_ALLOCATED)
+ if (ov->buf_state == BUF_ALLOCATED)
goto out;
- ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- if (!ov511->fbuf)
+ ov->fbuf = rvmalloc(data_bufsize);
+ if (!ov->fbuf)
goto error;
- ov511->rawfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
- if (!ov511->rawfbuf) {
- rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ ov->rawfbuf = vmalloc(raw_bufsize);
+ if (!ov->rawfbuf) {
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- memset(ov511->rawfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+ memset(ov->rawfbuf, 0, raw_bufsize);
- ov511->tempfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
- if (!ov511->tempfbuf) {
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
- rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ ov->tempfbuf = vmalloc(raw_bufsize);
+ if (!ov->tempfbuf) {
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- memset(ov511->tempfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+ memset(ov->tempfbuf, 0, raw_bufsize);
for (i = 0; i < OV511_NUMSBUF; i++) {
- ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
+ ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ov511->sbuf[i].data) {
+ if (!ov->sbuf[i].data) {
while (--i) {
- kfree(ov511->sbuf[i].data);
- ov511->sbuf[i].data = NULL;
+ kfree(ov->sbuf[i].data);
+ ov->sbuf[i].data = NULL;
}
- vfree(ov511->tempfbuf);
- ov511->tempfbuf = NULL;
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
- rvfree(ov511->fbuf,
- OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ vfree(ov->tempfbuf);
+ ov->tempfbuf = NULL;
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data);
+ PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE(w, h);
- ov511->frame[i].rawdata = ov511->rawfbuf
+ ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
+ ov->frame[i].rawdata = ov->rawfbuf
+ i * MAX_RAW_DATA_SIZE(w, h);
- ov511->frame[i].tempdata = ov511->tempfbuf
+ ov->frame[i].tempdata = ov->tempfbuf
+ i * MAX_RAW_DATA_SIZE(w, h);
- PDEBUG(4, "frame[%d] @ %p", i, ov511->frame[i].data);
+ PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
}
- ov511->buf_state = BUF_ALLOCATED;
+ ov->buf_state = BUF_ALLOCATED;
out:
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
return 0;
error:
- ov511->buf_state = BUF_NOT_ALLOCATED;
- up(&ov511->buf_lock);
+ ov->buf_state = BUF_NOT_ALLOCATED;
+ up(&ov->buf_lock);
PDEBUG(4, "errored");
return -ENOMEM;
}
@@ -4586,206 +4512,211 @@ error:
* them if you explicitly free them somewhere else!
*/
static void
-ov511_do_dealloc(struct usb_ov511 *ov511)
+ov51x_do_dealloc(struct usb_ov511 *ov)
{
int i;
PDEBUG(4, "entered");
- if (ov511->fbuf) {
- rvfree(ov511->fbuf, OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
- ov511->fbuf = NULL;
+ if (ov->fbuf) {
+ rvfree(ov->fbuf, OV511_NUMFRAMES
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
+ ov->fbuf = NULL;
}
- if (ov511->rawfbuf) {
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
+ if (ov->rawfbuf) {
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
}
- if (ov511->tempfbuf) {
- vfree(ov511->tempfbuf);
- ov511->tempfbuf = NULL;
+ if (ov->tempfbuf) {
+ vfree(ov->tempfbuf);
+ ov->tempfbuf = NULL;
}
for (i = 0; i < OV511_NUMSBUF; i++) {
- if (ov511->sbuf[i].data) {
- kfree(ov511->sbuf[i].data);
- ov511->sbuf[i].data = NULL;
+ if (ov->sbuf[i].data) {
+ kfree(ov->sbuf[i].data);
+ ov->sbuf[i].data = NULL;
}
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].data = NULL;
- ov511->frame[i].rawdata = NULL;
- ov511->frame[i].tempdata = NULL;
+ ov->frame[i].data = NULL;
+ ov->frame[i].rawdata = NULL;
+ ov->frame[i].tempdata = NULL;
}
PDEBUG(4, "buffer memory deallocated");
- ov511->buf_state = BUF_NOT_ALLOCATED;
+ ov->buf_state = BUF_NOT_ALLOCATED;
PDEBUG(4, "leaving");
}
static void
-ov511_buf_callback(unsigned long data)
+ov51x_buf_callback(unsigned long data)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)data;
+ struct usb_ov511 *ov = (struct usb_ov511 *)data;
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
- if (ov511->buf_state == BUF_PEND_DEALLOC)
- ov511_do_dealloc(ov511);
+ if (ov->buf_state == BUF_PEND_DEALLOC)
+ ov51x_do_dealloc(ov);
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
}
static void
-ov511_dealloc(struct usb_ov511 *ov511, int now)
+ov51x_dealloc(struct usb_ov511 *ov, int now)
{
- struct timer_list *bt = &(ov511->buf_timer);
+ struct timer_list *bt = &(ov->buf_timer);
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later");
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
+ if (ov->buf_state == BUF_PEND_DEALLOC) {
+ ov->buf_state = BUF_ALLOCATED;
del_timer(bt);
}
if (now)
- ov511_do_dealloc(ov511);
+ ov51x_do_dealloc(ov);
else {
- ov511->buf_state = BUF_PEND_DEALLOC;
+ ov->buf_state = BUF_PEND_DEALLOC;
init_timer(bt);
- bt->function = ov511_buf_callback;
- bt->data = (unsigned long)ov511;
+ bt->function = ov51x_buf_callback;
+ bt->data = (unsigned long)ov;
bt->expires = jiffies + buf_timeout * HZ;
add_timer(bt);
}
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
}
/****************************************************************************
*
- * V4L API
+ * V4L 1 API
*
***************************************************************************/
static int
-ov511_open(struct video_device *vdev, int flags)
+ov51x_v4l1_open(struct video_device *vdev, int flags)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
int err, i;
PDEBUG(4, "opening");
- down(&ov511->lock);
+ down(&ov->lock);
err = -EBUSY;
- if (ov511->user)
+ if (ov->user)
goto out;
err = -ENOMEM;
- if (ov511_alloc(ov511))
+ if (ov51x_alloc(ov))
goto out;
- ov511->sub_flag = 0;
+ ov->sub_flag = 0;
/* In case app doesn't set them... */
- if (ov51x_set_default_params(ov511) < 0)
+ if (ov51x_set_default_params(ov) < 0)
goto out;
/* Make sure frames are reset */
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].grabstate = FRAME_UNUSED;
- ov511->frame[i].bytes_read = 0;
+ ov->frame[i].grabstate = FRAME_UNUSED;
+ ov->frame[i].bytes_read = 0;
}
/* If compression is on, make sure now that a
* decompressor can be loaded */
- if (ov511->compress && !ov511->decomp_ops) {
- err = ov51x_request_decompressor(ov511);
- if (err)
+ if (ov->compress && !ov->decomp_ops) {
+ err = request_decompressor(ov);
+ if (err && !dumppix)
goto out;
}
- err = ov511_init_isoc(ov511);
+ err = ov51x_init_isoc(ov);
if (err) {
- ov511_dealloc(ov511, 0);
+ ov51x_dealloc(ov, 0);
goto out;
}
- ov511->user++;
+ ov->user++;
- if (ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 1);
+ if (ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 1);
out:
- up(&ov511->lock);
-
+ up(&ov->lock);
return err;
}
static void
-ov511_close(struct video_device *dev)
+ov51x_v4l1_close(struct video_device *vdev)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
+ struct usb_ov511 *ov = vdev->priv;
PDEBUG(4, "ov511_close");
- down(&ov511->lock);
+ down(&ov->lock);
- ov511->user--;
- ov511_stop_isoc(ov511);
+ ov->user--;
+ ov51x_stop_isoc(ov);
- ov51x_release_decompressor(ov511);
+ release_decompressor(ov);
- if (ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
- if (ov511->dev)
- ov511_dealloc(ov511, 0);
+ if (ov->dev)
+ ov51x_dealloc(ov, 0);
- up(&ov511->lock);
+ up(&ov->lock);
/* Device unplugged while open. Only a minimum of unregistration is done
* here; the disconnect callback already did the rest. */
- if (!ov511->dev) {
- ov511_dealloc(ov511, 1);
- video_unregister_device(&ov511->vdev);
- kfree(ov511);
- ov511 = NULL;
+ if (!ov->dev) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
+
+ ov51x_dealloc(ov, 1);
+ video_unregister_device(&ov->vdev);
+ kfree(ov);
+ ov = NULL;
}
}
static int
-ov511_init_done(struct video_device *vdev)
+ov51x_v4l1_init_done(struct video_device *vdev)
{
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- create_proc_ov511_cam((struct usb_ov511 *)vdev);
+ create_proc_ov511_cam(vdev->priv);
#endif
return 0;
}
static long
-ov511_write(struct video_device *vdev, const char *buf,
- unsigned long count, int noblock)
+ov51x_v4l1_write(struct video_device *vdev, const char *buf,
+ unsigned long count, int noblock)
{
return -EINVAL;
}
/* Do not call this function directly! */
static int
-ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
+ void *arg)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
+ struct usb_ov511 *ov = vdev->priv;
PDEBUG(5, "IOCtl: 0x%X", cmd);
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
switch (cmd) {
@@ -4797,20 +4728,20 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&b, 0, sizeof(b));
sprintf(b.name, "%s USB Camera",
- ov511->bridge == BRG_OV511 ? "OV511" :
- ov511->bridge == BRG_OV511PLUS ? "OV511+" :
- ov511->bridge == BRG_OV518 ? "OV518" :
- ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+ ov->bridge == BRG_OV511 ? "OV511" :
+ ov->bridge == BRG_OV511PLUS ? "OV511+" :
+ ov->bridge == BRG_OV518 ? "OV518" :
+ ov->bridge == BRG_OV518PLUS ? "OV518+" :
"unknown");
b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
- if (ov511->has_tuner)
+ if (ov->has_tuner)
b.type |= VID_TYPE_TUNER;
- b.channels = ov511->num_inputs;
- b.audios = ov511->has_audio_proc ? 1:0;
- b.maxwidth = ov511->maxwidth;
- b.maxheight = ov511->maxheight;
- b.minwidth = ov511->minwidth;
- b.minheight = ov511->minheight;
+ b.channels = ov->num_inputs;
+ b.audios = ov->has_audio_proc ? 1:0;
+ b.maxwidth = ov->maxwidth;
+ b.maxheight = ov->maxheight;
+ b.minwidth = ov->minwidth;
+ b.minheight = ov->minheight;
if (copy_to_user(arg, &b, sizeof(b)))
return -EFAULT;
@@ -4826,18 +4757,18 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- if ((unsigned)(v.channel) >= ov511->num_inputs) {
+ if ((unsigned)(v.channel) >= ov->num_inputs) {
err("Invalid channel (%d)", v.channel);
return -EINVAL;
}
- v.norm = ov511->norm;
- v.type = (ov511->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
- v.flags = (ov511->has_tuner) ? VIDEO_VC_TUNER : 0;
- v.flags |= (ov511->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
-// v.flags |= (ov511->has_decoder) ? VIDEO_VC_NORM : 0;
- v.tuners = (ov511->has_tuner) ? 1:0;
- decoder_get_input_name(ov511, v.channel, v.name);
+ v.norm = ov->norm;
+ v.type = (ov->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
+ v.flags = (ov->has_tuner) ? VIDEO_VC_TUNER : 0;
+ v.flags |= (ov->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
+// v.flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
+ v.tuners = (ov->has_tuner) ? 1:0;
+ decoder_get_input_name(ov, v.channel, v.name);
if (copy_to_user(arg, &v, sizeof(v)))
return -EFAULT;
@@ -4855,7 +4786,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EFAULT;
/* Make sure it's not a camera */
- if (!ov511->has_decoder) {
+ if (!ov->has_decoder) {
if (v.channel == 0)
return 0;
else
@@ -4870,16 +4801,16 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if ((unsigned)(v.channel) >= ov511->num_inputs) {
+ if ((unsigned)(v.channel) >= ov->num_inputs) {
err("Invalid channel (%d)", v.channel);
return -EINVAL;
}
- err = decoder_set_input(ov511, v.channel);
+ err = decoder_set_input(ov, v.channel);
if (err)
return err;
- err = decoder_set_norm(ov511, v.norm);
+ err = decoder_set_norm(ov, v.norm);
if (err)
return err;
@@ -4893,7 +4824,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&p, 0, sizeof(p));
- if (sensor_get_picture(ov511, &p))
+ if (sensor_get_picture(ov, &p))
return -EIO;
if (copy_to_user(arg, &p, sizeof(p)))
@@ -4911,10 +4842,10 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&p, arg, sizeof(p)))
return -EFAULT;
- if (!ov511_get_depth(p.palette))
+ if (!get_depth(p.palette))
return -EINVAL;
- if (sensor_set_picture(ov511, &p))
+ if (sensor_set_picture(ov, &p))
return -EIO;
if (force_palette && p.palette != force_palette) {
@@ -4923,23 +4854,22 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
}
// FIXME: Format should be independent of frames
- if (p.palette != ov511->frame[0].format) {
+ if (p.palette != ov->frame[0].format) {
PDEBUG(4, "Detected format change");
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- mode_init_regs(ov511, ov511->frame[0].width,
- ov511->frame[0].height, p.palette,
- ov511->sub_flag);
+ mode_init_regs(ov, ov->frame[0].width,
+ ov->frame[0].height, p.palette, ov->sub_flag);
}
PDEBUG(4, "Setting depth=%d, palette=%d", p.depth, p.palette);
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].depth = p.depth;
- ov511->frame[i].format = p.palette;
+ ov->frame[i].depth = p.depth;
+ ov->frame[i].format = p.palette;
}
return 0;
@@ -4952,7 +4882,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&vf, arg, sizeof(vf)))
return -EFAULT;
- ov511->sub_flag = vf;
+ ov->sub_flag = vf;
return 0;
}
case VIDIOCSCAPTURE:
@@ -4980,10 +4910,10 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (vc.height == 0)
vc.height = 16;
- ov511->subx = vc.x;
- ov511->suby = vc.y;
- ov511->subw = vc.width;
- ov511->subh = vc.height;
+ ov->subx = vc.x;
+ ov->suby = vc.y;
+ ov->subw = vc.width;
+ ov->subh = vc.height;
return 0;
}
@@ -5003,25 +4933,25 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
if (vw.clipcount)
return -EINVAL;
- if (vw.height != ov511->maxheight)
+ if (vw.height != ov->maxheight)
return -EINVAL;
- if (vw.width != ov511->maxwidth)
+ if (vw.width != ov->maxwidth)
return -EINVAL;
#endif
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- result = mode_init_regs(ov511, vw.width, vw.height,
- ov511->frame[0].format, ov511->sub_flag);
+ result = mode_init_regs(ov, vw.width, vw.height,
+ ov->frame[0].format, ov->sub_flag);
if (result < 0)
return result;
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].width = vw.width;
- ov511->frame[i].height = vw.height;
+ ov->frame[i].width = vw.width;
+ ov->frame[i].height = vw.height;
}
return 0;
@@ -5033,8 +4963,8 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&vw, 0, sizeof(vw));
vw.x = 0; /* FIXME */
vw.y = 0;
- vw.width = ov511->frame[0].width;
- vw.height = ov511->frame[0].height;
+ vw.width = ov->frame[0].width;
+ vw.height = ov->frame[0].height;
vw.flags = 30;
PDEBUG(4, "VIDIOCGWIN: %dx%d", vw.width, vw.height);
@@ -5053,13 +4983,13 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&vm, 0, sizeof(vm));
vm.size = OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
vm.frames = OV511_NUMFRAMES;
vm.offsets[0] = 0;
for (i = 1; i < OV511_NUMFRAMES; i++) {
vm.offsets[i] = vm.offsets[i-1]
- + MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+ + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
}
if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
@@ -5079,7 +5009,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
PDEBUG(4, "frame: %d, size: %dx%d, format: %d",
vm.frame, vm.width, vm.height, vm.format);
- depth = ov511_get_depth(vm.format);
+ depth = get_depth(vm.format);
if (!depth) {
err("VIDIOCMCAPTURE: invalid format (%d)", vm.format);
return -EINVAL;
@@ -5090,13 +5020,13 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if (vm.width > ov511->maxwidth
- || vm.height > ov511->maxheight) {
+ if (vm.width > ov->maxwidth
+ || vm.height > ov->maxheight) {
err("VIDIOCMCAPTURE: requested dimensions too big");
return -EINVAL;
}
- if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING) {
+ if (ov->frame[vm.frame].grabstate == FRAME_GRABBING) {
PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
return -EBUSY;
}
@@ -5106,38 +5036,38 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if ((ov511->frame[vm.frame].width != vm.width) ||
- (ov511->frame[vm.frame].height != vm.height) ||
- (ov511->frame[vm.frame].format != vm.format) ||
- (ov511->frame[vm.frame].sub_flag != ov511->sub_flag) ||
- (ov511->frame[vm.frame].depth != depth)) {
+ if ((ov->frame[vm.frame].width != vm.width) ||
+ (ov->frame[vm.frame].height != vm.height) ||
+ (ov->frame[vm.frame].format != vm.format) ||
+ (ov->frame[vm.frame].sub_flag != ov->sub_flag) ||
+ (ov->frame[vm.frame].depth != depth)) {
PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- ret = mode_init_regs(ov511, vm.width, vm.height,
- vm.format, ov511->sub_flag);
+ ret = mode_init_regs(ov, vm.width, vm.height,
+ vm.format, ov->sub_flag);
#if 0
if (ret < 0) {
PDEBUG(1, "Got error while initializing regs ");
return ret;
}
#endif
- ov511->frame[vm.frame].width = vm.width;
- ov511->frame[vm.frame].height = vm.height;
- ov511->frame[vm.frame].format = vm.format;
- ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
- ov511->frame[vm.frame].depth = depth;
+ ov->frame[vm.frame].width = vm.width;
+ ov->frame[vm.frame].height = vm.height;
+ ov->frame[vm.frame].format = vm.format;
+ ov->frame[vm.frame].sub_flag = ov->sub_flag;
+ ov->frame[vm.frame].depth = depth;
}
/* Mark it as ready */
- ov511->frame[vm.frame].grabstate = FRAME_READY;
+ ov->frame[vm.frame].grabstate = FRAME_READY;
PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", vm.frame);
- return ov511_new_frame(ov511, vm.frame);
+ return ov51x_new_frame(ov, vm.frame);
}
case VIDIOCSYNC:
{
@@ -5152,7 +5082,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- frame = &ov511->frame[fnum];
+ frame = &ov->frame[fnum];
PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
frame->grabstate);
@@ -5164,7 +5094,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
case FRAME_GRABBING:
case FRAME_ERROR:
redo:
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
rc = wait_event_interruptible(frame->wq,
@@ -5177,15 +5107,15 @@ redo:
if (frame->grabstate == FRAME_ERROR) {
int ret;
- if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+ if ((ret = ov51x_new_frame(ov, fnum)) < 0)
return ret;
goto redo;
}
/* Fall through */
case FRAME_DONE:
- if (ov511->snap_enabled && !frame->snapshot) {
+ if (ov->snap_enabled && !frame->snapshot) {
int ret;
- if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+ if ((ret = ov51x_new_frame(ov, fnum)) < 0)
return ret;
goto redo;
}
@@ -5194,13 +5124,13 @@ redo:
/* Reset the hardware snapshot button */
/* FIXME - Is this the best place for this? */
- if ((ov511->snap_enabled) && (frame->snapshot)) {
+ if ((ov->snap_enabled) && (frame->snapshot)) {
frame->snapshot = 0;
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
}
/* Decompression, format conversion, etc... */
- ov511_postprocess(ov511, frame);
+ ov51x_postprocess(ov, frame);
break;
} /* end switch */
@@ -5229,7 +5159,7 @@ redo:
memset(&vu, 0, sizeof(vu));
- vu.video = ov511->vdev.minor; /* Video minor */
+ vu.video = ov->vdev.minor; /* Video minor */
vu.vbi = VIDEO_NO_UNIT; /* VBI minor */
vu.radio = VIDEO_NO_UNIT; /* Radio minor */
vu.audio = VIDEO_NO_UNIT; /* Audio minor */
@@ -5249,7 +5179,7 @@ redo:
if (copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- if (!ov511->has_tuner || v.tuner) // Only tuner 0
+ if (!ov->has_tuner || v.tuner) // Only tuner 0
return -EINVAL;
strcpy(v.name, "Television");
@@ -5263,7 +5193,7 @@ redo:
v.mode = 0; /* FIXME: Not sure what this is yet */
v.signal = 0xFFFF; /* unknown */
- call_i2c_clients(ov511, cmd, &v);
+ call_i2c_clients(ov, cmd, &v);
if (copy_to_user(arg, &v, sizeof(v)))
return -EFAULT;
@@ -5281,7 +5211,7 @@ redo:
return -EFAULT;
/* Only no or one tuner for now */
- if (!ov511->has_tuner || v.tuner)
+ if (!ov->has_tuner || v.tuner)
return -EINVAL;
/* and it only has certain valid modes */
@@ -5290,21 +5220,21 @@ redo:
v.mode != VIDEO_MODE_SECAM) return -EOPNOTSUPP;
/* Is this right/necessary? */
- err = decoder_set_norm(ov511, v.mode);
+ err = decoder_set_norm(ov, v.mode);
if (err)
return err;
- call_i2c_clients(ov511, cmd, &v);
+ call_i2c_clients(ov, cmd, &v);
return 0;
}
case VIDIOCGFREQ:
{
- unsigned long v = ov511->freq;
+ unsigned long v = ov->freq;
PDEBUG(4, "VIDIOCGFREQ");
- if (!ov511->has_tuner)
+ if (!ov->has_tuner)
return -EINVAL;
#if 0
/* FIXME: this is necessary for testing */
@@ -5319,7 +5249,7 @@ redo:
{
unsigned long v;
- if (!ov511->has_tuner)
+ if (!ov->has_tuner)
return -EINVAL;
if (copy_from_user(&v, arg, sizeof(v)))
@@ -5327,8 +5257,8 @@ redo:
PDEBUG(4, "VIDIOCSFREQ: %lx", v);
- ov511->freq = v;
- call_i2c_clients(ov511, cmd, &v);
+ ov->freq = v;
+ call_i2c_clients(ov, cmd, &v);
return 0;
}
@@ -5347,29 +5277,29 @@ redo:
}
static int
-ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
{
int rc;
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
- rc = ov511_ioctl_internal(vdev, cmd, arg);
+ rc = ov51x_v4l1_ioctl_internal(vdev, cmd, arg);
- up(&ov511->lock);
+ up(&ov->lock);
return rc;
}
static inline long
-ov511_read(struct video_device *vdev, char *buf, unsigned long count,
- int noblock)
+ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count,
+ int noblock)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
int i, rc = 0, frmx = -1;
struct ov511_frame *frame;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
@@ -5379,16 +5309,16 @@ ov511_read(struct video_device *vdev, char *buf, unsigned long count,
goto error;
}
- if (!ov511->dev) {
+ if (!ov->dev) {
rc = -EIO;
goto error;
}
// FIXME: Only supports two frames
/* See if a frame is completed, then use it. */
- if (ov511->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
+ if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
frmx = 0;
- else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
+ else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
frmx = 1;
/* If nonblocking we return immediately */
@@ -5400,24 +5330,24 @@ ov511_read(struct video_device *vdev, char *buf, unsigned long count,
/* If no FRAME_DONE, look for a FRAME_GRABBING state. */
/* See if a frame is in process (grabbing), then use it. */
if (frmx == -1) {
- if (ov511->frame[0].grabstate == FRAME_GRABBING)
+ if (ov->frame[0].grabstate == FRAME_GRABBING)
frmx = 0;
- else if (ov511->frame[1].grabstate == FRAME_GRABBING)
+ else if (ov->frame[1].grabstate == FRAME_GRABBING)
frmx = 1;
}
/* If no frame is active, start one. */
if (frmx == -1) {
- if ((rc = ov511_new_frame(ov511, frmx = 0))) {
- err("read: ov511_new_frame error");
+ if ((rc = ov51x_new_frame(ov, frmx = 0))) {
+ err("read: ov51x_new_frame error");
goto error;
}
}
- frame = &ov511->frame[frmx];
+ frame = &ov->frame[frmx];
restart:
- if (!ov511->dev) {
+ if (!ov->dev) {
rc = -EIO;
goto error;
}
@@ -5436,9 +5366,9 @@ restart:
if (frame->grabstate == FRAME_ERROR) {
frame->bytes_read = 0;
- err("** ick! ** Errored frame %d", ov511->curframe);
- if (ov511_new_frame(ov511, frmx)) {
- err("read: ov511_new_frame error");
+ err("** ick! ** Errored frame %d", ov->curframe);
+ if (ov51x_new_frame(ov, frmx)) {
+ err("read: ov51x_new_frame error");
goto error;
}
goto restart;
@@ -5446,25 +5376,25 @@ restart:
/* Repeat until we get a snapshot frame */
- if (ov511->snap_enabled)
+ if (ov->snap_enabled)
PDEBUG(4, "Waiting snapshot frame");
- if (ov511->snap_enabled && !frame->snapshot) {
+ if (ov->snap_enabled && !frame->snapshot) {
frame->bytes_read = 0;
- if ((rc = ov511_new_frame(ov511, frmx))) {
- err("read: ov511_new_frame error");
+ if ((rc = ov51x_new_frame(ov, frmx))) {
+ err("read: ov51x_new_frame error");
goto error;
}
goto restart;
}
/* Clear the snapshot */
- if (ov511->snap_enabled && frame->snapshot) {
+ if (ov->snap_enabled && frame->snapshot) {
frame->snapshot = 0;
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
}
/* Decompression, format conversion, etc... */
- ov511_postprocess(ov511, frame);
+ ov51x_postprocess(ov, frame);
PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
frame->bytes_read,
@@ -5496,48 +5426,49 @@ restart:
// FIXME: Only supports two frames
/* Mark it as available to be used again. */
- ov511->frame[frmx].grabstate = FRAME_UNUSED;
- if ((rc = ov511_new_frame(ov511, !frmx))) {
- err("ov511_new_frame returned error");
+ ov->frame[frmx].grabstate = FRAME_UNUSED;
+ if ((rc = ov51x_new_frame(ov, !frmx))) {
+ err("ov51x_new_frame returned error");
goto error;
}
}
PDEBUG(4, "read finished, returning %ld (sweet)", count);
- up(&ov511->lock);
+ up(&ov->lock);
return count;
error:
- up(&ov511->lock);
+ up(&ov->lock);
return rc;
}
static int
-ov511_mmap(struct vm_area_struct *vma, struct video_device *vdev, const char *adr, unsigned long size)
+ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
+ const char *adr, unsigned long size)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
unsigned long start = (unsigned long)adr;
unsigned long page, pos;
- if (ov511->dev == NULL)
+ if (ov->dev == NULL)
return -EIO;
PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
if (size > (((OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight)
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
return -EINVAL;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
- pos = (unsigned long)ov511->fbuf;
+ pos = (unsigned long)ov->fbuf;
while (size > 0) {
page = kvirt_to_pa(pos);
if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- up(&ov511->lock);
+ up(&ov->lock);
return -EAGAIN;
}
start += PAGE_SIZE;
@@ -5548,31 +5479,31 @@ ov511_mmap(struct vm_area_struct *vma, struct video_device *vdev, const char *ad
size = 0;
}
- up(&ov511->lock);
+ up(&ov->lock);
return 0;
}
-static struct video_device ov511_template = {
+static struct video_device vdev_template = {
owner: THIS_MODULE,
name: "OV511 USB Camera",
type: VID_TYPE_CAPTURE,
hardware: VID_HARDWARE_OV511,
- open: ov511_open,
- close: ov511_close,
- read: ov511_read,
- write: ov511_write,
- ioctl: ov511_ioctl,
- mmap: ov511_mmap,
- initialize: ov511_init_done,
+ open: ov51x_v4l1_open,
+ close: ov51x_v4l1_close,
+ read: ov51x_v4l1_read,
+ write: ov51x_v4l1_write,
+ ioctl: ov51x_v4l1_ioctl,
+ mmap: ov51x_v4l1_mmap,
+ initialize: ov51x_v4l1_init_done,
};
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
static int
-ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long ularg)
{
struct proc_dir_entry *pde;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
void *arg = (void *) ularg;
int rc;
@@ -5580,11 +5511,11 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (!pde)
return -ENOENT;
- ov511 = (struct usb_ov511 *) pde->data;
- if (!ov511)
+ ov = (struct usb_ov511 *) pde->data;
+ if (!ov)
return -ENODEV;
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
/* Should we pass through standard V4L IOCTLs? */
@@ -5609,19 +5540,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
- rc = sensor_get_brightness(ov511, &(opt.val));
+ rc = sensor_get_brightness(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_SAT:
- rc = sensor_get_saturation(ov511, &(opt.val));
+ rc = sensor_get_saturation(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_HUE:
- rc = sensor_get_hue(ov511, &(opt.val));
+ rc = sensor_get_hue(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_CONTRAST:
- rc = sensor_get_contrast(ov511, &(opt.val));
+ rc = sensor_get_contrast(ov, &(opt.val));
if (rc) return rc;
break;
default:
@@ -5643,19 +5574,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
- rc = sensor_set_brightness(ov511, opt.val);
+ rc = sensor_set_brightness(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_SAT:
- rc = sensor_set_saturation(ov511, opt.val);
+ rc = sensor_set_saturation(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_HUE:
- rc = sensor_set_hue(ov511, opt.val);
+ rc = sensor_set_hue(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_CONTRAST:
- rc = sensor_set_contrast(ov511, opt.val);
+ rc = sensor_set_contrast(ov, opt.val);
if (rc) return rc;
break;
default:
@@ -5674,19 +5605,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
- opt.val = ov511->lightfreq;
+ opt.val = ov->lightfreq;
break;
case OV511_UIOPT_BFILTER:
- opt.val = ov511->bandfilt;
+ opt.val = ov->bandfilt;
break;
case OV511_UIOPT_LED:
- opt.val = ov511->led_policy;
+ opt.val = ov->led_policy;
break;
case OV511_UIOPT_DEBUG:
opt.val = debug;
break;
case OV511_UIOPT_COMPRESS:
- opt.val = ov511->compress;
+ opt.val = ov->compress;
break;
default:
err("Invalid get int option number");
@@ -5707,20 +5638,20 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
- rc = sensor_set_light_freq(ov511, opt.val);
+ rc = sensor_set_light_freq(ov, opt.val);
if (rc) return rc;
break;
case OV511_UIOPT_BFILTER:
- rc = sensor_set_banding_filter(ov511, opt.val);
+ rc = sensor_set_banding_filter(ov, opt.val);
if (rc) return rc;
break;
case OV511_UIOPT_LED:
if (opt.val <= 2) {
- ov511->led_policy = opt.val;
- if (ov511->led_policy == LED_OFF)
- ov51x_led_control(ov511, 0);
- else if (ov511->led_policy == LED_ON)
- ov51x_led_control(ov511, 1);
+ ov->led_policy = opt.val;
+ if (ov->led_policy == LED_OFF)
+ ov51x_led_control(ov, 0);
+ else if (ov->led_policy == LED_ON)
+ ov51x_led_control(ov, 1);
} else {
return -EINVAL;
}
@@ -5732,14 +5663,12 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return -EINVAL;
break;
case OV511_UIOPT_COMPRESS:
- ov511->compress = opt.val;
- if (ov511->compress) {
- if (ov511->bridge == BRG_OV511 ||
- ov511->bridge == BRG_OV511PLUS)
- ov511_init_compression(ov511);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov518_init_compression(ov511);
+ ov->compress = opt.val;
+ if (ov->compress) {
+ if (ov->bclass == BCL_OV511)
+ ov511_init_compression(ov);
+ else if (ov->bclass == BCL_OV518)
+ ov518_init_compression(ov);
}
break;
default:
@@ -5756,7 +5685,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_from_user(&w, arg, sizeof(w)))
return -EFAULT;
- return ov51x_i2c_write_slave(ov511, w.slave, w.reg, w.value,
+ return i2c_w_slave(ov, w.slave, w.reg, w.value,
w.mask);
}
case OV511IOC_RI2C:
@@ -5766,7 +5695,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_from_user(&r, arg, sizeof(r)))
return -EFAULT;
- rc = ov51x_i2c_read_slave(ov511, r.slave, r.reg);
+ rc = i2c_r_slave(ov, r.slave, r.reg);
if (rc < 0)
return rc;
@@ -5795,7 +5724,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* the same register settings as the OV7610, since they are very similar.
*/
static int
-ov7xx0_configure(struct usb_ov511 *ov511)
+ov7xx0_configure(struct usb_ov511 *ov)
{
int i, success;
int rc;
@@ -5912,16 +5841,15 @@ ov7xx0_configure(struct usb_ov511 *ov511)
PDEBUG(4, "starting configuration");
/* This looks redundant, but is necessary for WebCam 3 */
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
return -1;
- if (ov51x_init_ov_sensor(ov511) >= 0) {
+ if (init_ov_sensor(ov) >= 0) {
PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
} else {
/* Reset the 76xx */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -1;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -1;
/* Wait for it to initialize */
schedule_timeout(1 + 150 * HZ / 1000);
@@ -5929,10 +5857,8 @@ ov7xx0_configure(struct usb_ov511 *ov511)
i = 0;
success = 0;
while (i <= i2c_detect_tries) {
- if ((ov51x_i2c_read(ov511,
- OV7610_REG_ID_HIGH) == 0x7F) &&
- (ov51x_i2c_read(ov511,
- OV7610_REG_ID_LOW) == 0xA2)) {
+ if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
success = 1;
break;
} else {
@@ -5956,17 +5882,17 @@ ov7xx0_configure(struct usb_ov511 *ov511)
}
/* Detect sensor (sub)type */
- rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+ rc = i2c_r(ov, OV7610_REG_COM_I);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 3) == 3) {
info("Sensor is an OV7610");
- ov511->sensor = SEN_OV7610;
+ ov->sensor = SEN_OV7610;
} else if ((rc & 3) == 1) {
/* I don't know what's different about the 76BE yet */
- if (ov51x_i2c_read(ov511, 0x15) & 1)
+ if (i2c_r(ov, 0x15) & 1)
info("Sensor is an OV7620AE");
else
info("Sensor is an OV76BE");
@@ -5974,48 +5900,48 @@ ov7xx0_configure(struct usb_ov511 *ov511)
/* OV511+ will return all zero isoc data unless we
* configure the sensor as a 7620. Someone needs to
* find the exact reg. setting that causes this. */
- if (ov511->bridge == BRG_OV511PLUS) {
+ if (ov->bridge == BRG_OV511PLUS) {
info("Enabling 511+/7620AE workaround");
- ov511->sensor = SEN_OV7620;
+ ov->sensor = SEN_OV7620;
} else {
- ov511->sensor = SEN_OV7620AE;
+ ov->sensor = SEN_OV7620AE;
}
} else if ((rc & 3) == 0) {
info("Sensor is an OV7620");
- ov511->sensor = SEN_OV7620;
+ ov->sensor = SEN_OV7620;
} else {
err("Unknown image sensor version: %d", rc & 3);
return -1;
}
- if (ov511->sensor == SEN_OV7620) {
+ if (ov->sensor == SEN_OV7620) {
PDEBUG(4, "Writing 7620 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm7620))
+ if (write_regvals(ov, aRegvalsNorm7620))
return -1;
} else {
PDEBUG(4, "Writing 7610 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm7610))
+ if (write_regvals(ov, aRegvalsNorm7610))
return -1;
}
/* Set sensor-specific vars */
- ov511->maxwidth = 640;
- ov511->maxheight = 480;
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 640;
+ ov->maxheight = 480;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
return 0;
}
/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
static int
-ov6xx0_configure(struct usb_ov511 *ov511)
+ov6xx0_configure(struct usb_ov511 *ov)
{
int rc;
@@ -6141,7 +6067,7 @@ ov6xx0_configure(struct usb_ov511 *ov511)
PDEBUG(4, "starting sensor configuration");
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
err("Failed to read sensor ID. You might not have an OV6xx0,");
err("or it may be not responding. Report this to " EMAIL);
return -1;
@@ -6150,50 +6076,44 @@ ov6xx0_configure(struct usb_ov511 *ov511)
}
/* Detect sensor (sub)type */
- rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+ rc = i2c_r(ov, OV7610_REG_COM_I);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 3) == 0) {
info("Sensor is an OV6630");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
} else if ((rc & 3) == 1) {
info("Sensor is an OV6620");
- ov511->sensor = SEN_OV6620;
+ ov->sensor = SEN_OV6620;
} else if ((rc & 3) == 2) {
info("Sensor is an OV6630AE");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
} else if ((rc & 3) == 3) {
info("Sensor is an OV6630AF");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
}
/* Set sensor-specific vars */
- if (ov511->sensor == SEN_OV6620) {
- ov511->maxwidth = 352;
- ov511->maxheight = 288;
- } else {
- /* 352x288 not working with OV518 yet */
- ov511->maxwidth = 320;
- ov511->maxheight = 240;
- }
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 352;
+ ov->maxheight = 288;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
- if (ov511->sensor == SEN_OV6620) {
+ if (ov->sensor == SEN_OV6620) {
PDEBUG(4, "Writing 6x20 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm6x20))
+ if (write_regvals(ov, aRegvalsNorm6x20))
return -1;
} else {
PDEBUG(4, "Writing 6x30 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm6x30))
+ if (write_regvals(ov, aRegvalsNorm6x30))
return -1;
}
@@ -6202,13 +6122,13 @@ ov6xx0_configure(struct usb_ov511 *ov511)
/* This initializes the KS0127 and KS0127B video decoders. */
static int
-ks0127_configure(struct usb_ov511 *ov511)
+ks0127_configure(struct usb_ov511 *ov)
{
int rc;
// FIXME: I don't know how to sync or reset it yet
#if 0
- if (ov51x_init_ks_sensor(ov511) < 0) {
+ if (ov51x_init_ks_sensor(ov) < 0) {
err("Failed to initialize the KS0127");
return -1;
} else {
@@ -6217,21 +6137,21 @@ ks0127_configure(struct usb_ov511 *ov511)
#endif
/* Detect decoder subtype */
- rc = ov51x_i2c_read(ov511, 0x00);
+ rc = i2c_r(ov, 0x00);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if (rc & 0x08) {
- rc = ov51x_i2c_read(ov511, 0x3d);
+ rc = i2c_r(ov, 0x3d);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 0x0f) == 0) {
info("Sensor is a KS0127");
- ov511->sensor = SEN_KS0127;
+ ov->sensor = SEN_KS0127;
} else if ((rc & 0x0f) == 9) {
info("Sensor is a KS0127B Rev. A");
- ov511->sensor = SEN_KS0127B;
+ ov->sensor = SEN_KS0127B;
}
} else {
err("Error: Sensor is an unsupported KS0122");
@@ -6239,16 +6159,16 @@ ks0127_configure(struct usb_ov511 *ov511)
}
/* Set sensor-specific vars */
- ov511->maxwidth = 640;
- ov511->maxheight = 480;
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 640;
+ ov->maxheight = 480;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
/* This device is not supported yet. Bail out now... */
err("This sensor is not supported yet.");
@@ -6261,7 +6181,6 @@ ks0127_configure(struct usb_ov511 *ov511)
static int
saa7111a_configure(struct usb_ov511 *ov511)
{
- struct usb_device *dev = ov511->dev;
int rc;
/* Since there is no register reset command, all registers must be
@@ -6296,7 +6215,7 @@ saa7111a_configure(struct usb_ov511 *ov511)
// FIXME: I don't know how to sync or reset it yet
#if 0
- if (ov51x_init_saa_sensor(ov511) < 0) {
+ if (ov51x_init_saa_sensor(ov) < 0) {
err("Failed to initialize the SAA7111A");
return -1;
} else {
@@ -6323,12 +6242,12 @@ saa7111a_configure(struct usb_ov511 *ov511)
ov511->hue = 32768;
PDEBUG(4, "Writing SAA7111A registers");
- if (ov511_write_regvals(ov511, aRegvalsNormSAA7111A))
+ if (write_regvals(ov511, aRegvalsNormSAA7111A))
return -1;
/* Detect version of decoder. This must be done after writing the
* initial regs or the decoder will lock up. */
- rc = ov51x_i2c_read(ov511, 0x00);
+ rc = i2c_r(ov511, 0x00);
if (rc < 0) {
err("Error detecting sensor version");
@@ -6341,8 +6260,8 @@ saa7111a_configure(struct usb_ov511 *ov511)
// FIXME: Fix this for OV518(+)
/* Latch to negative edge of clock. Otherwise, we get incorrect
* colors and jitter in the digital signal. */
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS)
- ov511_reg_write(dev, 0x11, 0x00);
+ if (ov511->bclass == BCL_OV511)
+ reg_w(ov511, 0x11, 0x00);
else
warn("SAA7111A not yet supported with OV518/OV518+");
@@ -6351,144 +6270,138 @@ saa7111a_configure(struct usb_ov511 *ov511)
/* This initializes the OV511/OV511+ and the sensor */
static int
-ov511_configure(struct usb_ov511 *ov511)
+ov511_configure(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int i;
static struct ov511_regvals aRegvalsInit511[] = {
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3d },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
{ OV511_DONE_BUS, 0x0, 0x00},
};
static struct ov511_regvals aRegvalsNorm511[] = {
- { OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f },
- { OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
- { OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+ { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
+ { OV511_REG_BUS, R511_COMP_EN, 0x00 },
+ { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
static struct ov511_regvals aRegvalsNorm511Plus[] = {
- { OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0xff },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0xff },
- { OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
- { OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+ { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
+ { OV511_REG_BUS, R511_COMP_EN, 0x00 },
+ { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
PDEBUG(4, "");
- ov511->customid = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
- if (ov511->customid < 0) {
+ ov->customid = reg_r(ov, R511_SYS_CUST_ID);
+ if (ov->customid < 0) {
err("Unable to read camera bridge registers");
goto error;
}
- ov511->desc = -1;
- PDEBUG (1, "CustomID = %d", ov511->customid);
+ ov->desc = -1;
+ PDEBUG (1, "CustomID = %d", ov->customid);
for (i = 0; clist[i].id >= 0; i++) {
- if (ov511->customid == clist[i].id) {
+ if (ov->customid == clist[i].id) {
info("model: %s", clist[i].description);
- ov511->desc = i;
+ ov->desc = i;
break;
}
}
if (clist[i].id == -1) {
- err("Camera type (%d) not recognized", ov511->customid);
+ err("Camera type (%d) not recognized", ov->customid);
err("Please notify " EMAIL " of the name,");
err("manufacturer, model, and this number of your camera.");
err("Also include the output of the detection process.");
}
if (clist[i].id == 6) { /* USB Life TV (NTSC) */
- ov511->tuner_type = 8; /* Temic 4036FY5 3X 1981 */
+ ov->tuner_type = 8; /* Temic 4036FY5 3X 1981 */
}
- if (ov511_write_regvals(ov511, aRegvalsInit511)) goto error;
+ if (write_regvals(ov, aRegvalsInit511)) goto error;
- if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
/* The OV511+ has undocumented bits in the flow control register.
* Setting it to 0xff fixes the corruption with moving objects. */
- if (ov511->bridge == BRG_OV511) {
- if (ov511_write_regvals(ov511, aRegvalsNorm511)) goto error;
- } else if (ov511->bridge == BRG_OV511PLUS) {
- if (ov511_write_regvals(ov511, aRegvalsNorm511Plus)) goto error;
+ if (ov->bridge == BRG_OV511) {
+ if (write_regvals(ov, aRegvalsNorm511)) goto error;
+ } else if (ov->bridge == BRG_OV511PLUS) {
+ if (write_regvals(ov, aRegvalsNorm511Plus)) goto error;
} else {
err("Invalid bridge");
}
- if (ov511_init_compression(ov511)) goto error;
+ if (ov511_init_compression(ov)) goto error;
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->snap_enabled = snapshot;
+ ov->snap_enabled = snapshot;
/* Test for 7xx0 */
PDEBUG(3, "Testing for 0V7xx0");
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for 6xx0 */
PDEBUG(3, "Testing for 0V6xx0");
- ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
- OV6xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV6xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for 8xx0 */
PDEBUG(3, "Testing for 0V8xx0");
- ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
- OV8xx0_I2C_READ_ID))
+ ov->primary_i2c_slave = OV8xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV8xx0_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for SAA7111A */
PDEBUG(3, "Testing for SAA7111A");
- ov511->primary_i2c_slave = SAA7111A_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, SAA7111A_I2C_WRITE_ID,
- SAA7111A_I2C_READ_ID))
+ ov->primary_i2c_slave = SAA7111A_SID;
+ if (ov51x_set_slave_ids(ov, SAA7111A_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x0d, 0x00) < 0) {
+ if (i2c_w(ov, 0x0d, 0x00) < 0) {
/* Test for KS0127 */
PDEBUG(3, "Testing for KS0127");
- ov511->primary_i2c_slave = KS0127_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, KS0127_I2C_WRITE_ID,
- KS0127_I2C_READ_ID))
+ ov->primary_i2c_slave = KS0127_SID;
+ if (ov51x_set_slave_ids(ov, KS0127_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x10, 0x00) < 0) {
+ if (i2c_w(ov, 0x10, 0x00) < 0) {
err("Can't determine sensor slave IDs");
goto error;
} else {
- if(ks0127_configure(ov511) < 0) {
+ if (ks0127_configure(ov) < 0) {
err("Failed to configure KS0127");
goto error;
}
}
} else {
- if(saa7111a_configure(ov511) < 0) {
+ if (saa7111a_configure(ov) < 0) {
err("Failed to configure SAA7111A");
goto error;
}
@@ -6498,13 +6411,13 @@ ov511_configure(struct usb_ov511 *ov511)
goto error;
}
} else {
- if(ov6xx0_configure(ov511) < 0) {
+ if (ov6xx0_configure(ov) < 0) {
err("Failed to configure OV6xx0");
goto error;
}
}
} else {
- if(ov7xx0_configure(ov511) < 0) {
+ if (ov7xx0_configure(ov) < 0) {
err("Failed to configure OV7xx0");
goto error;
}
@@ -6520,96 +6433,90 @@ error:
/* This initializes the OV518/OV518+ and the sensor */
static int
-ov518_configure(struct usb_ov511 *ov511)
+ov518_configure(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
-
static struct ov511_regvals aRegvalsInit518[] = {
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x40 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3e },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x00 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, 0x46, 0x00 },
- { OV511_REG_BUS, 0x5d, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, 0x46, 0x00 },
+ { OV511_REG_BUS, 0x5d, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00},
};
/* New values, based on Windows driver. Since what they do is not
* known yet, this may be incorrect. */
static struct ov511_regvals aRegvalsNorm518[] = {
- { OV511_REG_BUS, 0x52, 0x02 }, /* Reset snapshot */
- { OV511_REG_BUS, 0x52, 0x01 }, /* Enable snapshot */
- { OV511_REG_BUS, 0x31, 0x0f },
- { OV511_REG_BUS, 0x5d, 0x03 },
- { OV511_REG_BUS, 0x24, 0x9f },
- { OV511_REG_BUS, 0x25, 0x90 },
- { OV511_REG_BUS, 0x20, 0x00 }, /* Was 0x08 */
- { OV511_REG_BUS, 0x51, 0x04 },
- { OV511_REG_BUS, 0x71, 0x19 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
+ { OV511_REG_BUS, 0x31, 0x0f },
+ { OV511_REG_BUS, 0x5d, 0x03 },
+ { OV511_REG_BUS, 0x24, 0x9f },
+ { OV511_REG_BUS, 0x25, 0x90 },
+ { OV511_REG_BUS, 0x20, 0x00 }, /* Was 0x08 */
+ { OV511_REG_BUS, 0x51, 0x04 },
+ { OV511_REG_BUS, 0x71, 0x19 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
PDEBUG(4, "");
/* First 5 bits of custom ID reg are a revision ID on OV518 */
- info("Device revision %d",
- 0x1F & ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID));
+ info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
- if (ov511_write_regvals(ov511, aRegvalsInit518)) goto error;
+ if (write_regvals(ov, aRegvalsInit518)) goto error;
/* Set LED GPIO pin to output mode */
- if (ov511_reg_write_mask(dev, 0x57,0x00, 0x02) < 0) goto error;
+ if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) goto error;
/* LED is off by default with OV518; have to explicitly turn it on */
- if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
else
- ov51x_led_control(ov511, 1);
+ ov51x_led_control(ov, 1);
/* Don't require compression if dumppix is enabled; otherwise it's
* required. OV518 has no uncompressed mode, to save RAM. */
- if (!dumppix && !ov511->compress) {
- ov511->compress = 1;
+ if (!dumppix && !ov->compress) {
+ ov->compress = 1;
warn("Compression required with OV518...enabling");
}
- if (ov511_write_regvals(ov511, aRegvalsNorm518)) goto error;
+ if (write_regvals(ov, aRegvalsNorm518)) goto error;
- if (ov511_reg_write(dev, 0x2f,0x80) < 0) goto error;
+ if (reg_w(ov, 0x2f, 0x80) < 0) goto error;
- if (ov518_init_compression(ov511)) goto error;
+ if (ov518_init_compression(ov)) goto error;
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->snap_enabled = snapshot;
+ ov->snap_enabled = snapshot;
/* Test for 76xx */
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
goto error;
/* The OV518 must be more aggressive about sensor detection since
* I2C write will never fail if the sensor is not present. We have
* to try to initialize the sensor to detect its presence */
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
/* Test for 6xx0 */
- ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
- OV6xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV6xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
goto error;
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
/* Test for 8xx0 */
- ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
- OV8xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV8xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
goto error;
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
err("Can't determine sensor slave IDs");
goto error;
} else {
@@ -6617,21 +6524,25 @@ ov518_configure(struct usb_ov511 *ov511)
goto error;
}
} else {
- if (ov6xx0_configure(ov511) < 0) {
+ if (ov6xx0_configure(ov) < 0) {
err("Failed to configure OV6xx0");
goto error;
}
}
} else {
- if (ov7xx0_configure(ov511) < 0) {
+ if (ov7xx0_configure(ov) < 0) {
err("Failed to configure OV7xx0");
goto error;
}
}
+ // FIXME: Sizes > 320x240 are not working yet
+ ov->maxwidth = 320;
+ ov->maxheight = 240;
+
// The OV518 cannot go as low as the sensor can
- ov511->minwidth = 160;
- ov511->minheight = 120;
+ ov->minwidth = 160;
+ ov->minheight = 120;
return 0;
@@ -6648,12 +6559,13 @@ error:
*
***************************************************************************/
+/* 2.2.x compatibility */
static void *
ov51x_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
{
struct usb_interface_descriptor *interface;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
int i;
int registered = 0;
@@ -6671,57 +6583,54 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
if (interface->bInterfaceSubClass != 0x00)
return NULL;
- /* Since code below may sleep, we use this as a lock */
- MOD_INC_USE_COUNT;
-
- if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {
- err("couldn't kmalloc ov511 struct");
- goto error_unlock;
+ if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
+ err("couldn't kmalloc ov struct");
+ goto error_out;
}
- memset(ov511, 0, sizeof(*ov511));
+ memset(ov, 0, sizeof(*ov));
- ov511->dev = dev;
- ov511->iface = interface->bInterfaceNumber;
- ov511->led_policy = led;
- ov511->compress = compress;
- ov511->lightfreq = lightfreq;
- ov511->num_inputs = 1; /* Video decoder init functs. change this */
- ov511->stop_during_set = !fastset;
- ov511->tuner_type = tuner;
- ov511->backlight = backlight;
+ ov->dev = dev;
+ ov->iface = interface->bInterfaceNumber;
+ ov->led_policy = led;
+ ov->compress = compress;
+ ov->lightfreq = lightfreq;
+ ov->num_inputs = 1; /* Video decoder init functs. change this */
+ ov->stop_during_set = !fastset;
+ ov->tuner_type = tuner;
+ ov->backlight = backlight;
- ov511->auto_brt = autobright;
- ov511->auto_gain = autogain;
- ov511->auto_exp = autoexp;
+ ov->auto_brt = autobright;
+ ov->auto_gain = autogain;
+ ov->auto_exp = autoexp;
switch (dev->descriptor.idProduct) {
case PROD_OV511:
info("USB OV511 camera found");
- ov511->bridge = BRG_OV511;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511;
+ ov->bclass = BCL_OV511;
break;
case PROD_OV511PLUS:
info("USB OV511+ camera found");
- ov511->bridge = BRG_OV511PLUS;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511PLUS;
+ ov->bclass = BCL_OV511;
break;
case PROD_OV518:
info("USB OV518 camera found");
- ov511->bridge = BRG_OV518;
- ov511->bclass = BCL_OV518;
+ ov->bridge = BRG_OV518;
+ ov->bclass = BCL_OV518;
break;
case PROD_OV518PLUS:
info("USB OV518+ camera found");
- ov511->bridge = BRG_OV518PLUS;
- ov511->bclass = BCL_OV518;
+ ov->bridge = BRG_OV518PLUS;
+ ov->bclass = BCL_OV518;
break;
case PROD_ME2CAM:
if (dev->descriptor.idVendor != VEND_MATTEL)
goto error;
info("Intel Play Me2Cam (OV511+) found");
- ov511->bridge = BRG_OV511PLUS;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511PLUS;
+ ov->bclass = BCL_OV511;
break;
default:
err("Unknown product ID 0x%x", dev->descriptor.idProduct);
@@ -6733,47 +6642,53 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
if (force_rgb)
info("data format set to RGB");
- init_waitqueue_head(&ov511->wq);
+ init_waitqueue_head(&ov->wq);
+
+ init_MUTEX(&ov->lock); /* to 1 == available */
+ init_MUTEX(&ov->buf_lock);
+ init_MUTEX(&ov->param_lock);
+ init_MUTEX(&ov->i2c_lock);
+ init_MUTEX(&ov->cbuf_lock);
- init_MUTEX(&ov511->lock); /* to 1 == available */
- init_MUTEX(&ov511->buf_lock);
- init_MUTEX(&ov511->param_lock);
- init_MUTEX(&ov511->i2c_lock);
- ov511->buf_state = BUF_NOT_ALLOCATED;
+ ov->buf_state = BUF_NOT_ALLOCATED;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
- if (ov518_configure(ov511) < 0)
+ /* Must be kmalloc()'ed, for DMA accessibility */
+ ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
+ if (!ov->cbuf)
+ goto error;
+
+ if (ov->bclass == BCL_OV518) {
+ if (ov518_configure(ov) < 0)
goto error;
} else {
- if (ov511_configure(ov511) < 0)
+ if (ov511_configure(ov) < 0)
goto error;
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].framenum = i;
- init_waitqueue_head(&ov511->frame[i].wq);
+ ov->frame[i].framenum = i;
+ init_waitqueue_head(&ov->frame[i].wq);
}
/* Unnecessary? (This is done on open(). Need to make sure variables
* are properly initialized without this before removing it, though). */
- if (ov51x_set_default_params(ov511) < 0)
+ if (ov51x_set_default_params(ov) < 0)
goto error;
#ifdef OV511_DEBUG
if (dump_bridge)
- ov511_dump_regs(dev);
+ ov511_dump_regs(ov);
#endif
- memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));
- ov511->vdev.priv = ov511;
+ memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
+ ov->vdev.priv = ov;
for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
/* Minor 0 cannot be specified; assume user wants autodetect */
if (unit_video[i] == 0)
break;
- if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER,
+ if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER,
unit_video[i]) >= 0) {
registered = 1;
break;
@@ -6782,35 +6697,40 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
/* Use the next available one */
if (!registered &&
- video_register_device(&ov511->vdev, VFL_TYPE_GRABBER, -1) < 0) {
+ video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
err("video_register_device failed");
goto error;
}
- info("Device registered on minor %d", ov511->vdev.minor);
+ info("Device registered on minor %d", ov->vdev.minor);
- MOD_DEC_USE_COUNT;
- return ov511;
+ return ov;
error:
err("Camera initialization failed");
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
/* Safe to call even if entry doesn't exist */
- destroy_proc_ov511_cam(ov511);
+ destroy_proc_ov511_cam(ov);
#endif
+ if (ov->cbuf) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
+ }
+
usb_driver_release_interface(&ov511_driver,
- &dev->actconfig->interface[ov511->iface]);
+ &dev->actconfig->interface[ov->iface]);
error_dealloc:
- if (ov511) {
- kfree(ov511);
- ov511 = NULL;
+ if (ov) {
+ kfree(ov);
+ ov = NULL;
}
-error_unlock:
- MOD_DEC_USE_COUNT;
+error_out:
return NULL;
}
@@ -6818,62 +6738,64 @@ error_unlock:
static void
ov51x_disconnect(struct usb_device *dev, void *ptr)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr;
+ struct usb_ov511 *ov = (struct usb_ov511 *) ptr;
int n;
- MOD_INC_USE_COUNT;
-
PDEBUG(3, "");
/* We don't want people trying to open up the device */
- if (!ov511->user)
- video_unregister_device(&ov511->vdev);
+ if (!ov->user)
+ video_unregister_device(&ov->vdev);
else
PDEBUG(3, "Device open...deferring video_unregister_device");
for (n = 0; n < OV511_NUMFRAMES; n++)
- ov511->frame[n].grabstate = FRAME_ERROR;
+ ov->frame[n].grabstate = FRAME_ERROR;
- ov511->curframe = -1;
+ ov->curframe = -1;
/* This will cause the process to request another frame */
for (n = 0; n < OV511_NUMFRAMES; n++)
- if (waitqueue_active(&ov511->frame[n].wq))
- wake_up_interruptible(&ov511->frame[n].wq);
- if (waitqueue_active(&ov511->wq))
- wake_up_interruptible(&ov511->wq);
+ if (waitqueue_active(&ov->frame[n].wq))
+ wake_up_interruptible(&ov->frame[n].wq);
+ if (waitqueue_active(&ov->wq))
+ wake_up_interruptible(&ov->wq);
- ov511->streaming = 0;
+ ov->streaming = 0;
/* Unschedule all of the iso td's */
for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
- if (ov511->sbuf[n].urb) {
- ov511->sbuf[n].urb->next = NULL;
- usb_unlink_urb(ov511->sbuf[n].urb);
- usb_free_urb(ov511->sbuf[n].urb);
- ov511->sbuf[n].urb = NULL;
+ if (ov->sbuf[n].urb) {
+ ov->sbuf[n].urb->next = NULL;
+ usb_unlink_urb(ov->sbuf[n].urb);
+ usb_free_urb(ov->sbuf[n].urb);
+ ov->sbuf[n].urb = NULL;
}
}
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- destroy_proc_ov511_cam(ov511);
+ destroy_proc_ov511_cam(ov);
#endif
usb_driver_release_interface(&ov511_driver,
- &ov511->dev->actconfig->interface[ov511->iface]);
- ov511->dev = NULL;
+ &ov->dev->actconfig->interface[ov->iface]);
+ ov->dev = NULL;
/* Free the memory */
- if (ov511 && !ov511->user) {
- ov511_dealloc(ov511, 1);
- kfree(ov511);
- ov511 = NULL;
- }
+ if (ov && !ov->user) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
- MOD_DEC_USE_COUNT;
+ ov51x_dealloc(ov, 1);
+ kfree(ov);
+ ov = NULL;
+ }
}
static struct usb_driver ov511_driver = {
+ owner: THIS_MODULE,
name: "ov511",
id_table: device_table,
probe: ov51x_probe,
diff --git a/drivers/usb/ov511.h b/drivers/usb/ov511.h
index 0bdf18885253..4e6a9fa6a262 100644
--- a/drivers/usb/ov511.h
+++ b/drivers/usb/ov511.h
@@ -9,11 +9,11 @@
#define OV511_DEBUG /* Turn on debug messages */
#ifdef OV511_DEBUG
-# define PDEBUG(level, fmt, args...) \
-if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
- ## args)
+ #define PDEBUG(level, fmt, args...) \
+ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt,\
+ __LINE__ , ## args)
#else
-# define PDEBUG(level, fmt, args...) do {} while(0)
+ #define PDEBUG(level, fmt, args...) do {} while(0)
#endif
/* This macro restricts an int variable to an inclusive range */
@@ -36,98 +36,105 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
#define VEND_MATTEL 0x0813
#define PROD_ME2CAM 0x0002
+/* --------------------------------- */
+/* OV51x REGISTER MNEMONICS */
+/* --------------------------------- */
+
/* Camera interface register numbers */
-#define OV511_REG_CAMERA_DELAY_MODE 0x10
-#define OV511_REG_CAMERA_EDGE_MODE 0x11
-#define OV511_REG_CAMERA_CLAMPED_PIXEL_NUM 0x12
-#define OV511_REG_CAMERA_CLAMPED_LINE_NUM 0x13
-#define OV511_REG_CAMERA_PIXEL_DIVISOR 0x14
-#define OV511_REG_CAMERA_LINE_DIVISOR 0x15
-#define OV511_REG_CAMERA_DATA_INPUT_SELECT 0x16
-#define OV511_REG_CAMERA_RESERVED_LINE_MODE 0x17
-#define OV511_REG_CAMERA_BITMASK 0x18
+#define R511_CAM_DELAY 0x10
+#define R511_CAM_EDGE 0x11
+#define R511_CAM_PXCNT 0x12
+#define R511_CAM_LNCNT 0x13
+#define R511_CAM_PXDIV 0x14
+#define R511_CAM_LNDIV 0x15
+#define R511_CAM_UV_EN 0x16
+#define R511_CAM_LINE_MODE 0x17
+#define R511_CAM_OPTS 0x18
/* Snapshot mode camera interface register numbers */
-#define OV511_REG_SNAP_CAPTURED_FRAME 0x19
-#define OV511_REG_SNAP_CLAMPED_PIXEL_NUM 0x1A
-#define OV511_REG_SNAP_CLAMPED_LINE_NUM 0x1B
-#define OV511_REG_SNAP_PIXEL_DIVISOR 0x1C
-#define OV511_REG_SNAP_LINE_DIVISOR 0x1D
-#define OV511_REG_SNAP_DATA_INPUT_SELECT 0x1E
-#define OV511_REG_SNAP_BITMASK 0x1F
+#define R511_SNAP_FRAME 0x19
+#define R511_SNAP_PXCNT 0x1A
+#define R511_SNAP_LNCNT 0x1B
+#define R511_SNAP_PXDIV 0x1C
+#define R511_SNAP_LNDIV 0x1D
+#define R511_SNAP_UV_EN 0x1E
+#define R511_SNAP_OPTS 0x1F
/* DRAM register numbers */
-#define OV511_REG_DRAM_ENABLE_FLOW_CONTROL 0x20
-#define OV511_REG_DRAM_READ_CYCLE_PREDICT 0x21
-#define OV511_REG_DRAM_MANUAL_READ_CYCLE 0x22
-#define OV511_REG_DRAM_REFRESH_COUNTER 0x23
+#define R511_DRAM_FLOW_CTL 0x20
+#define R511_DRAM_ARCP 0x21
+#define R511_DRAM_MRC 0x22
+#define R511_DRAM_RFC 0x23
/* ISO FIFO register numbers */
-#define OV511_REG_FIFO_PACKET_SIZE 0x30
-#define OV511_REG_FIFO_BITMASK 0x31
-
-/* PIO register numbers */
-#define OV511_REG_PIO_BITMASK 0x38
-#define OV511_REG_PIO_DATA_PORT 0x39
-#define OV511_REG_PIO_BIST 0x3E
-
-/* I2C register numbers */
-#define OV511_REG_I2C_CONTROL 0x40
-#define OV518_REG_I2C_CONTROL 0x47 /* OV518(+) only */
-#define OV511_REG_I2C_SLAVE_ID_WRITE 0x41
-#define OV511_REG_I2C_SUB_ADDRESS_3_BYTE 0x42
-#define OV511_REG_I2C_SUB_ADDRESS_2_BYTE 0x43
-#define OV511_REG_I2C_SLAVE_ID_READ 0x44
-#define OV511_REG_I2C_DATA_PORT 0x45
-#define OV511_REG_I2C_CLOCK_PRESCALER 0x46
-#define OV511_REG_I2C_TIME_OUT_COUNTER 0x47
-
-/* I2C snapshot register numbers */
-#define OV511_REG_I2C_SNAP_SUB_ADDRESS 0x48
-#define OV511_REG_I2C_SNAP_DATA_PORT 0x49
-
-/* System control register numbers */
-#define OV511_REG_SYSTEM_RESET 0x50
-#define OV511_RESET_UDC 0x01
-#define OV511_RESET_I2C 0x02
-#define OV511_RESET_FIFO 0x04
-#define OV511_RESET_OMNICE 0x08
-#define OV511_RESET_DRAM_INTF 0x10
-#define OV511_RESET_CAMERA_INTF 0x20
-#define OV511_RESET_OV511 0x40
-#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
-#define OV511_RESET_ALL 0x7F
-#define OV511_REG_SYSTEM_CLOCK_DIVISOR 0x51
-#define OV511_REG_SYSTEM_SNAPSHOT 0x52
-#define OV511_REG_SYSTEM_INIT 0x53
-#define OV511_REG_SYSTEM_PWR_CLK 0x54 /* OV511+/OV518(+) only */
-#define OV511_REG_SYSTEM_LED_CTL 0x55 /* OV511+ only */
-#define OV518_REG_GPIO_IN 0x55 /* OV518(+) only */
-#define OV518_REG_GPIO_OUT 0x56 /* OV518(+) only */
-#define OV518_REG_GPIO_CTL 0x57 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_IN 0x58 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_POLARITY 0x5a /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_EN 0x5b /* OV518(+) only */
-#define OV518_REG_GPIO_RESET 0x5c /* OV518(+) only */
-#define OV511_REG_SYSTEM_USER_DEFINED 0x5E
-#define OV511_REG_SYSTEM_CUSTOM_ID 0x5F
-
-/* OmniCE register numbers */
-#define OV511_OMNICE_PREDICTION_HORIZ_Y 0x70
-#define OV511_OMNICE_PREDICTION_HORIZ_UV 0x71
-#define OV511_OMNICE_PREDICTION_VERT_Y 0x72
-#define OV511_OMNICE_PREDICTION_VERT_UV 0x73
-#define OV511_OMNICE_QUANTIZATION_HORIZ_Y 0x74
-#define OV511_OMNICE_QUANTIZATION_HORIZ_UV 0x75
-#define OV511_OMNICE_QUANTIZATION_VERT_Y 0x76
-#define OV511_OMNICE_QUANTIZATION_VERT_UV 0x77
-#define OV511_OMNICE_ENABLE 0x78
-#define OV511_OMNICE_LUT_ENABLE 0x79
-#define OV511_OMNICE_Y_LUT_BEGIN 0x80
-#define OV511_OMNICE_Y_LUT_END 0x9F
-#define OV511_OMNICE_UV_LUT_BEGIN 0xA0
-#define OV511_OMNICE_UV_LUT_END 0xBF
+#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
+#define R511_FIFO_OPTS 0x31
+
+/* Parallel IO register numbers */
+#define R511_PIO_OPTS 0x38
+#define R511_PIO_DATA 0x39
+#define R511_PIO_BIST 0x3E
+#define R518_GPIO_IN 0x55 /* OV518(+) only */
+#define R518_GPIO_OUT 0x56 /* OV518(+) only */
+#define R518_GPIO_CTL 0x57 /* OV518(+) only */
+#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */
+#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
+#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */
+#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */
+#define R518_GPIO_RESET 0x5c /* OV518(+) only */
+
+/* I2C registers */
+#define R511_I2C_CTL 0x40
+#define R518_I2C_CTL 0x47 /* OV518(+) only */
+#define R51x_I2C_W_SID 0x41
+#define R51x_I2C_SADDR_3 0x42
+#define R51x_I2C_SADDR_2 0x43
+#define R51x_I2C_R_SID 0x44
+#define R51x_I2C_DATA 0x45
+#define R51x_I2C_CLOCK 0x46
+#define R51x_I2C_TIMEOUT 0x47
+
+/* I2C snapshot registers */
+#define R511_SI2C_SADDR_3 0x48
+#define R511_SI2C_DATA 0x49
+
+/* System control registers */
+#define R51x_SYS_RESET 0x50
+ /* Reset type definitions */
+#define OV511_RESET_UDC 0x01
+#define OV511_RESET_I2C 0x02
+#define OV511_RESET_FIFO 0x04
+#define OV511_RESET_OMNICE 0x08
+#define OV511_RESET_DRAM 0x10
+#define OV511_RESET_CAM_INT 0x20
+#define OV511_RESET_OV511 0x40
+#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
+#define OV511_RESET_ALL 0x7F
+
+#define R511_SYS_CLOCK_DIV 0x51
+#define R51x_SYS_SNAP 0x52
+#define R51x_SYS_INIT 0x53
+#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */
+#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
+#define R511_SYS_USER 0x5E
+#define R511_SYS_CUST_ID 0x5F
+
+/* OmniCE (compression) registers */
+#define R511_COMP_PHY 0x70
+#define R511_COMP_PHUV 0x71
+#define R511_COMP_PVY 0x72
+#define R511_COMP_PVUV 0x73
+#define R511_COMP_QHY 0x74
+#define R511_COMP_QHUV 0x75
+#define R511_COMP_QVY 0x76
+#define R511_COMP_QVUV 0x77
+#define R511_COMP_EN 0x78
+#define R511_COMP_LUT_EN 0x79
+#define R511_COMP_LUT_BEGIN 0x80
+
+/* --------------------------------- */
+/* ALTERNATE NUMBERS */
+/* --------------------------------- */
/* Alternate numbers for various max packet sizes (OV511 only) */
#define OV511_ALT_SIZE_992 0
@@ -159,6 +166,10 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
#define OV518_ALT_SIZE_768 6
#define OV518_ALT_SIZE_896 7
+/* --------------------------------- */
+/* OV7610 REGISTER MNEMONICS */
+/* --------------------------------- */
+
/* OV7610 registers */
#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
#define OV7610_REG_BLUE 0x01 /* blue channel balance */
@@ -210,26 +221,27 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
/* 36-37 reserved */
#define OV7610_REG_COM_K 0x38 /* misc registers */
+/* --------------------------------- */
+/* I2C ADDRESSES */
+/* --------------------------------- */
+
+#define OV7xx0_SID 0x42
+#define OV6xx0_SID 0xC0
+#define OV8xx0_SID 0xA0
+#define KS0127_SID 0xD8
+#define SAA7111A_SID 0x48
+
+/* --------------------------------- */
+/* MISCELLANEOUS DEFINES */
+/* --------------------------------- */
+
+#define I2C_CLOCK_PRESCALER 0x03
+
#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */
-#define FRAME_SIZE_PER_DESC 993 /* FIXME - Deprecated */
#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */
#define PIXELS_PER_SEG 256 /* Pixels per segment */
-#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
-
-/* I2C addresses */
-#define OV7xx0_I2C_WRITE_ID 0x42
-#define OV7xx0_I2C_READ_ID 0x43
-#define OV6xx0_I2C_WRITE_ID 0xC0
-#define OV6xx0_I2C_READ_ID 0xC1
-#define OV8xx0_I2C_WRITE_ID 0xA0
-#define OV8xx0_I2C_READ_ID 0xA1
-#define KS0127_I2C_WRITE_ID 0xD8
-#define KS0127_I2C_READ_ID 0xD9
-#define SAA7111A_I2C_WRITE_ID 0x48
-#define SAA7111A_I2C_READ_ID 0x49
-
-#define OV511_I2C_CLOCK_PRESCALER 0x03
+#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
/* Bridge types */
enum {
@@ -429,11 +441,14 @@ struct ov51x_decomp_ops {
#define OV511_NUMFRAMES 2
#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
-#error "OV511_NUMFRAMES is too high"
+ #error "OV511_NUMFRAMES is too high"
#endif
#define OV511_NUMSBUF 2
+/* Control transfers use up to 4 bytes */
+#define OV511_CBUF_SIZE 4
+
struct usb_ov511 {
struct video_device vdev;
@@ -535,6 +550,10 @@ struct usb_ov511 {
/* I2C interface to kernel */
struct semaphore i2c_lock; /* Protect I2C controller regs */
unsigned char primary_i2c_slave; /* I2C write id of sensor */
+
+ /* Control transaction stuff */
+ unsigned char *cbuf; /* Buffer for payload */
+ struct semaphore cbuf_lock;
};
struct cam_list {
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index e668cf3f15e4..368f2158065b 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -4,7 +4,7 @@
* Maintainer: Johannes Erdfelt <johannes@erdfelt.com>
*
* (C) Copyright 1999 Linus Torvalds
- * (C) Copyright 1999-2001 Johannes Erdfelt, johannes@erdfelt.com
+ * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
* (C) Copyright 1999 Randy Dunlap
* (C) Copyright 1999 Georg Acher, acher@in.tum.de
* (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
@@ -240,10 +240,10 @@ static void uhci_remove_td(struct uhci *uhci, struct uhci_td *td)
unsigned long flags;
/* If it's not inserted, don't remove it */
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (td->frame == -1 && list_empty(&td->fl_list))
- return;
+ goto out;
- spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) {
if (list_empty(&td->fl_list)) {
uhci->fl->frame[td->frame] = td->link;
@@ -268,6 +268,7 @@ static void uhci_remove_td(struct uhci *uhci, struct uhci_td *td)
list_del_init(&td->fl_list);
td->frame = -1;
+out:
spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
}
@@ -358,6 +359,9 @@ static void uhci_free_qh(struct uhci *uhci, struct uhci_qh *qh)
pci_pool_free(uhci->qh_pool, qh, qh->dma_handle);
}
+/*
+ * MUST be called with uhci->frame_list_lock acquired
+ */
static void _uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct urb *urb)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -417,11 +421,10 @@ static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
return;
/* Only go through the hoops if it's actually linked in */
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (!list_empty(&qh->list)) {
qh->urbp = NULL;
- spin_lock_irqsave(&uhci->frame_list_lock, flags);
-
pqh = list_entry(qh->list.prev, struct uhci_qh, list);
if (pqh->urbp) {
@@ -444,9 +447,8 @@ static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
qh->element = qh->link = UHCI_PTR_TERM;
list_del_init(&qh->list);
-
- spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
}
+ spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
spin_lock_irqsave(&uhci->qh_remove_list_lock, flags);
@@ -658,6 +660,9 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci *uhci, struct urb *urb)
return urbp;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -667,6 +672,9 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
list_add_tail(&td->list, &urbp->td_list);
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_remove_td_from_urb(struct uhci_td *td)
{
if (list_empty(&td->list))
@@ -677,22 +685,22 @@ static void uhci_remove_td_from_urb(struct uhci_td *td)
td->urb = NULL;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_destroy_urb_priv(struct urb *urb)
{
struct list_head *head, *tmp;
struct urb_priv *urbp;
struct uhci *uhci;
- unsigned long flags;
-
- spin_lock_irqsave(&urb->lock, flags);
urbp = (struct urb_priv *)urb->hcpriv;
if (!urbp)
- goto out;
+ return;
if (!urbp->dev || !urbp->dev->bus || !urbp->dev->bus->hcpriv) {
warn("uhci_destroy_urb_priv: urb %p belongs to disconnected device or bus?", urb);
- goto out;
+ return;
}
if (!list_empty(&urb->urb_list))
@@ -715,20 +723,21 @@ static void uhci_destroy_urb_priv(struct urb *urb)
uhci_free_td(uhci, td);
}
- if (urbp->setup_packet_dma_handle)
+ if (urbp->setup_packet_dma_handle) {
pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
+ urbp->setup_packet_dma_handle = 0;
+ }
- if (urbp->transfer_buffer_dma_handle)
+ if (urbp->transfer_buffer_dma_handle) {
pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ urbp->transfer_buffer_dma_handle = 0;
+ }
urb->hcpriv = NULL;
kmem_cache_free(uhci_up_cachep, urbp);
-
-out:
- spin_unlock_irqrestore(&urb->lock, flags);
}
static void uhci_inc_fsbr(struct uhci *uhci, struct urb *urb)
@@ -872,7 +881,7 @@ static int uhci_submit_control(struct urb *urb)
* It's IN if the pipe is an output pipe or we're not expecting
* data back.
*/
- destination &= ~TD_PID;
+ destination &= ~TD_TOKEN_PID_MASK;
if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length)
destination |= USB_PID_IN;
else
@@ -1312,9 +1321,7 @@ static int isochronous_find_limits(struct urb *urb, unsigned int *start, unsigne
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
struct list_head *tmp, *head;
int ret = 0;
- unsigned long flags;
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
tmp = head->next;
while (tmp != head) {
@@ -1337,8 +1344,6 @@ static int isochronous_find_limits(struct urb *urb, unsigned int *start, unsigne
} else
ret = -1; /* no previous urb found */
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-
return ret;
}
@@ -1446,34 +1451,30 @@ static int uhci_result_isochronous(struct urb *urb)
return ret;
}
+/*
+ * MUST be called with uhci->urb_list_lock acquired
+ */
static struct urb *uhci_find_urb_ep(struct uhci *uhci, struct urb *urb)
{
struct list_head *tmp, *head;
- unsigned long flags;
- struct urb *u = NULL;
/* We don't match Isoc transfers since they are special */
if (usb_pipeisoc(urb->pipe))
return NULL;
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
tmp = head->next;
while (tmp != head) {
- u = list_entry(tmp, struct urb, urb_list);
+ struct urb *u = list_entry(tmp, struct urb, urb_list);
tmp = tmp->next;
if (u->dev == urb->dev && u->pipe == urb->pipe &&
u->status == -EINPROGRESS)
- goto out;
+ return u;
}
- u = NULL;
-
-out:
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
- return u;
+ return NULL;
}
static int uhci_submit_urb(struct urb *urb, int mem_flags)
@@ -1492,19 +1493,25 @@ static int uhci_submit_urb(struct urb *urb, int mem_flags)
return -ENODEV;
}
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb(urb);
+
uhci = (struct uhci *)urb->dev->bus->hcpriv;
INIT_LIST_HEAD(&urb->urb_list);
usb_inc_dev_use(urb->dev);
- spin_lock_irqsave(&urb->lock, flags);
+ spin_lock_irqsave(&uhci->urb_list_lock, flags);
+ spin_lock(&urb->lock);
if (urb->status == -EINPROGRESS || urb->status == -ECONNRESET ||
urb->status == -ECONNABORTED) {
dbg("uhci_submit_urb: urb not available to submit (status = %d)", urb->status);
/* Since we can have problems on the out path */
- spin_unlock_irqrestore(&urb->lock, flags);
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
usb_dec_dev_use(urb->dev);
+ usb_put_urb(urb);
return ret;
}
@@ -1572,18 +1579,21 @@ static int uhci_submit_urb(struct urb *urb, int mem_flags)
out:
urb->status = ret;
- spin_unlock_irqrestore(&urb->lock, flags);
-
if (ret == -EINPROGRESS) {
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
/* We use _tail to make find_urb_ep more efficient */
list_add_tail(&urb->urb_list, &uhci->urb_list);
+
+ spin_unlock(&urb->lock);
spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
return 0;
}
uhci_unlink_generic(uhci, urb);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
return ret;
@@ -1592,7 +1602,7 @@ out:
/*
* Return the result of a transfer
*
- * Must be called with urb_list_lock acquired
+ * MUST be called with urb_list_lock acquired
*/
static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
{
@@ -1631,10 +1641,10 @@ static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
urbp->status = ret;
- spin_unlock_irqrestore(&urb->lock, flags);
-
- if (ret == -EINPROGRESS)
+ if (ret == -EINPROGRESS) {
+ spin_unlock_irqrestore(&urb->lock, flags);
return;
+ }
switch (usb_pipetype(urb->pipe)) {
case PIPE_CONTROL:
@@ -1664,15 +1674,22 @@ static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
usb_pipetype(urb->pipe), urb);
}
+ /* Remove it from uhci->urb_list */
list_del_init(&urb->urb_list);
uhci_add_complete(urb);
+
+ spin_unlock_irqrestore(&urb->lock, flags);
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
{
struct list_head *head, *tmp;
struct urb_priv *urbp = urb->hcpriv;
+ int prevactive = 1;
/* We can get called when urbp allocation fails, so check */
if (!urbp)
@@ -1680,6 +1697,19 @@ static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
+ /*
+ * Now we need to find out what the last successful toggle was
+ * so we can update the local data toggle for the next transfer
+ *
+ * There's 3 way's the last successful completed TD is found:
+ *
+ * 1) The TD is NOT active and the actual length < expected length
+ * 2) The TD is NOT active and it's the last TD in the chain
+ * 3) The TD is active and the previous TD is NOT active
+ *
+ * Control and Isochronous ignore the toggle, so this is safe
+ * for all types
+ */
head = &urbp->td_list;
tmp = head->next;
while (tmp != head) {
@@ -1687,15 +1717,18 @@ static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
tmp = tmp->next;
- /* Control and Isochronous ignore the toggle, so this */
- /* is safe for all types */
- if ((!(td->status & TD_CTRL_ACTIVE) &&
- (uhci_actual_length(td->status) < uhci_expected_length(td->info)) ||
- tmp == head)) {
+ if (!(td->status & TD_CTRL_ACTIVE) &&
+ (uhci_actual_length(td->status) < uhci_expected_length(td->info) ||
+ tmp == head))
usb_settoggle(urb->dev, uhci_endpoint(td->info),
uhci_packetout(td->info),
uhci_toggle(td->info) ^ 1);
- }
+ else if ((td->status & TD_CTRL_ACTIVE) && !prevactive)
+ usb_settoggle(urb->dev, uhci_endpoint(td->info),
+ uhci_packetout(td->info),
+ uhci_toggle(td->info));
+
+ prevactive = td->status & TD_CTRL_ACTIVE;
}
uhci_delete_queued_urb(uhci, urb);
@@ -1718,6 +1751,9 @@ static int uhci_unlink_urb(struct urb *urb)
uhci = (struct uhci *)urb->dev->bus->hcpriv;
+ spin_lock_irqsave(&uhci->urb_list_lock, flags);
+ spin_lock(&urb->lock);
+
/* Release bandwidth for Interrupt or Isoc. transfers */
/* Spinlock needed ? */
if (urb->bandwidth) {
@@ -1733,35 +1769,41 @@ static int uhci_unlink_urb(struct urb *urb)
}
}
- if (urb->status != -EINPROGRESS)
+ if (urb->status != -EINPROGRESS) {
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
return 0;
+ }
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
list_del_init(&urb->urb_list);
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
uhci_unlink_generic(uhci, urb);
/* Short circuit the virtual root hub */
if (urb->dev == uhci->rh.dev) {
rh_unlink_urb(urb);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
} else {
if (urb->transfer_flags & USB_ASYNC_UNLINK) {
- /* urb_list is available now since we called */
- /* uhci_unlink_generic already */
-
urbp->status = urb->status = -ECONNABORTED;
- spin_lock_irqsave(&uhci->urb_remove_list_lock, flags);
+ spin_lock(&uhci->urb_remove_list_lock);
- /* Check to see if the remove list is empty */
+ /* If we're the first, set the next interrupt bit */
if (list_empty(&uhci->urb_remove_list))
uhci_set_next_interrupt(uhci);
list_add(&urb->urb_list, &uhci->urb_remove_list);
- spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
+ spin_unlock(&uhci->urb_remove_list_lock);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
} else {
urb->status = -ENOENT;
@@ -1774,6 +1816,9 @@ static int uhci_unlink_urb(struct urb *urb)
} else
schedule_timeout(1+1*HZ/1000);
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
}
}
@@ -1907,12 +1952,14 @@ static __u8 root_hub_hub_des[] =
/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */
static int rh_send_irq(struct urb *urb)
{
- int i, len = 1;
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
+ struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
unsigned int io_addr = uhci->io_addr;
+ unsigned long flags;
+ int i, len = 1;
__u16 data = 0;
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ spin_lock_irqsave(&urb->lock, flags);
for (i = 0; i < uhci->rh.numports; i++) {
data |= ((inw(io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i + 1)) : 0);
len = (i + 1) / 8 + 1;
@@ -1922,6 +1969,8 @@ static int rh_send_irq(struct urb *urb)
urb->actual_length = len;
urbp->status = 0;
+ spin_unlock_irqrestore(&urb->lock, flags);
+
if ((data > 0) && (uhci->rh.send != 0)) {
dbg("root-hub INT complete: port1: %x port2: %x data: %x",
inw(io_addr + USBPORTSC1), inw(io_addr + USBPORTSC2), data);
@@ -1948,7 +1997,6 @@ static void rh_int_timer_do(unsigned long ptr)
spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
-
tmp = head->next;
while (tmp != head) {
struct urb *u = list_entry(tmp, struct urb, urb_list);
@@ -1956,6 +2004,8 @@ static void rh_int_timer_do(unsigned long ptr)
tmp = tmp->next;
+ spin_lock(&urb->lock);
+
/* Check if the FSBR timed out */
if (urbp->fsbr && !urbp->fsbr_timeout && time_after_eq(jiffies, urbp->fsbrtime + IDLE_TIMEOUT))
uhci_fsbr_timeout(uhci, u);
@@ -1965,6 +2015,8 @@ static void rh_int_timer_do(unsigned long ptr)
list_del(&u->urb_list);
list_add_tail(&u->urb_list, &list);
}
+
+ spin_unlock(&urb->lock);
}
spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
@@ -2198,6 +2250,9 @@ static int rh_submit_urb(struct urb *urb)
return stat;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static int rh_unlink_urb(struct urb *urb)
{
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
@@ -2233,16 +2288,25 @@ static void uhci_free_pending_qhs(struct uhci *uhci)
static void uhci_call_completion(struct urb *urb)
{
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ struct urb_priv *urbp;
struct usb_device *dev = urb->dev;
struct uhci *uhci = (struct uhci *)dev->bus->hcpriv;
int is_ring = 0, killed, resubmit_interrupt, status;
struct urb *nurb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&urb->lock, flags);
+
+ urbp = (struct urb_priv *)urb->hcpriv;
+ if (!urbp || !urb->dev) {
+ spin_unlock_irqrestore(&urb->lock, flags);
+ return;
+ }
killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED ||
urb->status == -ECONNRESET);
resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
- urb->interval && !killed);
+ urb->interval);
nurb = urb->next;
if (nurb && !killed) {
@@ -2267,14 +2331,6 @@ static void uhci_call_completion(struct urb *urb)
is_ring = (nurb == urb);
}
- status = urbp->status;
- if (!resubmit_interrupt)
- /* We don't need urb_priv anymore */
- uhci_destroy_urb_priv(urb);
-
- if (!killed)
- urb->status = status;
-
if (urbp->transfer_buffer_dma_handle)
pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
@@ -2284,11 +2340,28 @@ static void uhci_call_completion(struct urb *urb)
pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
+ status = urbp->status;
+ if (!resubmit_interrupt || killed)
+ /* We don't need urb_priv anymore */
+ uhci_destroy_urb_priv(urb);
+
+ if (!killed)
+ urb->status = status;
+
urb->dev = NULL;
- if (urb->complete)
+ spin_unlock_irqrestore(&urb->lock, flags);
+
+ if (urb->complete) {
urb->complete(urb);
- if (resubmit_interrupt) {
+ /* Recheck the status. The completion handler may have */
+ /* unlinked the resubmitting interrupt URB */
+ killed = (urb->status == -ENOENT ||
+ urb->status == -ECONNABORTED ||
+ urb->status == -ECONNRESET);
+ }
+
+ if (resubmit_interrupt && !killed) {
urb->dev = dev;
uhci_reset_interrupt(urb);
} else {
@@ -2299,6 +2372,7 @@ static void uhci_call_completion(struct urb *urb)
/* We decrement the usage count after we're done */
/* with everything */
usb_dec_dev_use(dev);
+ usb_put_urb(urb);
}
}
}
@@ -2315,11 +2389,14 @@ static void uhci_finish_completion(struct uhci *uhci)
struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list);
struct urb *urb = urbp->urb;
- tmp = tmp->next;
-
list_del_init(&urbp->complete_list);
+ spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
uhci_call_completion(urb);
+
+ spin_lock_irqsave(&uhci->complete_list_lock, flags);
+ head = &uhci->complete_list;
+ tmp = head->next;
}
spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
}
@@ -2341,7 +2418,8 @@ static void uhci_remove_pending_qhs(struct uhci *uhci)
list_del_init(&urb->urb_list);
urbp->status = urb->status = -ECONNRESET;
- uhci_call_completion(urb);
+
+ uhci_add_complete(urb);
}
spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
}
@@ -2996,7 +3074,7 @@ static struct pci_driver uhci_pci_driver = {
id_table: uhci_pci_ids,
probe: uhci_pci_probe,
- remove: uhci_pci_remove,
+ remove: __devexit_p(uhci_pci_remove),
#ifdef CONFIG_PM
suspend: uhci_pci_suspend,
@@ -3074,3 +3152,4 @@ module_exit(uhci_hcd_cleanup);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/uhci.h b/drivers/usb/uhci.h
index c2b17f6705a1..2a7e94535ec3 100644
--- a/drivers/usb/uhci.h
+++ b/drivers/usb/uhci.h
@@ -121,15 +121,16 @@ struct uhci_qh {
* for TD <info>: (a.k.a. Token)
*/
#define TD_TOKEN_TOGGLE 19
-#define TD_PID 0xFF
+#define TD_TOKEN_PID_MASK 0xFF
+#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */
#define uhci_maxlen(token) ((token) >> 21)
-#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
+#define uhci_expected_length(info) (((info >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) /* 1-based */
#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1)
#define uhci_endpoint(token) (((token) >> 15) & 0xf)
#define uhci_devaddr(token) (((token) >> 8) & 0x7f)
#define uhci_devep(token) (((token) >> 8) & 0x7ff)
-#define uhci_packetid(token) ((token) & 0xff)
+#define uhci_packetid(token) ((token) & TD_TOKEN_PID_MASK)
#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN)
#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN)
@@ -163,7 +164,7 @@ struct uhci_td {
struct list_head list; /* P: urb->lock */
int frame;
- struct list_head fl_list; /* P: frame_list_lock */
+ struct list_head fl_list; /* P: uhci->frame_list_lock */
} __attribute__((aligned(16)));
/*
@@ -306,21 +307,25 @@ struct uhci {
struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */
spinlock_t frame_list_lock;
- struct uhci_frame_list *fl; /* Frame list */
+ struct uhci_frame_list *fl; /* P: uhci->frame_list_lock */
int fsbr; /* Full speed bandwidth reclamation */
int is_suspended;
+ /* Main list of URB's currently controlled by this HC */
+ spinlock_t urb_list_lock;
+ struct list_head urb_list; /* P: uhci->urb_list_lock */
+
+ /* List of QH's that are done, but waiting to be unlinked (race) */
spinlock_t qh_remove_list_lock;
- struct list_head qh_remove_list;
+ struct list_head qh_remove_list; /* P: uhci->qh_remove_list_lock */
+ /* List of asynchronously unlinked URB's */
spinlock_t urb_remove_list_lock;
- struct list_head urb_remove_list;
-
- spinlock_t urb_list_lock;
- struct list_head urb_list;
+ struct list_head urb_remove_list; /* P: uhci->urb_remove_list_lock */
+ /* List of URB's awaiting completion callback */
spinlock_t complete_list_lock;
- struct list_head complete_list;
+ struct list_head complete_list; /* P: uhci->complete_list_lock */
struct virt_root_hub rh; /* private data of the virtual root hub */
};
@@ -333,7 +338,7 @@ struct urb_priv {
dma_addr_t transfer_buffer_dma_handle;
struct uhci_qh *qh; /* QH for this URB */
- struct list_head td_list;
+ struct list_head td_list; /* P: urb->lock */
int fsbr : 1; /* URB turned on FSBR */
int fsbr_timeout : 1; /* URB timed out on FSBR */
@@ -345,12 +350,37 @@ struct urb_priv {
int status; /* Final status */
unsigned long inserttime; /* In jiffies */
- unsigned long fsbrtime; /* In jiffies */
+ unsigned long fsbrtime; /* In jiffies */
- struct list_head queue_list;
- struct list_head complete_list;
+ struct list_head queue_list; /* P: uhci->frame_list_lock */
+ struct list_head complete_list; /* P: uhci->complete_list_lock */
};
+/*
+ * Locking in uhci.c
+ *
+ * spinlocks are used extensively to protect the many lists and data
+ * structures we have. It's not that pretty, but it's necessary. We
+ * need to be done with all of the locks (except complete_list_lock) when
+ * we call urb->complete. I've tried to make it simple enough so I don't
+ * have to spend hours racking my brain trying to figure out if the
+ * locking is safe.
+ *
+ * Here's the safe locking order to prevent deadlocks:
+ *
+ * #1 uhci->urb_list_lock
+ * #2 urb->lock
+ * #3 uhci->urb_remove_list_lock, uhci->frame_list_lock,
+ * uhci->qh_remove_list_lock
+ * #4 uhci->complete_list_lock
+ *
+ * If you're going to grab 2 or more locks at once, ALWAYS grab the lock
+ * at the lowest level FIRST and NEVER grab locks at the same level at the
+ * same time.
+ *
+ * So, if you need uhci->urb_list_lock, grab it before you grab urb->lock
+ */
+
/* -------------------------------------------------------------------------
Virtual Root HUB
------------------------------------------------------------------------- */
diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index 63fb3a7b1d15..32a17a937c70 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -205,6 +205,7 @@ static void urb_rm_priv_locked (struct urb * urb)
urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
usb_dec_dev_use (urb->dev);
urb->dev = NULL;
+ usb_put_urb (urb);
}
}
@@ -553,6 +554,9 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)))
// return -EPIPE;
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb (urb);
+
usb_inc_dev_use (urb->dev);
ohci = (ohci_t *) urb->dev->bus->hcpriv;
@@ -568,12 +572,14 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
* such as powering down ports */
if (ohci->disabled) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ESHUTDOWN;
}
/* every endpoint has a ed, locate and fill it */
if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
@@ -595,6 +601,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
size = urb->number_of_packets;
if (size <= 0) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -EINVAL;
}
for (i = 0; i < urb->number_of_packets; i++) {
@@ -615,6 +622,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
if (!urb_priv) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
@@ -632,6 +640,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
}
@@ -640,6 +649,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -EINVAL;
}
@@ -662,6 +672,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return bustime;
}
usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
@@ -2100,6 +2111,7 @@ static int rh_submit_urb (struct urb * urb)
urb->dev = NULL;
if (urb->complete)
urb->complete (urb);
+ usb_put_urb (urb);
return 0;
}
@@ -2123,6 +2135,7 @@ static int rh_unlink_urb (struct urb * urb)
urb->complete (urb);
} else
urb->status = -ENOENT;
+ usb_put_urb (urb);
}
return 0;
}
@@ -2859,7 +2872,7 @@ static struct pci_driver ohci_pci_driver = {
id_table: &ohci_pci_ids [0],
probe: ohci_pci_probe,
- remove: ohci_pci_remove,
+ remove: __devexit_p(ohci_pci_remove),
#ifdef CONFIG_PM
suspend: ohci_pci_suspend,
diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
index 2f38a19857de..00346153dbab 100644
--- a/drivers/usb/usb-uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -1217,6 +1217,7 @@ _static int uhci_unlink_urb_sync (uhci_t *s, struct urb *urb)
urb->complete ((struct urb *) urb);
}
usb_dec_dev_use (usb_dev);
+ usb_put_urb (urb);
}
else
spin_unlock_irqrestore (&s->urb_list_lock, flags);
@@ -1305,7 +1306,7 @@ _static void uhci_cleanup_unlink(uhci_t *s, int force)
#else
kfree (urb_priv);
#endif
-
+ usb_put_urb (urb);
}
}
}
@@ -1650,6 +1651,9 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
return -EINVAL;
}
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb (urb);
+
usb_inc_dev_use (urb->dev);
spin_lock_irqsave (&s->urb_list_lock, flags);
@@ -1665,6 +1669,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
(!(urb->transfer_flags & USB_QUEUE_BULK) || !(queued_urb->transfer_flags & USB_QUEUE_BULK)))) {
spin_unlock_irqrestore (&s->urb_list_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
err("ENXIO %08x, flags %x, urb %p, burb %p",urb->pipe,urb->transfer_flags,urb,queued_urb);
return -ENXIO; // urb already queued
}
@@ -1678,6 +1683,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
if (!urb_priv) {
usb_dec_dev_use (urb->dev);
spin_unlock_irqrestore (&s->urb_list_lock, flags);
+ usb_put_urb (urb);
return -ENOMEM;
}
@@ -1766,6 +1772,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
#else
kfree (urb_priv);
#endif
+ usb_put_urb (urb);
return ret;
}
@@ -2730,6 +2737,7 @@ _static int process_urb (uhci_t *s, struct list_head *p)
}
usb_dec_dev_use (usb_dev);
+ usb_put_urb (urb);
}
}
diff --git a/drivers/usb/vicam.c b/drivers/usb/vicam.c
index c74b653c2e52..916c808f2086 100644
--- a/drivers/usb/vicam.c
+++ b/drivers/usb/vicam.c
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/module.h>
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index d83338cc3965..74553d1392f0 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1683,7 +1683,7 @@ static struct pci_device_id cyberpro_pci_table[] __devinitdata = {
static struct pci_driver cyberpro_driver = {
name: "CyberPro",
probe: cyberpro_probe,
- remove: cyberpro_remove,
+ remove: __devexit_p(cyberpro_remove),
suspend: cyberpro_suspend,
resume: cyberpro_resume,
id_table: cyberpro_pci_table
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index b3ef1541d3fa..76be9abdb73a 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1643,7 +1643,7 @@ static struct pci_driver imsttfb_pci_driver = {
name: "imsttfb",
id_table: imsttfb_pci_tbl,
probe: imsttfb_probe,
- remove: imsttfb_remove,
+ remove: __devexit_p(imsttfb_remove),
};
static struct fb_ops imsttfb_ops = {
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 2550a8a20020..757512059647 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -2332,7 +2332,7 @@ static struct pci_driver neofb_driver = {
name: "neofb",
id_table: neofb_devices,
probe: neofb_probe,
- remove: neofb_remove
+ remove: __devexit_p(neofb_remove)
};
/* **************************** init-time only **************************** */
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index d89cdb282c45..218ae637bc26 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -619,7 +619,7 @@ static struct pci_driver radeonfb_driver = {
name: "radeonfb",
id_table: radeonfb_pci_table,
probe: radeonfb_pci_register,
- remove: radeonfb_pci_unregister,
+ remove: __devexit_p(radeonfb_pci_unregister),
};
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 2213a8595582..a68cc3372c80 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1811,7 +1811,7 @@ static int __devinit riva_set_fbinfo(struct rivafb_info *rinfo)
info = &rinfo->info;
strcpy(info->modename, rinfo->drvr_name);
- info->node = -1;
+ info->node = NODEV;
info->flags = FBINFO_FLAG_DEFAULT;
info->fbops = &riva_fb_ops;
@@ -2082,7 +2082,7 @@ static struct pci_driver rivafb_driver = {
name: "rivafb",
id_table: rivafb_pci_tbl,
probe: rivafb_init_one,
- remove: rivafb_remove_one,
+ remove: __devexit_p(rivafb_remove_one),
};
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 68b8ed57a7c3..c49378e82e9f 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -495,7 +495,7 @@ static struct pci_driver tdfxfb_driver = {
name: "tdfxfb",
id_table: tdfxfb_id_table,
probe: tdfxfb_probe,
- remove: tdfxfb_remove,
+ remove: __devexit_p(tdfxfb_remove),
};
MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 0b292b3562ff..73859637332d 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -625,6 +625,18 @@ fat_read_super(struct super_block *sb, void *data, int silent,
}
b = (struct fat_boot_sector *) bh->b_data;
+ if (!b->reserved) {
+ if (!silent)
+ printk("FAT: bogus number of reserved sectors\n");
+ brelse(bh);
+ goto out_invalid;
+ }
+ if (!b->fats) {
+ if (!silent)
+ printk("FAT: bogus number of FAT structure\n");
+ brelse(bh);
+ goto out_invalid;
+ }
if (!b->secs_track) {
if (!silent)
printk("FAT: bogus sectors-per-track value\n");
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 80e64d703b2a..6b448dd91c35 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -344,8 +344,6 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent
struct reiserfs_dir_entry de;
INITIALIZE_PATH (path_to_entry);
- reiserfs_check_lock_depth("lookup") ;
-
if (dentry->d_name.len > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize))
return ERR_PTR(-ENAMETOOLONG);
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 1ba4266c7376..d76bcde410da 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -460,6 +460,27 @@ found_middle:
#ifdef __KERNEL__
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is set.
+ */
+static inline unsigned long
+sched_find_first_bit(unsigned long b[3])
+{
+ unsigned long b0 = b[0], b1 = b[1], b2 = b[2];
+ unsigned long ofs;
+
+ ofs = (b1 ? 64 : 128);
+ b1 = (b1 ? b1 : b2);
+ ofs = (b0 ? 0 : ofs);
+ b0 = (b0 ? b0 : b1);
+
+ return __ffs(b0) + ofs;
+}
+
+
#define ext2_set_bit __test_and_set_bit
#define ext2_clear_bit __test_and_clear_bit
#define ext2_test_bit test_bit
diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h
index 94d26e7b60f3..01265ce73e37 100644
--- a/include/asm-alpha/mmu_context.h
+++ b/include/asm-alpha/mmu_context.h
@@ -21,31 +21,6 @@
#include <asm/io.h>
#endif
-/* ??? This does not belong here. */
-/*
- * Every architecture must define this function. It's the fastest
- * way of searching a 168-bit bitmap where the first 128 bits are
- * unlikely to be set. It's guaranteed that at least one of the 168
- * bits is set.
- */
-#if MAX_RT_PRIO != 128 || MAX_PRIO > 192
-# error update this function.
-#endif
-
-static inline int
-sched_find_first_bit(unsigned long *b)
-{
- unsigned long b0 = b[0], b1 = b[1], b2 = b[2];
- unsigned long offset = 128;
-
- if (unlikely(b0 | b1)) {
- b2 = (b0 ? b0 : b1);
- offset = (b0 ? 0 : 64);
- }
-
- return __ffs(b2) + offset;
-}
-
extern inline unsigned long
__reload_thread(struct pcb_struct *pcb)
diff --git a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
index 619643e9c275..d928c653c4f7 100644
--- a/include/asm-alpha/spinlock.h
+++ b/include/asm-alpha/spinlock.h
@@ -121,8 +121,8 @@ static inline void _raw_write_lock(rwlock_t * lock)
" bne %1,6b\n"
" br 1b\n"
".previous"
- : "=m" (*(volatile int *)lock), "=&r" (regx)
- : "0" (*(volatile int *)lock) : "memory");
+ : "=m" (*lock), "=&r" (regx)
+ : "0" (*lock) : "memory");
}
static inline void _raw_read_lock(rwlock_t * lock)
@@ -141,8 +141,8 @@ static inline void _raw_read_lock(rwlock_t * lock)
" blbs %1,6b\n"
" br 1b\n"
".previous"
- : "=m" (*(volatile int *)lock), "=&r" (regx)
- : "m" (*(volatile int *)lock) : "memory");
+ : "=m" (*lock), "=&r" (regx)
+ : "m" (*lock) : "memory");
}
#endif /* CONFIG_DEBUG_RWLOCK */
@@ -164,8 +164,8 @@ static inline void _raw_read_unlock(rwlock_t * lock)
".subsection 2\n"
"6: br 1b\n"
".previous"
- : "=m" (*(volatile int *)lock), "=&r" (regx)
- : "m" (*(volatile int *)lock) : "memory");
+ : "=m" (*lock), "=&r" (regx)
+ : "m" (*lock) : "memory");
}
#endif /* _ALPHA_SPINLOCK_H */
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index bc06fe188985..ad6c9fbde6a5 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -131,15 +131,13 @@ extern void halt(void) __attribute__((noreturn));
#define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
#define prepare_to_switch() do { } while(0)
-#define switch_to(prev,next,last) \
-do { \
- unsigned long pcbb; \
- pcbb = virt_to_phys(&(next)->thread_info->pcb); \
- (last) = alpha_switch_to(pcbb, (prev)); \
- check_mmu_context(); \
+#define switch_to(prev,next) \
+do { \
+ alpha_switch_to(virt_to_phys(&(next)->thread_info->pcb), (prev)); \
+ check_mmu_context(); \
} while (0)
-extern struct task_struct* alpha_switch_to(unsigned long, struct task_struct*);
+extern void alpha_switch_to(unsigned long, struct task_struct*);
#define mb() \
__asm__ __volatile__("mb": : :"memory")
@@ -368,7 +366,59 @@ extern void __global_restore_flags(unsigned long flags);
* it must clobber "memory" (also for interrupts in UP).
*/
-extern __inline__ unsigned long
+static inline unsigned long
+__xchg_u8(volatile char *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " insbl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extbl %2,%4,%0\n"
+ " mskbl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+__xchg_u16(volatile short *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " inswl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extwl %2,%4,%0\n"
+ " mskwl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
__xchg_u32(volatile int *m, unsigned long val)
{
unsigned long dummy;
@@ -390,7 +440,7 @@ __xchg_u32(volatile int *m, unsigned long val)
return val;
}
-extern __inline__ unsigned long
+static inline unsigned long
__xchg_u64(volatile long *m, unsigned long val)
{
unsigned long dummy;
@@ -416,10 +466,14 @@ __xchg_u64(volatile long *m, unsigned long val)
if something tries to do an invalid xchg(). */
extern void __xchg_called_with_bad_pointer(void);
-static __inline__ unsigned long
+static inline unsigned long
__xchg(volatile void *ptr, unsigned long x, int size)
{
switch (size) {
+ case 1:
+ return __xchg_u8(ptr, x);
+ case 2:
+ return __xchg_u16(ptr, x);
case 4:
return __xchg_u32(ptr, x);
case 8:
@@ -451,7 +505,65 @@ __xchg(volatile void *ptr, unsigned long x, int size)
#define __HAVE_ARCH_CMPXCHG 1
-extern __inline__ unsigned long
+static inline unsigned long
+__cmpxchg_u8(volatile char *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " insbl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extbl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskbl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u16(volatile short *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " inswl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extwl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskwl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
__cmpxchg_u32(volatile int *m, int old, int new)
{
unsigned long prev, cmp;
@@ -476,7 +588,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
return prev;
}
-extern __inline__ unsigned long
+static inline unsigned long
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
{
unsigned long prev, cmp;
@@ -505,10 +617,14 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);
-static __inline__ unsigned long
+static inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
{
switch (size) {
+ case 1:
+ return __cmpxchg_u8(ptr, old, new);
+ case 2:
+ return __cmpxchg_u16(ptr, old, new);
case 4:
return __cmpxchg_u32(ptr, old, new);
case 8:
diff --git a/include/asm-arm/arch-adifcc/serial.h b/include/asm-arm/arch-adifcc/serial.h
index e7555e6ab12b..2325cd765f13 100644
--- a/include/asm-arm/arch-adifcc/serial.h
+++ b/include/asm-arm/arch-adifcc/serial.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 2001 MontaVista Software, Inc.
*/
-
+#include <linux/config.h>
/*
* This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-arm/arch-anakin/ide.h b/include/asm-arm/arch-anakin/ide.h
index c998cfe70518..0d676932de73 100644
--- a/include/asm-arm/arch-anakin/ide.h
+++ b/include/asm-arm/arch-anakin/ide.h
@@ -7,7 +7,6 @@
* (jonm@bluemug.com).
*/
-#include <linux/config.h>
#include <asm/irq.h>
#include <asm/hardware.h>
diff --git a/include/asm-arm/arch-anakin/uncompress.h b/include/asm-arm/arch-anakin/uncompress.h
index 5558abd8bf82..1b940cedb05b 100644
--- a/include/asm-arm/arch-anakin/uncompress.h
+++ b/include/asm-arm/arch-anakin/uncompress.h
@@ -14,6 +14,7 @@
#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H
+#include <linux/config.h>
#include <asm/io.h>
#include <asm/arch/serial_reg.h>
diff --git a/include/asm-arm/arch-clps711x/memory.h b/include/asm-arm/arch-clps711x/memory.h
index 043ee9a9baec..1e884d9e4167 100644
--- a/include/asm-arm/arch-clps711x/memory.h
+++ b/include/asm-arm/arch-clps711x/memory.h
@@ -20,6 +20,8 @@
#ifndef __ASM_ARCH_MMU_H
#define __ASM_ARCH_MMU_H
+#include <linux/config.h>
+
/*
* Task size: 3GB
*/
diff --git a/include/asm-arm/arch-ebsa285/keyboard.h b/include/asm-arm/arch-ebsa285/keyboard.h
index 0106c5e0817a..968163b3f883 100644
--- a/include/asm-arm/arch-ebsa285/keyboard.h
+++ b/include/asm-arm/arch-ebsa285/keyboard.h
@@ -6,6 +6,7 @@
* Copyright (C) 1998-2001 Russell King
* (C) 1998 Phil Blundell
*/
+#include <linux/config.h>
#include <linux/ioport.h>
#include <asm/irq.h>
#include <asm/system.h>
diff --git a/include/asm-arm/arch-epxa10db/time.h b/include/asm-arm/arch-epxa10db/time.h
index b18453053e9b..7f0e6a7c0d00 100644
--- a/include/asm-arm/arch-epxa10db/time.h
+++ b/include/asm-arm/arch-epxa10db/time.h
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/config.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/arch/hardware.h>
diff --git a/include/asm-arm/arch-iop310/irqs.h b/include/asm-arm/arch-iop310/irqs.h
index 6b671853c122..f468a285832f 100644
--- a/include/asm-arm/arch-iop310/irqs.h
+++ b/include/asm-arm/arch-iop310/irqs.h
@@ -11,7 +11,7 @@
* 06/13/01: Added 80310 on-chip interrupt sources <dsaxena@mvista.com>
*
*/
-
+#include <linux/config.h>
/*
* XS80200 specific IRQs
diff --git a/include/asm-arm/arch-iop310/memory.h b/include/asm-arm/arch-iop310/memory.h
index 64c078981659..c1b47276d41a 100644
--- a/include/asm-arm/arch-iop310/memory.h
+++ b/include/asm-arm/arch-iop310/memory.h
@@ -5,6 +5,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
+#include <linux/config.h>
/*
* Task size: 3GB
diff --git a/include/asm-arm/arch-iop310/serial.h b/include/asm-arm/arch-iop310/serial.h
index b25a5e5e9517..48e20ba12d5c 100644
--- a/include/asm-arm/arch-iop310/serial.h
+++ b/include/asm-arm/arch-iop310/serial.h
@@ -1,7 +1,7 @@
/*
* include/asm-arm/arch-iop310/serial.h
*/
-
+#include <linux/config.h>
/*
* This assumes you have a 1.8432 MHz clock for your UART.
diff --git a/include/asm-arm/arch-iop310/timex.h b/include/asm-arm/arch-iop310/timex.h
index 8a085715ad07..a836e5f5b823 100644
--- a/include/asm-arm/arch-iop310/timex.h
+++ b/include/asm-arm/arch-iop310/timex.h
@@ -3,7 +3,7 @@
*
* IOP310 architecture timex specifications
*/
-
+#include <linux/config.h>
#ifdef CONFIG_ARCH_IQ80310
diff --git a/include/asm-arm/arch-iop310/uncompress.h b/include/asm-arm/arch-iop310/uncompress.h
index 40300833cdfb..c8d6a6ca859a 100644
--- a/include/asm-arm/arch-iop310/uncompress.h
+++ b/include/asm-arm/arch-iop310/uncompress.h
@@ -1,6 +1,7 @@
/*
* linux/include/asm-arm/arch-iop80310/uncompress.h
*/
+#include <linux/config.h>
#ifdef CONFIG_ARCH_IQ80310
#define UART1_BASE ((volatile unsigned char *)0xfe800000)
diff --git a/include/asm-arm/arch-sa1100/assabet.h b/include/asm-arm/arch-sa1100/assabet.h
index 6d13df14a60a..f9df2064573d 100644
--- a/include/asm-arm/arch-sa1100/assabet.h
+++ b/include/asm-arm/arch-sa1100/assabet.h
@@ -12,6 +12,8 @@
#ifndef __ASM_ARCH_ASSABET_H
#define __ASM_ARCH_ASSABET_H
+#include <linux/config.h>
+
/* System Configuration Register flags */
#define ASSABET_SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */
diff --git a/include/asm-arm/arch-sa1100/cerf.h b/include/asm-arm/arch-sa1100/cerf.h
index c37cb9e4839f..7bdc6a296f18 100644
--- a/include/asm-arm/arch-sa1100/cerf.h
+++ b/include/asm-arm/arch-sa1100/cerf.h
@@ -1,6 +1,8 @@
#ifndef _INCLUDE_CERF_H_
#define _INCLUDE_CERF_H_
+#include <linux/config.h>
+
#ifdef CONFIG_SA1100_CERF_CPLD
diff --git a/include/asm-arm/arch-sa1100/pangolin.h b/include/asm-arm/arch-sa1100/pangolin.h
index b261dd4437ae..889585365762 100644
--- a/include/asm-arm/arch-sa1100/pangolin.h
+++ b/include/asm-arm/arch-sa1100/pangolin.h
@@ -6,11 +6,12 @@
* This file contains the hardware specific definitions for Pangolin
*
*/
-
#ifndef __ASM_ARCH_HARDWARE_H
#error "include <asm/hardware.h> instead"
#endif
+#include <linux/config.h>
+
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
/* GPIOs for which the generic definition doesn't say much */
diff --git a/include/asm-arm/arch-shark/keyboard.h b/include/asm-arm/arch-shark/keyboard.h
index 5cbacaa0a21f..3d400663a304 100644
--- a/include/asm-arm/arch-shark/keyboard.h
+++ b/include/asm-arm/arch-shark/keyboard.h
@@ -6,6 +6,7 @@
* (C) 1998 Russell King
* (C) 1998 Phil Blundell
*/
+#include <linux/config.h>
#include <linux/ioport.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index dbb54a4d64bd..ecdd955a8381 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -302,6 +302,23 @@ static inline unsigned long ffz(unsigned long word)
}
/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+ int k;
+
+ k = 31;
+ if (word & 0x0000ffff) { k -= 16; word <<= 16; }
+ if (word & 0x00ff0000) { k -= 8; word <<= 8; }
+ if (word & 0x0f000000) { k -= 4; word <<= 4; }
+ if (word & 0x30000000) { k -= 2; word <<= 2; }
+ if (word & 0x40000000) { k -= 1; }
+ return k;
+}
+
+/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
diff --git a/include/asm-arm/current.h b/include/asm-arm/current.h
index 597a8773cc5b..921ee95e0d92 100644
--- a/include/asm-arm/current.h
+++ b/include/asm-arm/current.h
@@ -1,12 +1,13 @@
#ifndef _ASMARM_CURRENT_H
#define _ASMARM_CURRENT_H
+#include <asm/thread_info.h>
+
static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
static inline struct task_struct *get_current(void)
{
- register unsigned long sp asm ("sp");
- return (struct task_struct *)(sp & ~0x1fff);
+ return current_thread_info()->task;
}
#define current (get_current())
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h
new file mode 100644
index 000000000000..785749b3c5ab
--- /dev/null
+++ b/include/asm-arm/fpstate.h
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/fpstate.h
+ *
+ * Copyright (C) 1995 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_FPSTATE_H
+#define __ASM_ARM_FPSTATE_H
+
+#define FP_SIZE 35
+
+struct fp_hard_struct {
+ unsigned int save[FP_SIZE]; /* as yet undefined */
+};
+
+struct fp_soft_struct {
+ unsigned int save[FP_SIZE]; /* undefined information */
+};
+
+union fp_state {
+ struct fp_hard_struct hard;
+ struct fp_soft_struct soft;
+};
+
+#endif
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index 572e729095f8..c96c7a390692 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -34,6 +34,7 @@ typedef struct {
#define irq_exit(cpu,irq) (local_irq_count(cpu)--)
#define synchronize_irq() do { } while (0)
+#define release_irqlock(cpu) do { } while (0)
#else
#error SMP not supported
diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h
index 6aad02f46ff7..0acf4d89c965 100644
--- a/include/asm-arm/mmu_context.h
+++ b/include/asm-arm/mmu_context.h
@@ -42,14 +42,34 @@ static inline void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk, unsigned int cpu)
{
- if (prev != next) {
+ if (prev != next)
cpu_switch_mm(next->pgd, tsk);
- clear_bit(cpu, &prev->cpu_vm_mask);
- }
- set_bit(cpu, &next->cpu_vm_mask);
}
#define activate_mm(prev, next) \
s