---------------------------
+What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
+ (temporary transition config option provided until then)
+ The transition config option will also be removed at the same time.
+When: before 2.6.19
+Why: Unused symbols are both increasing the size of the kernel binary
+ and are often a sign of "wrong API"
+Who: Arjan van de Ven <arjan@linux.intel.com>
+
+---------------------------
+
What: remove EXPORT_SYMBOL(tasklist_lock)
When: August 2006
Files: kernel/fork.c
to run the program with an "&" to run it in the background!)
If you want to write a program to be compatible with the PC Watchdog
- driver, simply do the following:
-
--- Snippet of code --
-/*
- * Watchdog Driver Test Program
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-
-int fd;
-
-/*
- * This function simply sends an IOCTL to the driver, which in turn ticks
- * the PC Watchdog card to reset its internal timer so it doesn't trigger
- * a computer reset.
- */
-void keep_alive(void)
-{
- int dummy;
-
- ioctl(fd, WDIOC_KEEPALIVE, &dummy);
-}
-
-/*
- * The main program. Run the program with "-d" to disable the card,
- * or "-e" to enable the card.
- */
-int main(int argc, char *argv[])
-{
- fd = open("/dev/watchdog", O_WRONLY);
-
- if (fd == -1) {
- fprintf(stderr, "Watchdog device not enabled.\n");
- fflush(stderr);
- exit(-1);
- }
-
- if (argc > 1) {
- if (!strncasecmp(argv[1], "-d", 2)) {
- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
- fprintf(stderr, "Watchdog card disabled.\n");
- fflush(stderr);
- exit(0);
- } else if (!strncasecmp(argv[1], "-e", 2)) {
- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
- fprintf(stderr, "Watchdog card enabled.\n");
- fflush(stderr);
- exit(0);
- } else {
- fprintf(stderr, "-d to disable, -e to enable.\n");
- fprintf(stderr, "run by itself to tick the card.\n");
- fflush(stderr);
- exit(0);
- }
- } else {
- fprintf(stderr, "Watchdog Ticking Away!\n");
- fflush(stderr);
- }
-
- while(1) {
- keep_alive();
- sleep(1);
- }
-}
--- End snippet --
+ driver, simply use of modify the watchdog test program:
+ Documentation/watchdog/src/watchdog-test.c
+
Other IOCTL functions include:
--- /dev/null
+#include <stdlib.h>
+#include <fcntl.h>
+
+int main(int argc, const char *argv[]) {
+ int fd = open("/dev/watchdog", O_WRONLY);
+ if (fd == -1) {
+ perror("watchdog");
+ exit(1);
+ }
+ while (1) {
+ write(fd, "\0", 1);
+ fsync(fd);
+ sleep(10);
+ }
+}
--- /dev/null
+/*
+ * Watchdog Driver Test Program
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+int fd;
+
+/*
+ * This function simply sends an IOCTL to the driver, which in turn ticks
+ * the PC Watchdog card to reset its internal timer so it doesn't trigger
+ * a computer reset.
+ */
+void keep_alive(void)
+{
+ int dummy;
+
+ ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+}
+
+/*
+ * The main program. Run the program with "-d" to disable the card,
+ * or "-e" to enable the card.
+ */
+int main(int argc, char *argv[])
+{
+ fd = open("/dev/watchdog", O_WRONLY);
+
+ if (fd == -1) {
+ fprintf(stderr, "Watchdog device not enabled.\n");
+ fflush(stderr);
+ exit(-1);
+ }
+
+ if (argc > 1) {
+ if (!strncasecmp(argv[1], "-d", 2)) {
+ ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
+ fprintf(stderr, "Watchdog card disabled.\n");
+ fflush(stderr);
+ exit(0);
+ } else if (!strncasecmp(argv[1], "-e", 2)) {
+ ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+ fprintf(stderr, "Watchdog card enabled.\n");
+ fflush(stderr);
+ exit(0);
+ } else {
+ fprintf(stderr, "-d to disable, -e to enable.\n");
+ fprintf(stderr, "run by itself to tick the card.\n");
+ fflush(stderr);
+ exit(0);
+ }
+ } else {
+ fprintf(stderr, "Watchdog Ticking Away!\n");
+ fflush(stderr);
+ }
+
+ while(1) {
+ keep_alive();
+ sleep(1);
+ }
+}
the watchdog is pinged within a certain time, this time is called the
timeout or margin. The simplest way to ping the watchdog is to write
some data to the device. So a very simple watchdog daemon would look
-like this:
-
-#include <stdlib.h>
-#include <fcntl.h>
-
-int main(int argc, const char *argv[]) {
- int fd=open("/dev/watchdog",O_WRONLY);
- if (fd==-1) {
- perror("watchdog");
- exit(1);
- }
- while(1) {
- write(fd, "\0", 1);
- sleep(10);
- }
-}
+like this source file: see Documentation/watchdog/src/watchdog-simple.c
A more advanced driver could for example check that a HTTP server is
still responding before doing the write call to ping the watchdog.
ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
printf("The timeout was is %d seconds\n", timeout);
-Envinronmental monitoring:
+Pretimeouts:
+
+Some watchdog timers can be set to have a trigger go off before the
+actual time they will reset the system. This can be done with an NMI,
+interrupt, or other mechanism. This allows Linux to record useful
+information (like panic information and kernel coredumps) before it
+resets.
+
+ pretimeout = 10;
+ ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout);
+
+Note that the pretimeout is the number of seconds before the time
+when the timeout will go off. It is not the number of seconds until
+the pretimeout. So, for instance, if you set the timeout to 60 seconds
+and the pretimeout to 10 seconds, the pretimout will go of in 50
+seconds. Setting a pretimeout to zero disables it.
+
+There is also a get function for getting the pretimeout:
+
+ ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout);
+ printf("The pretimeout was is %d seconds\n", timeout);
+
+Not all watchdog drivers will support a pretimeout.
+
+Get the number of seconds before reboot:
+
+Some watchdog drivers have the ability to report the remaining time
+before the system will reboot. The WDIOC_GETTIMELEFT is the ioctl
+that returns the number of seconds before reboot.
+
+ ioctl(fd, WDIOC_GETTIMELEFT, &timeleft);
+ printf("The timeout was is %d seconds\n", timeleft);
+
+Environmental monitoring:
All watchdog drivers are required return more information about the system,
some do temperature, fan and power level monitoring, some can tell you
WDIOF_SETTIMEOUT Can set/get the timeout
+The watchdog can do pretimeouts.
+
+ WDIOF_PRETIMEOUT Pretimeout (in seconds), get/set
+
For those drivers that return any bits set in the option field, the
GETSTATUS and GETBOOTSTATUS ioctls can be used to ask for the current
Minor numbers are however allocated for it.
-Example Watchdog Driver
------------------------
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-int main(int argc, const char *argv[])
-{
- int fd=open("/dev/watchdog",O_WRONLY);
- if(fd==-1)
- {
- perror("watchdog");
- exit(1);
- }
- while(1)
- {
- write(fd,"\0",1);
- fsync(fd);
- sleep(10);
- }
-}
+Example Watchdog Driver: see Documentation/watchdog/src/watchdog-simple.c
Contact Information
u32 *isp;
#endif
+ if (unlikely((unsigned)irq >= NR_IRQS)) {
+ printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
+ __FUNCTION__, irq);
+ BUG();
+ }
+
irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
vma->vm_mm = mm;
ret = insert_vm_struct(mm, vma);
- if (ret)
- goto free_vma;
+ if (unlikely(ret)) {
+ kmem_cache_free(vm_area_cachep, vma);
+ goto up_fail;
+ }
current->mm->context.vdso = (void *)addr;
current_thread_info()->sysenter_return =
up_fail:
up_write(&mm->mmap_sem);
return ret;
-
-free_vma:
- kmem_cache_free(vm_area_cachep, vma);
- return ret;
}
const char *arch_vma_name(struct vm_area_struct *vma)
CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=17
CONFIG_SMP=y
-CONFIG_NR_CPUS=4
+CONFIG_NR_CPUS=16
CONFIG_HOTPLUG_CPU=y
CONFIG_PERMIT_BSP_REMOVE=y
CONFIG_FORCE_CPEI_RETARGET=y
}
/* Register for future delivery via notify registration */
- register_cpu_notifier(&palinfo_cpu_notifier);
+ register_hotcpu_notifier(&palinfo_cpu_notifier);
return 0;
}
* support here so we don't have to listen to failed keyboard probe
* messages.
*/
- if (version <= 0x0209 && acpi_kbd_controller_present) {
+ if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) {
printk(KERN_INFO "Disabling legacy keyboard support as prom "
"is too old and doesn't provide FADT\n");
acpi_kbd_controller_present = 0;
int i;
static int wars_have_been_checked;
- if (smp_processor_id() == 0 && IS_MEDUSA()) {
+ cpuid = smp_processor_id();
+ if (cpuid == 0 && IS_MEDUSA()) {
if (ia64_sn_is_fake_prom())
sn_prom_type = 2;
else
BUG();
sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
+ /*
+ * Don't check status. The SAL call is not supported on all PROMs
+ * but a failure is harmless.
+ */
+ (void) ia64_sn_set_cpu_number(cpuid);
+
/*
* The boot cpu makes this call again after platform initialization is
* complete.
if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0)
break;
- cpuid = smp_processor_id();
cpuphyid = get_sapicid();
if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice))
/* sanity check prom rev */
- if (sn_sal_rev() < 0x0406) {
+ if (is_shub1() && sn_sal_rev() < 0x0406) {
printk
(KERN_ERR "%s: SGI prom rev 4.06 or greater required "
"for tioca support\n", __FUNCTION__);
endchoice
+comment "ROM configuration"
+
+config ROM
+ bool "Specify ROM linker regions"
+ default n
+ help
+ Define a ROM region for the linker script. This creates a kernel
+ that can be stored in flash, with possibly the text, and data
+ regions being copied out to RAM at startup.
+
+config ROMBASE
+ hex "Address of the base of ROM device"
+ default "0"
+ depends on ROM
+ help
+ Define the address that the ROM region starts at. Some platforms
+ use this to set their chip select region accordingly for the boot
+ device.
+
+config ROMVEC
+ hex "Address of the base of the ROM vectors"
+ default "0"
+ depends on ROM
+ help
+ This is almost always the same as the base of the ROM. Since on all
+ 68000 type varients the vectors are at the base of the boot device
+ on system startup.
+
+config ROMVECSIZE
+ hex "Size of ROM vector region (in bytes)"
+ default "0x400"
+ depends on ROM
+ help
+ Define the size of the vector region in ROM. For most 68000
+ varients this would be 0x400 bytes in size. Set to 0 if you do
+ not want a vector region at the start of the ROM.
+
+config ROMSTART
+ hex "Address of the base of system image in ROM"
+ default "0x400"
+ depends on ROM
+ help
+ Define the start address of the system image in ROM. Commonly this
+ is strait after the ROM vectors.
+
+config ROMSIZE
+ hex "Size of the ROM device"
+ default "0x100000"
+ depends on ROM
+ help
+ Size of the ROM device. On some platforms this is used to setup
+ the chip select that controls the boot ROM device.
+
choice
prompt "Kernel executes from"
---help---
*
* (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>
*
- * This ends up looking compilcated, because of the number of
- * address variations for ram and rom/flash layouts. The real
- * work of the linker script is all at the end, and reasonably
- * strait forward.
+ * This linker script is equiped to build either ROM loaded or RAM
+ * run kernels.
*/
#include <linux/config.h>
#include <asm-generic/vmlinux.lds.h>
-/*
- * Original Palm pilot (same for Xcopilot).
- * There is really only a rom target for this.
- */
-#ifdef CONFIG_PILOT3
-#define ROMVEC_START 0x10c00000
-#define ROMVEC_LENGTH 0x10400
-#define ROM_START 0x10c10400
-#define ROM_LENGTH 0xfec00
-#define ROM_END 0x10d00000
-#define DATA_ADDR CONFIG_KERNELBASE
-#endif
-
-/*
- * Same setup on both the uCsimm and uCdimm.
- */
-#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
-#ifdef CONFIG_RAMKERNEL
-#define ROMVEC_START 0x10c10000
-#define ROMVEC_LENGTH 0x400
-#define ROM_START 0x10c10400
-#define ROM_LENGTH 0x1efc00
-#define ROM_END 0x10e00000
-#endif
-#ifdef CONFIG_ROMKERNEL
-#define ROMVEC_START 0x10c10000
-#define ROMVEC_LENGTH 0x400
-#define ROM_START 0x10c10400
-#define ROM_LENGTH 0x1efc00
-#define ROM_END 0x10e00000
-#endif
-#ifdef CONFIG_HIMEMKERNEL
-#define ROMVEC_START 0x00600000
-#define ROMVEC_LENGTH 0x400
-#define ROM_START 0x00600400
-#define ROM_LENGTH 0x1efc00
-#define ROM_END 0x007f0000
-#endif
-#endif
-
-#ifdef CONFIG_UCQUICC
-#define ROMVEC_START 0x00000000
-#define ROMVEC_LENGTH 0x404
-#define ROM_START 0x00000404
-#define ROM_LENGTH 0x1ff6fc
-#define ROM_END 0x00200000
-#endif
-
#if defined(CONFIG_RAMKERNEL)
#define RAM_START CONFIG_KERNELBASE
#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
#define RAM_START CONFIG_RAMBASE
#define RAM_LENGTH CONFIG_RAMSIZE
+#define ROMVEC_START CONFIG_ROMVEC
+#define ROMVEC_LENGTH CONFIG_ROMVECSIZE
+#define ROM_START CONFIG_ROMSTART
+#define ROM_LENGTH CONFIG_ROMSIZE
#define TEXT rom
#define DATA ram
#define INIT ram
#ifdef ROM_START
romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH
- erom : ORIGIN = ROM_END, LENGTH = 0
#endif
}
_etext = . ;
} > TEXT
-#ifdef ROM_END
- . = ROM_END ;
- .erom : {
- __rom_end = . ;
- } > erom
-#endif
-
.data DATA_ADDR : {
. = ALIGN(4);
_sdata = . ;
obj-y += entry.o ints.o timers.o
obj-$(CONFIG_M68328) += config.o
+obj-$(CONFIG_ROM) += romvec.o
extra-y := head.o
extra-$(CONFIG_M68328) += bootlogo.rh head.o
#include <asm/system.h>
#include <asm/irq.h>
+#include <asm/irqnode.h>
#include <asm/traps.h>
#include <asm/io.h>
#include <asm/machdep.h>
/* irq node variables for the 32 (potential) on chip sources */
static irq_node_t int_irq_list[NR_IRQS];
-#if !defined(CONFIG_DRAGEN2)
-asm (".global _start, __ramend/n/t"
- ".section .romvec/n"
- "e_vectors:\n\t"
- ".long __ramend-4, _start, buserr, trap, trap, trap, trap, trap\n\t"
- ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
- ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
- ".long trap, trap, trap, trap\n\t"
- ".long trap, trap, trap, trap\n\t"
- /*.long inthandler, inthandler, inthandler, inthandler
- .long inthandler4, inthandler, inthandler, inthandler */
- /* TRAP #0-15 */
- ".long system_call, trap, trap, trap, trap, trap, trap, trap\n\t"
- ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t"
- ".long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\t"
- ".text\n"
- "ignore: rte");
-#endif
-
/*
* This function should be called during kernel startup to initialize
* the IRQ handling routines.
--- /dev/null
+/*
+ * linux/arch/m68knommu/platform/68328/romvec.S
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
+ * Copyright 2006 Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <linux/config.h>
+
+.global _start
+.global _buserr
+.global trap
+.global system_call
+
+.section .romvec
+
+e_vectors:
+.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+/* TRAP #0-15 */
+.long system_call, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
void BSP_reset (void)
{
local_irq_disable();
- asm volatile ("
- moveal #_start, %a0;
- moveb #0, 0xFFFFF300;
- moveal 0(%a0), %sp;
- moveal 4(%a0), %a0;
- jmp (%a0);
- ");
+ asm volatile (
+ "moveal #_start, %a0;\n"
+ "moveb #0, 0xFFFFF300;\n"
+ "moveal 0(%a0), %sp;\n"
+ "moveal 4(%a0), %a0;\n"
+ "jmp (%a0);\n"
+ );
}
unsigned char *scc1_hwaddr;
#include <asm/system.h>
#include <asm/irq.h>
+#include <asm/irqnode.h>
#include <asm/traps.h>
#include <asm/io.h>
#include <asm/machdep.h>
void m68ez328_reset(void)
{
local_irq_disable();
- asm volatile ("
- moveal #0x10c00000, %a0;
- moveb #0, 0xFFFFF300;
- moveal 0(%a0), %sp;
- moveal 4(%a0), %a0;
- jmp (%a0);
- ");
+ asm volatile (
+ "moveal #0x10c00000, %a0;\n"
+ "moveb #0, 0xFFFFF300;\n"
+ "moveal 0(%a0), %sp;\n"
+ "moveal 4(%a0), %a0;\n"
+ "jmp (%a0);\n"
+ );
}
/***************************************************************************/
static void m68vz328_reset(void)
{
local_irq_disable();
- asm volatile ("
- moveal #0x10c00000, %a0;
- moveb #0, 0xFFFFF300;
- moveal 0(%a0), %sp;
- moveal 4(%a0), %a0;
- jmp (%a0);
- ");
+ asm volatile (
+ "moveal #0x10c00000, %a0;\n\t"
+ "moveb #0, 0xFFFFF300;\n\t"
+ "moveal 0(%a0), %sp;\n\t"
+ "moveal 4(%a0), %a0;\n\t"
+ "jmp (%a0);\n"
+ );
}
unsigned char *cs8900a_hwaddr;
down(&pmac_backlight->sem);
props = pmac_backlight->props;
props->brightness = brightness *
- props->max_brightness / OLD_BACKLIGHT_MAX;
+ (props->max_brightness + 1) /
+ (OLD_BACKLIGHT_MAX + 1);
+
+ if (props->brightness > props->max_brightness)
+ props->brightness = props->max_brightness;
+ else if (props->brightness < 0)
+ props->brightness = 0;
+
props->update_status(pmac_backlight);
up(&pmac_backlight->sem);
down(&pmac_backlight->sem);
props = pmac_backlight->props;
+
result = props->brightness *
- OLD_BACKLIGHT_MAX / props->max_brightness;
+ (OLD_BACKLIGHT_MAX + 1) /
+ (props->max_brightness + 1);
+
up(&pmac_backlight->sem);
}
mutex_unlock(&pmac_backlight_mutex);
/* high bit used in ret_from_ code */
unsigned irq = ~regs->orig_rax;
+ if (unlikely(irq >= NR_IRQS)) {
+ printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
+ __FUNCTION__, irq);
+ BUG();
+ }
+
exit_idle();
irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
vmalloc_sync_all();
rcu_assign_pointer(nmi_callback, callback);
}
+EXPORT_SYMBOL_GPL(set_nmi_callback);
void unset_nmi_callback(void)
{
nmi_callback = dummy_nmi_callback;
}
+EXPORT_SYMBOL_GPL(unset_nmi_callback);
#ifdef CONFIG_SYSCTL
{
struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
struct address_space *mapping = file->f_mapping;
- struct address_space_operations *aops = mapping->a_ops;
+ const struct address_space_operations *aops = mapping->a_ops;
pgoff_t index;
unsigned offset, bv_offs;
int len, ret;
error = -EINVAL;
if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- struct address_space_operations *aops = mapping->a_ops;
+ const struct address_space_operations *aops = mapping->a_ops;
/*
* If we can't read - sorry. If we only can't write - well,
* it's going to be read-only.
return 0;
}
-static struct address_space_operations ramdisk_aops = {
+static const struct address_space_operations ramdisk_aops = {
.readpage = ramdisk_readpage,
.prepare_write = ramdisk_prepare_write,
.commit_write = ramdisk_commit_write,
proc_ipmi_root->owner = THIS_MODULE;
#endif /* CONFIG_PROC_FS */
- init_timer(&ipmi_timer);
- ipmi_timer.data = 0;
- ipmi_timer.function = ipmi_timeout;
- ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
- add_timer(&ipmi_timer);
+ setup_timer(&ipmi_timer, ipmi_timeout, 0);
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <asm/irq.h>
-#ifdef CONFIG_HIGH_RES_TIMERS
-#include <linux/hrtime.h>
-# if defined(schedule_next_int)
-/* Old high-res timer code, do translations. */
-# define get_arch_cycles(a) quick_update_jiffies_sub(a)
-# define arch_cycles_per_jiffy cycles_per_jiffies
-# endif
-static inline void add_usec_to_timer(struct timer_list *t, long v)
-{
- t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000);
- while (t->arch_cycle_expires >= arch_cycles_per_jiffy)
- {
- t->expires++;
- t->arch_cycle_expires -= arch_cycles_per_jiffy;
- }
-}
-#endif
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
#include <linux/ipmi_smi.h>
return atomic_notifier_chain_register(&xaction_notifier_list, nb);
}
-static void si_restart_short_timer(struct smi_info *smi_info);
-
static void deliver_recv_msg(struct smi_info *smi_info,
struct ipmi_smi_msg *msg)
{
&& (smi_info->curr_msg == NULL))
{
start_next_msg(smi_info);
- si_restart_short_timer(smi_info);
}
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}
static int initialized = 0;
-/* Must be called with interrupts off and with the si_lock held. */
-static void si_restart_short_timer(struct smi_info *smi_info)
-{
-#if defined(CONFIG_HIGH_RES_TIMERS)
- unsigned long flags;
- unsigned long jiffies_now;
- unsigned long seq;
-
- if (del_timer(&(smi_info->si_timer))) {
- /* If we don't delete the timer, then it will go off
- immediately, anyway. So we only process if we
- actually delete the timer. */
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- jiffies_now = jiffies;
- smi_info->si_timer.expires = jiffies_now;
- smi_info->si_timer.arch_cycle_expires
- = get_arch_cycles(jiffies_now);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
-
- add_timer(&(smi_info->si_timer));
- spin_lock_irqsave(&smi_info->count_lock, flags);
- smi_info->timeout_restarts++;
- spin_unlock_irqrestore(&smi_info->count_lock, flags);
- }
-#endif
-}
-
static void smi_timeout(unsigned long data)
{
struct smi_info *smi_info = (struct smi_info *) data;
/* If the state machine asks for a short delay, then shorten
the timer timeout. */
if (smi_result == SI_SM_CALL_WITH_DELAY) {
-#if defined(CONFIG_HIGH_RES_TIMERS)
- unsigned long seq;
-#endif
spin_lock_irqsave(&smi_info->count_lock, flags);
smi_info->short_timeouts++;
spin_unlock_irqrestore(&smi_info->count_lock, flags);
-#if defined(CONFIG_HIGH_RES_TIMERS)
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- smi_info->si_timer.expires = jiffies;
- smi_info->si_timer.arch_cycle_expires
- = get_arch_cycles(smi_info->si_timer.expires);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
- add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
-#else
smi_info->si_timer.expires = jiffies + 1;
-#endif
} else {
spin_lock_irqsave(&smi_info->count_lock, flags);
smi_info->long_timeouts++;
spin_unlock_irqrestore(&smi_info->count_lock, flags);
smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
-#if defined(CONFIG_HIGH_RES_TIMERS)
- smi_info->si_timer.arch_cycle_expires = 0;
-#endif
}
do_add_timer:
/* Disable the WDT if we are shutting down. */
ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
panic_halt_ipmi_set_timeout();
- } else {
+ } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
/* Set a long timer to let the reboot happens, but
- reboot if it hangs. */
+ reboot if it hangs, but only if the watchdog
+ timer was already running. */
timeout = 120;
pretimeout = 0;
ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
{
static int panic_event_handled = 0;
- /* On a panic, if we have a panic timeout, make sure that the thing
- reboots, even if it hangs during that panic. */
- if (watchdog_user && !panic_event_handled) {
- /* Make sure the panic doesn't hang, and make sure we
- do this only once. */
+ /* On a panic, if we have a panic timeout, make sure to extend
+ the watchdog timer to a reasonable value to complete the
+ panic, if the watchdog timer is running. Plus the
+ pretimeout is meaningless at panic time. */
+ if (watchdog_user && !panic_event_handled &&
+ ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
+ /* Make sure we do this only once. */
panic_event_handled = 1;
timeout = 255;
pretimeout = 0;
- ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
panic_halt_ipmi_set_timeout();
}
#include <linux/devfs_fs_kernel.h>
#include <linux/device.h>
#include <linux/wait.h>
+#include <linux/eisa.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#ifdef CONFIG_PCI
#include <linux/pci.h>
-#endif
/*****************************************************************************/
static int stli_nrbrds = ARRAY_SIZE(stli_brdconf);
+/* stli_lock must NOT be taken holding brd_lock */
+static spinlock_t stli_lock; /* TTY logic lock */
+static spinlock_t brd_lock; /* Board logic lock */
+
/*
* There is some experimental EISA board detection code in this driver.
* By default it is disabled, but for those that want to try it out,
static struct tty_driver *stli_serial;
-/*
- * We will need to allocate a temporary write buffer for chars that
- * come direct from user space. The problem is that a copy from user
- * space might cause a page fault (typically on a system that is
- * swapping!). All ports will share one buffer - since if the system
- * is already swapping a shared buffer won't make things any worse.
- */
-static char *stli_tmpwritebuf;
#define STLI_TXBUFSIZE 4096
#endif
static struct pci_device_id istallion_pci_tbl[] = {
- { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
-static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
+static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp);
static void stli_poll(unsigned long arg);
static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);
static int stli_setport(stliport_t *portp);
static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
-static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp);
+static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
+static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp);
static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);
static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
static long stli_mktiocm(unsigned long sigvalue);
static int __init istallion_module_init(void)
{
- unsigned long flags;
-
-#ifdef DEBUG
- printk("init_module()\n");
-#endif
-
- save_flags(flags);
- cli();
stli_init();
- restore_flags(flags);
-
- return(0);
+ return 0;
}
/*****************************************************************************/
{
stlibrd_t *brdp;
stliport_t *portp;
- unsigned long flags;
int i, j;
-#ifdef DEBUG
- printk("cleanup_module()\n");
-#endif
-
printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
stli_drvversion);
- save_flags(flags);
- cli();
-
-/*
- * Free up all allocated resources used by the ports. This includes
- * memory and interrupts.
- */
+ /*
+ * Free up all allocated resources used by the ports. This includes
+ * memory and interrupts.
+ */
if (stli_timeron) {
stli_timeron = 0;
- del_timer(&stli_timerlist);
+ del_timer_sync(&stli_timerlist);
}
i = tty_unregister_driver(stli_serial);
if (i) {
printk("STALLION: failed to un-register tty driver, "
"errno=%d\n", -i);
- restore_flags(flags);
return;
}
put_tty_driver(stli_serial);
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -i);
- kfree(stli_tmpwritebuf);
kfree(stli_txcookbuf);
for (i = 0; (i < stli_nrbrds); i++) {
- if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
+ if ((brdp = stli_brds[i]) == NULL)
continue;
for (j = 0; (j < STL_MAXPORTS); j++) {
portp = brdp->ports[j];
- if (portp != (stliport_t *) NULL) {
- if (portp->tty != (struct tty_struct *) NULL)
+ if (portp != NULL) {
+ if (portp->tty != NULL)
tty_hangup(portp->tty);
kfree(portp);
}
if (brdp->iosize > 0)
release_region(brdp->iobase, brdp->iosize);
kfree(brdp);
- stli_brds[i] = (stlibrd_t *) NULL;
+ stli_brds[i] = NULL;
}
-
- restore_flags(flags);
}
module_init(istallion_module_init);
static void stli_argbrds(void)
{
- stlconf_t conf;
- stlibrd_t *brdp;
- int i;
-
-#ifdef DEBUG
- printk("stli_argbrds()\n");
-#endif
+ stlconf_t conf;
+ stlibrd_t *brdp;
+ int i;
for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {
memset(&conf, 0, sizeof(conf));
if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)
continue;
- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
+ if ((brdp = stli_allocbrd()) == NULL)
continue;
stli_nrbrds = i + 1;
brdp->brdnr = i;
static unsigned long stli_atol(char *str)
{
- unsigned long val;
- int base, c;
- char *sp;
+ unsigned long val;
+ int base, c;
+ char *sp;
val = 0;
sp = str;
static int stli_parsebrd(stlconf_t *confp, char **argp)
{
- char *sp;
- int i;
-
-#ifdef DEBUG
- printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
-#endif
+ char *sp;
+ int i;
- if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
- return(0);
+ if (argp[0] == NULL || *argp[0] == 0)
+ return 0;
for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
*sp = TOLOWER(*sp);
}
confp->brdtype = stli_brdstr[i].type;
- if ((argp[1] != (char *) NULL) && (*argp[1] != 0))
+ if (argp[1] != NULL && *argp[1] != 0)
confp->ioaddr1 = stli_atol(argp[1]);
- if ((argp[2] != (char *) NULL) && (*argp[2] != 0))
+ if (argp[2] != NULL && *argp[2] != 0)
confp->memaddr = stli_atol(argp[2]);
return(1);
}
static int stli_open(struct tty_struct *tty, struct file *filp)
{
- stlibrd_t *brdp;
- stliport_t *portp;
- unsigned int minordev;
- int brdnr, portnr, rc;
-
-#ifdef DEBUG
- printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty,
- (int) filp, tty->name);
-#endif
+ stlibrd_t *brdp;
+ stliport_t *portp;
+ unsigned int minordev;
+ int brdnr, portnr, rc;
minordev = tty->index;
brdnr = MINOR2BRD(minordev);
if (brdnr >= stli_nrbrds)
- return(-ENODEV);
+ return -ENODEV;
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
if ((brdp->state & BST_STARTED) == 0)
- return(-ENODEV);
+ return -ENODEV;
portnr = MINOR2PORT(minordev);
if ((portnr < 0) || (portnr > brdp->nrports))
- return(-ENODEV);
+ return -ENODEV;
portp = brdp->ports[portnr];
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
+ if (portp == NULL)
+ return -ENODEV;
if (portp->devnr < 1)
- return(-ENODEV);
+ return -ENODEV;
/*
if (portp->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&portp->close_wait);
if (portp->flags & ASYNC_HUP_NOTIFY)
- return(-EAGAIN);
- return(-ERESTARTSYS);
+ return -EAGAIN;
+ return -ERESTARTSYS;
}
/*
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_INITIALIZING, &portp->state));
if (signal_pending(current))
- return(-ERESTARTSYS);
+ return -ERESTARTSYS;
if ((portp->flags & ASYNC_INITIALIZED) == 0) {
set_bit(ST_INITIALIZING, &portp->state);
clear_bit(ST_INITIALIZING, &portp->state);
wake_up_interruptible(&portp->raw_wait);
if (rc < 0)
- return(rc);
+ return rc;
}
/*
if (portp->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&portp->close_wait);
if (portp->flags & ASYNC_HUP_NOTIFY)
- return(-EAGAIN);
- return(-ERESTARTSYS);
+ return -EAGAIN;
+ return -ERESTARTSYS;
}
/*
*/
if (!(filp->f_flags & O_NONBLOCK)) {
if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
- return(rc);
+ return rc;
}
portp->flags |= ASYNC_NORMAL_ACTIVE;
- return(0);
+ return 0;
}
/*****************************************************************************/
static void stli_close(struct tty_struct *tty, struct file *filp)
{
- stlibrd_t *brdp;
- stliport_t *portp;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
-#endif
+ stlibrd_t *brdp;
+ stliport_t *portp;
+ unsigned long flags;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&stli_lock, flags);
if (tty_hung_up_p(filp)) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&stli_lock, flags);
return;
}
if ((tty->count == 1) && (portp->refcount != 1))
portp->refcount = 1;
if (portp->refcount-- > 1) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&stli_lock, flags);
return;
}
if (tty == stli_txcooktty)
stli_flushchars(tty);
tty->closing = 1;
+ spin_unlock_irqrestore(&stli_lock, flags);
+
if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, portp->closing_wait);
stli_flushbuffer(tty);
tty->closing = 0;
- portp->tty = (struct tty_struct *) NULL;
+ portp->tty = NULL;
if (portp->openwaitcnt) {
if (portp->close_delay)
portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
wake_up_interruptible(&portp->close_wait);
- restore_flags(flags);
}
/*****************************************************************************/
static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
{
- struct tty_struct *tty;
- asynotify_t nt;
- asyport_t aport;
- int rc;
-
-#ifdef DEBUG
- printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp);
-#endif
+ struct tty_struct *tty;
+ asynotify_t nt;
+ asyport_t aport;
+ int rc;
if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0)
- return(rc);
+ return rc;
memset(&nt, 0, sizeof(asynotify_t));
nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
nt.signal = SG_DCD;
if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
sizeof(asynotify_t), 0)) < 0)
- return(rc);
+ return rc;
tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
- return(-ENODEV);
+ if (tty == NULL)
+ return -ENODEV;
stli_mkasyport(portp, &aport, tty->termios);
if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
sizeof(asyport_t), 0)) < 0)
- return(rc);
+ return rc;
set_bit(ST_GETSIGS, &portp->state);
if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
sizeof(asysigs_t), 1)) < 0)
- return(rc);
+ return rc;
if (test_and_clear_bit(ST_GETSIGS, &portp->state))
portp->sigs = stli_mktiocm(portp->asig.sigvalue);
stli_mkasysigs(&portp->asig, 1, 1);
if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
sizeof(asysigs_t), 0)) < 0)
- return(rc);
+ return rc;
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
{
- volatile cdkhdr_t *hdrp;
- volatile cdkctrl_t *cp;
- volatile unsigned char *bits;
- unsigned long flags;
- int rc;
-
-#ifdef DEBUG
- printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
- (int) brdp, (int) portp, (int) arg, wait);
-#endif
+ cdkhdr_t __iomem *hdrp;
+ cdkctrl_t __iomem *cp;
+ unsigned char __iomem *bits;
+ unsigned long flags;
+ int rc;
/*
* Send a message to the slave to open this port.
*/
- save_flags(flags);
- cli();
/*
* Slave is already closing this port. This can happen if a hangup
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current)) {
- restore_flags(flags);
return -ERESTARTSYS;
}
* memory. Once the message is in set the service bits to say that
* this port wants service.
*/
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
- cp->openarg = arg;
- cp->open = 1;
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+ writel(arg, &cp->openarg);
+ writeb(1, &cp->open);
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
portp->portidx;
- *bits |= portp->portbit;
+ writeb(readb(bits) | portp->portbit, bits);
EBRDDISABLE(brdp);
if (wait == 0) {
- restore_flags(flags);
- return(0);
+ spin_unlock_irqrestore(&brd_lock, flags);
+ return 0;
}
/*
*/
rc = 0;
set_bit(ST_OPENING, &portp->state);
+ spin_unlock_irqrestore(&brd_lock, flags);
+
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_OPENING, &portp->state));
if (signal_pending(current))
rc = -ERESTARTSYS;
- restore_flags(flags);
if ((rc == 0) && (portp->rc != 0))
rc = -EIO;
- return(rc);
+ return rc;
}
/*****************************************************************************/
static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
{
- volatile cdkhdr_t *hdrp;
- volatile cdkctrl_t *cp;
- volatile unsigned char *bits;
- unsigned long flags;
- int rc;
-
-#ifdef DEBUG
- printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
- (int) brdp, (int) portp, (int) arg, wait);
-#endif
-
- save_flags(flags);
- cli();
+ cdkhdr_t __iomem *hdrp;
+ cdkctrl_t __iomem *cp;
+ unsigned char __iomem *bits;
+ unsigned long flags;
+ int rc;
/*
* Slave is already closing this port. This can happen if a hangup
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current)) {
- restore_flags(flags);
return -ERESTARTSYS;
}
}
/*
* Write the close command into shared memory.
*/
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
- cp->closearg = arg;
- cp->close = 1;
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+ writel(arg, &cp->closearg);
+ writeb(1, &cp->close);
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
portp->portidx;
- *bits |= portp->portbit;
+ writeb(readb(bits) |portp->portbit, bits);
EBRDDISABLE(brdp);
set_bit(ST_CLOSING, &portp->state);
- if (wait == 0) {
- restore_flags(flags);
- return(0);
- }
+ spin_unlock_irqrestore(&brd_lock, flags);
+
+ if (wait == 0)
+ return 0;
/*
* Slave is in action, so now we must wait for the open acknowledgment
!test_bit(ST_CLOSING, &portp->state));
if (signal_pending(current))
rc = -ERESTARTSYS;
- restore_flags(flags);
if ((rc == 0) && (portp->rc != 0))
rc = -EIO;
- return(rc);
+ return rc;
}
/*****************************************************************************/
static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
{
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
- "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
- (int) arg, size, copyback);
-#endif
-
- save_flags(flags);
- cli();
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_CMDING, &portp->state));
- if (signal_pending(current)) {
- restore_flags(flags);
+ if (signal_pending(current))
return -ERESTARTSYS;
- }
stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
wait_event_interruptible(portp->raw_wait,
!test_bit(ST_CMDING, &portp->state));
- if (signal_pending(current)) {
- restore_flags(flags);
+ if (signal_pending(current))
return -ERESTARTSYS;
- }
- restore_flags(flags);
if (portp->rc != 0)
- return(-EIO);
- return(0);
+ return -EIO;
+ return 0;
}
/*****************************************************************************/
static int stli_setport(stliport_t *portp)
{
- stlibrd_t *brdp;
- asyport_t aport;
-
-#ifdef DEBUG
- printk("stli_setport(portp=%x)\n", (int) portp);
-#endif
+ stlibrd_t *brdp;
+ asyport_t aport;
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
- if (portp->tty == (struct tty_struct *) NULL)
- return(-ENODEV);
- if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds))
- return(-ENODEV);
+ if (portp == NULL)
+ return -ENODEV;
+ if (portp->tty == NULL)
+ return -ENODEV;
+ if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds)
+ return -ENODEV;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
stli_mkasyport(portp, &aport, portp->tty->termios);
return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)
{
- unsigned long flags;
- int rc, doclocal;
-
-#ifdef DEBUG
- printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n",
- (int) brdp, (int) portp, (int) filp);
-#endif
+ unsigned long flags;
+ int rc, doclocal;
rc = 0;
doclocal = 0;
if (portp->tty->termios->c_cflag & CLOCAL)
doclocal++;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&stli_lock, flags);
portp->openwaitcnt++;
if (! tty_hung_up_p(filp))
portp->refcount--;
+ spin_unlock_irqrestore(&stli_lock, flags);
for (;;) {
stli_mkasysigs(&portp->asig, 1, 1);
interruptible_sleep_on(&portp->open_wait);
}
+ spin_lock_irqsave(&stli_lock, flags);
if (! tty_hung_up_p(filp))
portp->refcount++;
portp->openwaitcnt--;
- restore_flags(flags);
+ spin_unlock_irqrestore(&stli_lock, flags);
- return(rc);
+ return rc;
}
/*****************************************************************************/
static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
- volatile cdkasy_t *ap;
- volatile cdkhdr_t *hdrp;
- volatile unsigned char *bits;
- unsigned char *shbuf, *chbuf;
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned int len, stlen, head, tail, size;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_write(tty=%x,buf=%x,count=%d)\n",
- (int) tty, (int) buf, count);
-#endif
+ cdkasy_t __iomem *ap;
+ cdkhdr_t __iomem *hdrp;
+ unsigned char __iomem *bits;
+ unsigned char __iomem *shbuf;
+ unsigned char *chbuf;
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned int len, stlen, head, tail, size;
+ unsigned long flags;
- if ((tty == (struct tty_struct *) NULL) ||
- (stli_tmpwritebuf == (char *) NULL))
- return(0);
if (tty == stli_txcooktty)
stli_flushchars(tty);
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return(0);
+ if (portp == NULL)
+ return 0;
if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
chbuf = (unsigned char *) buf;
/*
* All data is now local, shove as much as possible into shared memory.
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
- head = (unsigned int) ap->txq.head;
- tail = (unsigned int) ap->txq.tail;
- if (tail != ((unsigned int) ap->txq.tail))
- tail = (unsigned int) ap->txq.tail;
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+ head = (unsigned int) readw(&ap->txq.head);
+ tail = (unsigned int) readw(&ap->txq.tail);
+ if (tail != ((unsigned int) readw(&ap->txq.tail)))
+ tail = (unsigned int) readw(&ap->txq.tail);
size = portp->txsize;
if (head >= tail) {
len = size - (head - tail) - 1;
len = MIN(len, count);
count = 0;
- shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
+ shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset);
while (len > 0) {
stlen = MIN(len, stlen);
- memcpy((shbuf + head), chbuf, stlen);
+ memcpy_toio(shbuf + head, chbuf, stlen);
chbuf += stlen;
len -= stlen;
count += stlen;
}
}
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
- ap->txq.head = head;
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+ writew(head, &ap->txq.head);
if (test_bit(ST_TXBUSY, &portp->state)) {
- if (ap->changed.data & DT_TXEMPTY)
- ap->changed.data &= ~DT_TXEMPTY;
+ if (readl(&ap->changed.data) & DT_TXEMPTY)
+ writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
}
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
portp->portidx;
- *bits |= portp->portbit;
+ writeb(readb(bits) | portp->portbit, bits);
set_bit(ST_TXBUSY, &portp->state);
EBRDDISABLE(brdp);
-
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
return(count);
}
static void stli_putchar(struct tty_struct *tty, unsigned char ch)
{
-#ifdef DEBUG
- printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
if (tty != stli_txcooktty) {
- if (stli_txcooktty != (struct tty_struct *) NULL)
+ if (stli_txcooktty != NULL)
stli_flushchars(stli_txcooktty);
stli_txcooktty = tty;
}
static void stli_flushchars(struct tty_struct *tty)
{
- volatile cdkhdr_t *hdrp;
- volatile unsigned char *bits;
- volatile cdkasy_t *ap;
- struct tty_struct *cooktty;
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned int len, stlen, head, tail, size, count, cooksize;
- unsigned char *buf, *shbuf;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_flushchars(tty=%x)\n", (int) tty);
-#endif
+ cdkhdr_t __iomem *hdrp;
+ unsigned char __iomem *bits;
+ cdkasy_t __iomem *ap;
+ struct tty_struct *cooktty;
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned int len, stlen, head, tail, size, count, cooksize;
+ unsigned char *buf;
+ unsigned char __iomem *shbuf;
+ unsigned long flags;
cooksize = stli_txcooksize;
cooktty = stli_txcooktty;
stli_txcooksize = 0;
stli_txcookrealsize = 0;
- stli_txcooktty = (struct tty_struct *) NULL;
+ stli_txcooktty = NULL;
- if (tty == (struct tty_struct *) NULL)
+ if (tty == NULL)
return;
- if (cooktty == (struct tty_struct *) NULL)
+ if (cooktty == NULL)
return;
if (tty != cooktty)
tty = cooktty;
return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
- head = (unsigned int) ap->txq.head;
- tail = (unsigned int) ap->txq.tail;
- if (tail != ((unsigned int) ap->txq.tail))
- tail = (unsigned int) ap->txq.tail;
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+ head = (unsigned int) readw(&ap->txq.head);
+ tail = (unsigned int) readw(&ap->txq.tail);
+ if (tail != ((unsigned int) readw(&ap->txq.tail)))
+ tail = (unsigned int) readw(&ap->txq.tail);
size = portp->txsize;
if (head >= tail) {
len = size - (head - tail) - 1;
while (len > 0) {
stlen = MIN(len, stlen);
- memcpy((shbuf + head), buf, stlen);
+ memcpy_toio(shbuf + head, buf, stlen);
buf += stlen;
len -= stlen;
count += stlen;
}
}
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
- ap->txq.head = head;
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+ writew(head, &ap->txq.head);
if (test_bit(ST_TXBUSY, &portp->state)) {
- if (ap->changed.data & DT_TXEMPTY)
- ap->changed.data &= ~DT_TXEMPTY;
+ if (readl(&ap->changed.data) & DT_TXEMPTY)
+ writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data);
}
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
portp->portidx;
- *bits |= portp->portbit;
+ writeb(readb(bits) | portp->portbit, bits);
set_bit(ST_TXBUSY, &portp->state);
EBRDDISABLE(brdp);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
}
/*****************************************************************************/
static int stli_writeroom(struct tty_struct *tty)
{
- volatile cdkasyrq_t *rp;
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned int head, tail, len;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_writeroom(tty=%x)\n", (int) tty);
-#endif
+ cdkasyrq_t __iomem *rp;
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned int head, tail, len;
+ unsigned long flags;
- if (tty == (struct tty_struct *) NULL)
- return(0);
if (tty == stli_txcooktty) {
if (stli_txcookrealsize != 0) {
len = stli_txcookrealsize - stli_txcooksize;
- return(len);
+ return len;
}
}
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return(0);
+ if (portp == NULL)
+ return 0;
if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
- head = (unsigned int) rp->head;
- tail = (unsigned int) rp->tail;
- if (tail != ((unsigned int) rp->tail))
- tail = (unsigned int) rp->tail;
+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
+ head = (unsigned int) readw(&rp->head);
+ tail = (unsigned int) readw(&rp->tail);
+ if (tail != ((unsigned int) readw(&rp->tail)))
+ tail = (unsigned int) readw(&rp->tail);
len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head);
len--;
EBRDDISABLE(brdp);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
if (tty == stli_txcooktty) {
stli_txcookrealsize = len;
len -= stli_txcooksize;
}
- return(len);
+ return len;
}
/*****************************************************************************/
static int stli_charsinbuffer(struct tty_struct *tty)
{
- volatile cdkasyrq_t *rp;
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned int head, tail, len;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("stli_charsinbuffer(tty=%x)\n", (int) tty);
-#endif
+ cdkasyrq_t __iomem *rp;
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned int head, tail, len;
+ unsigned long flags;
- if (tty == (struct tty_struct *) NULL)
- return(0);
if (tty == stli_txcooktty)
stli_flushchars(tty);
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return(0);
+ if (portp == NULL)
+ return 0;
if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
- head = (unsigned int) rp->head;
- tail = (unsigned int) rp->tail;
- if (tail != ((unsigned int) rp->tail))
- tail = (unsigned int) rp->tail;
+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq;
+ head = (unsigned int) readw(&rp->head);
+ tail = (unsigned int) readw(&rp->tail);
+ if (tail != ((unsigned int) readw(&rp->tail)))
+ tail = (unsigned int) readw(&rp->tail);
len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head));
if ((len == 0) && test_bit(ST_TXBUSY, &portp->state))
len = 1;
EBRDDISABLE(brdp);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
- return(len);
+ return len;
}
/*****************************************************************************/
static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)
{
- struct serial_struct sio;
- stlibrd_t *brdp;
-
-#ifdef DEBUG
- printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
+ struct serial_struct sio;
+ stlibrd_t *brdp;
memset(&sio, 0, sizeof(struct serial_struct));
sio.type = PORT_UNKNOWN;
sio.hub6 = 0;
brdp = stli_brds[portp->brdnr];
- if (brdp != (stlibrd_t *) NULL)
+ if (brdp != NULL)
sio.port = brdp->iobase;
return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ?
static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)
{
- struct serial_struct sio;
- int rc;
-
-#ifdef DEBUG
- printk("stli_setserial(portp=%p,sp=%p)\n", portp, sp);
-#endif
+ struct serial_struct sio;
+ int rc;
if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
return -EFAULT;
(sio.close_delay != portp->close_delay) ||
((sio.flags & ~ASYNC_USR_MASK) !=
(portp->flags & ~ASYNC_USR_MASK)))
- return(-EPERM);
+ return -EPERM;
}
portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
portp->custom_divisor = sio.custom_divisor;
if ((rc = stli_setport(portp)) < 0)
- return(rc);
- return(0);
+ return rc;
+ return 0;
}
/*****************************************************************************/
stlibrd_t *brdp;
int rc;
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ if (portp == NULL)
+ return -ENODEV;
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
if (tty->flags & (1 << TTY_IO_ERROR))
- return(-EIO);
+ return -EIO;
if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
&portp->asig, sizeof(asysigs_t), 1)) < 0)
- return(rc);
+ return rc;
return stli_mktiocm(portp->asig.sigvalue);
}
stlibrd_t *brdp;
int rts = -1, dtr = -1;
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ if (portp == NULL)
+ return -ENODEV;
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
if (tty->flags & (1 << TTY_IO_ERROR))
- return(-EIO);
+ return -EIO;
if (set & TIOCM_RTS)
rts = 1;
static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
{
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned int ival;
- int rc;
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned int ival;
+ int rc;
void __user *argp = (void __user *)arg;
-#ifdef DEBUG
- printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
- (int) tty, (int) file, cmd, (int) arg);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return(-ENODEV);
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return(0);
+ if (portp == NULL)
+ return -ENODEV;
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+ return 0;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(0);
+ if (brdp == NULL)
+ return 0;
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
if (tty->flags & (1 << TTY_IO_ERROR))
- return(-EIO);
+ return -EIO;
}
rc = 0;
break;
}
- return(rc);
+ return rc;
}
/*****************************************************************************/
static void stli_settermios(struct tty_struct *tty, struct termios *old)
{
- stliport_t *portp;
- stlibrd_t *brdp;
- struct termios *tiosp;
- asyport_t aport;
-
-#ifdef DEBUG
- printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
-#endif
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ struct termios *tiosp;
+ asyport_t aport;
- if (tty == (struct tty_struct *) NULL)
+ if (tty == NULL)
return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
tiosp = tty->termios;
static void stli_throttle(struct tty_struct *tty)
{
- stliport_t *portp;
-
-#ifdef DEBUG
- printk("stli_throttle(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ stliport_t *portp = tty->driver_data;
+ if (portp == NULL)
return;
-
set_bit(ST_RXSTOP, &portp->state);
}
static void stli_unthrottle(struct tty_struct *tty)
{
- stliport_t *portp;
-
-#ifdef DEBUG
- printk("stli_unthrottle(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
+ stliport_t *portp = tty->driver_data;
+ if (portp == NULL)
return;
- portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return;
-
clear_bit(ST_RXSTOP, &portp->state);
}
/*****************************************************************************/
/*
- * Stop the transmitter. Basically to do this we will just turn TX
- * interrupts off.
+ * Stop the transmitter.
*/
static void stli_stop(struct tty_struct *tty)
{
- stlibrd_t *brdp;
- stliport_t *portp;
- asyctrl_t actrl;
-
-#ifdef DEBUG
- printk("stli_stop(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return;
- brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return;
-
- memset(&actrl, 0, sizeof(asyctrl_t));
- actrl.txctrl = CT_STOPFLOW;
-#if 0
- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
-#endif
}
/*****************************************************************************/
/*
- * Start the transmitter again. Just turn TX interrupts back on.
+ * Start the transmitter again.
*/
static void stli_start(struct tty_struct *tty)
{
- stliport_t *portp;
- stlibrd_t *brdp;
- asyctrl_t actrl;
-
-#ifdef DEBUG
- printk("stli_start(tty=%x)\n", (int) tty);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
- portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
- return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
- return;
- brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return;
-
- memset(&actrl, 0, sizeof(asyctrl_t));
- actrl.txctrl = CT_STARTFLOW;
-#if 0
- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
-#endif
}
/*****************************************************************************/
static void stli_dohangup(void *arg)
{
- stliport_t *portp;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg);
-#endif
-
- /*
- * FIXME: There's a module removal race here: tty_hangup
- * calls schedule_work which will call into this
- * driver later.
- */
- portp = (stliport_t *) arg;
- if (portp != (stliport_t *) NULL) {
- if (portp->tty != (struct tty_struct *) NULL) {
- tty_hangup(portp->tty);
- }
+ stliport_t *portp = (stliport_t *) arg;
+ if (portp->tty != NULL) {
+ tty_hangup(portp->tty);
}
}
static void stli_hangup(struct tty_struct *tty)
{
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned long flags;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty);
-#endif
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned long flags;
- if (tty == (struct tty_struct *) NULL)
- return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
portp->flags &= ~ASYNC_INITIALIZED;
- save_flags(flags);
- cli();
- if (! test_bit(ST_CLOSING, &portp->state))
+ if (!test_bit(ST_CLOSING, &portp->state))
stli_rawclose(brdp, portp, 0, 0);
+
+ spin_lock_irqsave(&stli_lock, flags);
if (tty->termios->c_cflag & HUPCL) {
stli_mkasysigs(&portp->asig, 0, 0);
if (test_bit(ST_CMDING, &portp->state)) {
&portp->asig, sizeof(asysigs_t), 0);
}
}
- restore_flags(flags);
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
set_bit(TTY_IO_ERROR, &tty->flags);
- portp->tty = (struct tty_struct *) NULL;
+ portp->tty = NULL;
portp->flags &= ~ASYNC_NORMAL_ACTIVE;
portp->refcount = 0;
+ spin_unlock_irqrestore(&stli_lock, flags);
+
wake_up_interruptible(&portp->open_wait);
}
static void stli_flushbuffer(struct tty_struct *tty)
{
- stliport_t *portp;
- stlibrd_t *brdp;
- unsigned long ftype, flags;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty);
-#endif
+ stliport_t *portp;
+ stlibrd_t *brdp;
+ unsigned long ftype, flags;
- if (tty == (struct tty_struct *) NULL)
- return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
if (tty == stli_txcooktty) {
- stli_txcooktty = (struct tty_struct *) NULL;
+ stli_txcooktty = NULL;
stli_txcooksize = 0;
stli_txcookrealsize = 0;
}
ftype |= FLUSHRX;
clear_bit(ST_DOFLUSHRX, &portp->state);
}
- stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
- sizeof(unsigned long), 0);
+ __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
}
- restore_flags(flags);
-
- wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
+ spin_unlock_irqrestore(&brd_lock, flags);
+ tty_wakeup(tty);
}
/*****************************************************************************/
stlibrd_t *brdp;
stliport_t *portp;
long arg;
- /* long savestate, savetime; */
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
-/*
- * Due to a bug in the tty send_break() code we need to preserve
- * the current process state and timeout...
- savetime = current->timeout;
- savestate = current->state;
- */
-
arg = (state == -1) ? BREAKON : BREAKOFF;
stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
-
-/*
- *
- current->timeout = savetime;
- current->state = savestate;
- */
}
/*****************************************************************************/
static void stli_waituntilsent(struct tty_struct *tty, int timeout)
{
- stliport_t *portp;
- unsigned long tend;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout);
-#endif
+ stliport_t *portp;
+ unsigned long tend;
- if (tty == (struct tty_struct *) NULL)
+ if (tty == NULL)
return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
if (timeout == 0)
stliport_t *portp;
asyctrl_t actrl;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);
-#endif
-
- if (tty == (struct tty_struct *) NULL)
- return;
portp = tty->driver_data;
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
return;
- if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+ if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
return;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
return;
memset(&actrl, 0, sizeof(asyctrl_t));
actrl.txctrl = CT_SENDCHR;
actrl.tximdch = ch;
}
-
stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
}
static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos)
{
- char *sp, *uart;
- int rc, cnt;
+ char *sp, *uart;
+ int rc, cnt;
rc = stli_portcmdstats(portp);
uart = "UNKNOWN";
if (brdp->state & BST_STARTED) {
switch (stli_comstats.hwid) {
- case 0: uart = "2681"; break;
- case 1: uart = "SC26198"; break;
- default: uart = "CD1400"; break;
+ case 0: uart = "2681"; break;
+ case 1: uart = "SC26198"; break;
+ default:uart = "CD1400"; break;
}
}
static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- stlibrd_t *brdp;
- stliport_t *portp;
- int brdnr, portnr, totalport;
- int curoff, maxoff;
- char *pos;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"
- "data=%x\n", (int) page, (int) start, (int) off, count,
- (int) eof, (int) data);
-#endif
+ stlibrd_t *brdp;
+ stliport_t *portp;
+ int brdnr, portnr, totalport;
+ int curoff, maxoff;
+ char *pos;
pos = page;
totalport = 0;
*/
for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
continue;
if (brdp->state == 0)
continue;
for (portnr = 0; (portnr < brdp->nrports); portnr++,
totalport++) {
portp = brdp->ports[portnr];
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
continue;
if (off >= (curoff += MAXLINE))
continue;
* a poll routine that does not have user context. Therefore you cannot
* copy back directly into user space, or to the kernel stack of a
* process. This routine does not sleep, so can be called from anywhere.
+ *
+ * The caller must hold the brd_lock (see also stli_sendcmd the usual
+ * entry point)
*/
-static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
{
- volatile cdkhdr_t *hdrp;
- volatile cdkctrl_t *cp;
- volatile unsigned char *bits;
- unsigned long flags;
+ cdkhdr_t __iomem *hdrp;
+ cdkctrl_t __iomem *cp;
+ unsigned char __iomem *bits;
+ unsigned long flags;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
- "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
- (int) arg, size, copyback);
-#endif
-
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&brd_lock, flags);
if (test_bit(ST_CMDING, &portp->state)) {
printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",
(int) cmd);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
return;
}
EBRDENABLE(brdp);
- cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
+ cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl;
if (size > 0) {
- memcpy((void *) &(cp->args[0]), arg, size);
+ memcpy_toio((void __iomem *) &(cp->args[0]), arg, size);
if (copyback) {
portp->argp = arg;
portp->argsize = size;
}
}
- cp->status = 0;
- cp->cmd = cmd;
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ writel(0, &cp->status);
+ writel(cmd, &cp->cmd);
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset +
portp->portidx;
- *bits |= portp->portbit;
+ writeb(readb(bits) | portp->portbit, bits);
set_bit(ST_CMDING, &portp->state);
EBRDDISABLE(brdp);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
+}
+
+static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&brd_lock, flags);
+ __stli_sendcmd(brdp, portp, cmd, arg, size, copyback);
+ spin_unlock_irqrestore(&brd_lock, flags);
}
/*****************************************************************************/
static void stli_read(stlibrd_t *brdp, stliport_t *portp)
{
- volatile cdkasyrq_t *rp;
- volatile char *shbuf;
+ cdkasyrq_t __iomem *rp;
+ char __iomem *shbuf;
struct tty_struct *tty;
- unsigned int head, tail, size;
- unsigned int len, stlen;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n",
- (int) brdp, (int) portp);
-#endif
+ unsigned int head, tail, size;
+ unsigned int len, stlen;
if (test_bit(ST_RXSTOP, &portp->state))
return;
tty = portp->tty;
- if (tty == (struct tty_struct *) NULL)
+ if (tty == NULL)
return;
- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
- head = (unsigned int) rp->head;
- if (head != ((unsigned int) rp->head))
- head = (unsigned int) rp->head;
- tail = (unsigned int) rp->tail;
+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
+ head = (unsigned int) readw(&rp->head);
+ if (head != ((unsigned int) readw(&rp->head)))
+ head = (unsigned int) readw(&rp->head);
+ tail = (unsigned int) readw(&rp->tail);
size = portp->rxsize;
if (head >= tail) {
len = head - tail;
}
len = tty_buffer_request_room(tty, len);
- /* FIXME : iomap ? */
- shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
+
+ shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset);
while (len > 0) {
+ unsigned char *cptr;
+
stlen = MIN(len, stlen);
- tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen);
+ tty_prepare_flip_string(tty, &cptr, stlen);
+ memcpy_fromio(cptr, shbuf + tail, stlen);
len -= stlen;
tail += stlen;
if (tail >= size) {
stlen = head;
}
}
- rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
- rp->tail = tail;
+ rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq;
+ writew(tail, &rp->tail);
if (head != tail)
set_bit(ST_RXING, &portp->state);
* difficult to deal with them here.
*/
-static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp)
+static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp)
{
- int cmd;
+ int cmd;
if (test_bit(ST_DOSIGS, &portp->state)) {
if (test_bit(ST_DOFLUSHTX, &portp->state) &&
clear_bit(ST_DOFLUSHTX, &portp->state);
clear_bit(ST_DOFLUSHRX, &portp->state);
clear_bit(ST_DOSIGS, &portp->state);
- memcpy((void *) &(cp->args[0]), (void *) &portp->asig,
+ memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig,
sizeof(asysigs_t));
- cp->status = 0;
- cp->cmd = cmd;
+ writel(0, &cp->status);
+ writel(cmd, &cp->cmd);
set_bit(ST_CMDING, &portp->state);
} else if (test_bit(ST_DOFLUSHTX, &portp->state) ||
test_bit(ST_DOFLUSHRX, &portp->state)) {
cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
clear_bit(ST_DOFLUSHTX, &portp->state);
clear_bit(ST_DOFLUSHRX, &portp->state);
- memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int));
- cp->status = 0;
- cp->cmd = A_FLUSH;
+ memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int));
+ writel(0, &cp->status);
+ writel(A_FLUSH, &cp->cmd);
set_bit(ST_CMDING, &portp->state);
}
}
static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
{
- volatile cdkasy_t *ap;
- volatile cdkctrl_t *cp;
- struct tty_struct *tty;
- asynotify_t nt;
- unsigned long oldsigs;
- int rc, donerx;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n",
- (int) brdp, channr);
-#endif
-
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
+ cdkasy_t __iomem *ap;
+ cdkctrl_t __iomem *cp;
+ struct tty_struct *tty;
+ asynotify_t nt;
+ unsigned long oldsigs;
+ int rc, donerx;
+
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
cp = &ap->ctrl;
/*
* Check if we are waiting for an open completion message.
*/
if (test_bit(ST_OPENING, &portp->state)) {
- rc = (int) cp->openarg;
- if ((cp->open == 0) && (rc != 0)) {
+ rc = readl(&cp->openarg);
+ if (readb(&cp->open) == 0 && rc != 0) {
if (rc > 0)
rc--;
- cp->openarg = 0;
+ writel(0, &cp->openarg);
portp->rc = rc;
clear_bit(ST_OPENING, &portp->state);
wake_up_interruptible(&portp->raw_wait);
* Check if we are waiting for a close completion message.
*/
if (test_bit(ST_CLOSING, &portp->state)) {
- rc = (int) cp->closearg;
- if ((cp->close == 0) && (rc != 0)) {
+ rc = (int) readl(&cp->closearg);
+ if (readb(&cp->close) == 0 && rc != 0) {
if (rc > 0)
rc--;
- cp->closearg = 0;
+ writel(0, &cp->closearg);
portp->rc = rc;
clear_bit(ST_CLOSING, &portp->state);
wake_up_interruptible(&portp->raw_wait);
* need to copy out the command results associated with this command.
*/
if (test_bit(ST_CMDING, &portp->state)) {
- rc = cp->status;
- if ((cp->cmd == 0) && (rc != 0)) {
+ rc = readl(&cp->status);
+ if (readl(&cp->cmd) == 0 && rc != 0) {
if (rc > 0)
rc--;
- if (portp->argp != (void *) NULL) {
- memcpy(portp->argp, (void *) &(cp->args[0]),
+ if (portp->argp != NULL) {
+ memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]),
portp->argsize);
- portp->argp = (void *) NULL;
+ portp->argp = NULL;
}
- cp->status = 0;
+ writel(0, &cp->status);
portp->rc = rc;
clear_bit(ST_CMDING, &portp->state);
stli_dodelaycmd(portp, cp);
if (nt.data & DT_TXEMPTY)
clear_bit(ST_TXBUSY, &portp->state);
if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
- if (tty != (struct tty_struct *) NULL) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup) {
- (tty->ldisc.write_wakeup)(tty);
- EBRDENABLE(brdp);
- }
+ if (tty != NULL) {
+ tty_wakeup(tty);
+ EBRDENABLE(brdp);
wake_up_interruptible(&tty->write_wait);
}
}
if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
- if (tty != (struct tty_struct *) NULL) {
+ if (tty != NULL) {
tty_insert_flip_char(tty, 0, TTY_BREAK);
if (portp->flags & ASYNC_SAK) {
do_SAK(tty);
* at the cdk header structure.
*/
-static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
+static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp)
{
- stliport_t *portp;
- unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
- unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
- unsigned char *slavep;
- int bitpos, bitat, bitsize;
- int channr, nrdevs, slavebitchange;
+ stliport_t *portp;
+ unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
+ unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
+ unsigned char __iomem *slavep;
+ int bitpos, bitat, bitsize;
+ int channr, nrdevs, slavebitchange;
bitsize = brdp->bitsize;
nrdevs = brdp->nrdevs;
* 8 service bits at a time in the inner loop, so we can bypass
* the lot if none of them want service.
*/
- memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset),
+ memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset),
bitsize);
memset(&slavebits[0], 0, bitsize);
* service may initiate more slave requests.
*/
if (slavebitchange) {
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset;
for (bitpos = 0; (bitpos < bitsize); bitpos++) {
- if (slavebits[bitpos])
- slavep[bitpos] &= ~slavebits[bitpos];
+ if (readb(slavebits + bitpos))
+ writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos);
}
}
}
static void stli_poll(unsigned long arg)
{
- volatile cdkhdr_t *hdrp;
- stlibrd_t *brdp;
- int brdnr;
+ cdkhdr_t __iomem *hdrp;
+ stlibrd_t *brdp;
+ int brdnr;
stli_timerlist.expires = STLI_TIMEOUT;
add_timer(&stli_timerlist);
*/
for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) {
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
continue;
if ((brdp->state & BST_STARTED) == 0)
continue;
+ spin_lock(&brd_lock);
EBRDENABLE(brdp);
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- if (hdrp->hostreq)
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ if (readb(&hdrp->hostreq))
stli_brdpoll(brdp, hdrp);
EBRDDISABLE(brdp);
+ spin_unlock(&brd_lock);
}
}
static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n",
- (int) portp, (int) pp, (int) tiosp);
-#endif
-
memset(pp, 0, sizeof(asyport_t));
/*
static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n",
- (int) sp, dtr, rts);
-#endif
-
memset(sp, 0, sizeof(asysigs_t));
if (dtr >= 0) {
sp->signal |= SG_DTR;
static long stli_mktiocm(unsigned long sigvalue)
{
- long tiocm;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue);
-#endif
-
- tiocm = 0;
+ long tiocm = 0;
tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0);
tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0);
tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0);
stliport_t *portp;
int i, panelnr, panelport;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp);
-#endif
-
for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);
if (!portp) {
brdp->ports[i] = portp;
}
- return(0);
+ return 0;
}
/*****************************************************************************/
{
unsigned long memconf;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp);
-#endif
-
outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
udelay(10);
outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
static void stli_ecpenable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp);
-#endif
outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));
}
static void stli_ecpdisable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp);
-#endif
outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
}
static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
{
- void *ptr;
- unsigned char val;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
- (int) offset);
-#endif
+ void *ptr;
+ unsigned char val;
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
static void stli_ecpreset(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp);
-#endif
-
outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
udelay(10);
outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
static void stli_ecpintr(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp);
-#endif
outb(0x1, brdp->iobase);
}
{
unsigned long memconf;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp);
-#endif
-
outb(0x1, (brdp->iobase + ECP_EIBRDENAB));
outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
udelay(10);
void *ptr;
unsigned char val;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
- (int) brdp, (int) offset, line);
-#endif
-
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
"range at line=%d(%d), brd=%d\n",
static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
{
- void *ptr;
- unsigned char val;
+ void *ptr;
+ unsigned char val;
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
static void stli_ecppciinit(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp);
-#endif
-
outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
udelay(10);
outb(0, (brdp->iobase + ECP_PCICONFR));
void *ptr;
unsigned char val;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n",
- (int) brdp, (int) offset, line);
-#endif
-
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
"range at line=%d(%d), board=%d\n",
{
unsigned long memconf;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp);
-#endif
-
outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
udelay(10);
outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
static void stli_onbenable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp);
-#endif
outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));
}
static void stli_onbdisable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp);
-#endif
outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));
}
{
void *ptr;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
- (int) offset);
-#endif
-
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
"range at line=%d(%d), brd=%d\n",
static void stli_onbreset(stlibrd_t *brdp)
{
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp);
-#endif
-
outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
udelay(10);
outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR));
{
unsigned long memconf;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp);
-#endif
-
outb(0x1, (brdp->iobase + ONB_EIBRDENAB));
outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
udelay(10);
static void stli_onbeenable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp);
-#endif
outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));
}
static void stli_onbedisable(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp);
-#endif
outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
}
static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
{
- void *ptr;
- unsigned char val;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n",
- (int) brdp, (int) offset, line);
-#endif
+ void *ptr;
+ unsigned char val;
if (offset > brdp->memsize) {
printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
static void stli_onbereset(stlibrd_t *brdp)
{
-
-#ifdef DEBUG
- printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp);
-#endif
-
outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
udelay(10);
outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
static void stli_bbyinit(stlibrd_t *brdp)
{
-
-#ifdef DEBUG
- printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp);
-#endif
-
outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
udelay(10);
outb(0, (brdp->iobase + BBY_ATCONFR));
static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
{
- void *ptr;
- unsigned char val;
+ void *ptr;
+ unsigned char val;
-#ifdef DEBUG
- printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
- (int) offset);
-#endif
+ BUG_ON(offset > brdp->memsize);
- if (offset > brdp->memsize) {
- printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
- "range at line=%d(%d), brd=%d\n",
- (int) offset, line, __LINE__, brdp->brdnr);
- ptr = NULL;
- val = 0;
- } else {
- ptr = brdp->membase + (offset % BBY_PAGESIZE);
- val = (unsigned char) (offset / BBY_PAGESIZE);
- }
+ ptr = brdp->membase + (offset % BBY_PAGESIZE);
+ val = (unsigned char) (offset / BBY_PAGESIZE);
outb(val, (brdp->iobase + BBY_ATCONFR));
return(ptr);
}
static void stli_bbyreset(stlibrd_t *brdp)
{
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp);
-#endif
-
outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
udelay(10);
outb(0, (brdp->iobase + BBY_ATCONFR));
static void stli_stalinit(stlibrd_t *brdp)
{
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp);
-#endif
-
outb(0x1, brdp->iobase);
mdelay(1000);
}
static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
{
- void *ptr;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
- (int) offset);
-#endif
-
- if (offset > brdp->memsize) {
- printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
- "range at line=%d(%d), brd=%d\n",
- (int) offset, line, __LINE__, brdp->brdnr);
- ptr = NULL;
- } else {
- ptr = brdp->membase + (offset % STAL_PAGESIZE);
- }
- return(ptr);
+ BUG_ON(offset > brdp->memsize);
+ return brdp->membase + (offset % STAL_PAGESIZE);
}
/*****************************************************************************/
static void stli_stalreset(stlibrd_t *brdp)
{
- volatile unsigned long *vecp;
+ u32 __iomem *vecp;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp);
-#endif
-
- vecp = (volatile unsigned long *) (brdp->membase + 0x30);
- *vecp = 0xffff0000;
+ vecp = (u32 __iomem *) (brdp->membase + 0x30);
+ writel(0xffff0000, vecp);
outb(0, brdp->iobase);
mdelay(1000);
}
static int stli_initecp(stlibrd_t *brdp)
{
- cdkecpsig_t sig;
- cdkecpsig_t *sigsp;
- unsigned int status, nxtid;
- char *name;
- int panelnr, nrports;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp);
-#endif
+ cdkecpsig_t sig;
+ cdkecpsig_t __iomem *sigsp;
+ unsigned int status, nxtid;
+ char *name;
+ int panelnr, nrports;
if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
return -EIO;
if ((brdp->iobase == 0) || (brdp->memaddr == 0))
{
release_region(brdp->iobase, brdp->iosize);
- return(-ENODEV);
+ return -ENODEV;
}
brdp->iosize = ECP_IOSIZE;
default:
release_region(brdp->iobase, brdp->iosize);
- return(-EINVAL);
+ return -EINVAL;
}
/*
EBRDINIT(brdp);
brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
- if (brdp->membase == (void *) NULL)
+ if (brdp->membase == NULL)
{
release_region(brdp->iobase, brdp->iosize);
- return(-ENOMEM);
+ return -ENOMEM;
}
/*
* this is, and what it is connected to it.
*/
EBRDENABLE(brdp);
- sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
+ sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
memcpy(&sig, sigsp, sizeof(cdkecpsig_t));
EBRDDISABLE(brdp);
-#if 0
- printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
- __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],
- (int) sig.panelid[1], (int) sig.panelid[2],
- (int) sig.panelid[3], (int) sig.panelid[4],
- (int) sig.panelid[5], (int) sig.panelid[6],
- (int) sig.panelid[7]);
-#endif
-
- if (sig.magic != ECP_MAGIC)
+ if (sig.magic != cpu_to_le32(ECP_MAGIC))
{
release_region(brdp->iobase, brdp->iosize);
- return(-ENODEV);
+ return -ENODEV;
}
/*
brdp->state |= BST_FOUND;
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_initonb(stlibrd_t *brdp)
{
- cdkonbsig_t sig;
- cdkonbsig_t *sigsp;
- char *name;
- int i;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp);
-#endif
+ cdkonbsig_t sig;
+ cdkonbsig_t __iomem *sigsp;
+ char *name;
+ int i;
/*
* Do a basic sanity check on the IO and memory addresses.
*/
- if ((brdp->iobase == 0) || (brdp->memaddr == 0))
- return(-ENODEV);
+ if (brdp->iobase == 0 || brdp->memaddr == 0)
+ return -ENODEV;
brdp->iosize = ONB_IOSIZE;
case BRD_ONBOARD2:
case BRD_ONBOARD2_32:
case BRD_ONBOARDRS:
- brdp->membase = (void *) brdp->memaddr;
brdp->memsize = ONB_MEMSIZE;
brdp->pagesize = ONB_ATPAGESIZE;
brdp->init = stli_onbinit;
break;
case BRD_ONBOARDE:
- brdp->membase = (void *) brdp->memaddr;
brdp->memsize = ONB_EIMEMSIZE;
brdp->pagesize = ONB_EIPAGESIZE;
brdp->init = stli_onbeinit;
case BRD_BRUMBY4:
case BRD_BRUMBY8:
case BRD_BRUMBY16:
- brdp->membase = (void *) brdp->memaddr;
brdp->memsize = BBY_MEMSIZE;
brdp->pagesize = BBY_PAGESIZE;
brdp->init = stli_bbyinit;
break;
case BRD_STALLION:
- brdp->membase = (void *) brdp->memaddr;
brdp->memsize = STAL_MEMSIZE;
brdp->pagesize = STAL_PAGESIZE;
brdp->init = stli_stalinit;
default:
release_region(brdp->iobase, brdp->iosize);
- return(-EINVAL);
+ return -EINVAL;
}
/*
EBRDINIT(brdp);
brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
- if (brdp->membase == (void *) NULL)
+ if (brdp->membase == NULL)
{
release_region(brdp->iobase, brdp->iosize);
- return(-ENOMEM);
+ return -ENOMEM;
}
/*
* this is, and how many ports.
*/
EBRDENABLE(brdp);
- sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
- memcpy(&sig, sigsp, sizeof(cdkonbsig_t));
+ sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR);
+ memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t));
EBRDDISABLE(brdp);
-#if 0
- printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n",
- __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2,
- sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2);
-#endif
-
- if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
- (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
+ if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
+ sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
+ sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
+ sig.magic3 != cpu_to_le16(ONB_MAGIC3))
{
release_region(brdp->iobase, brdp->iosize);
- return(-ENODEV);
+ return -ENODEV;
}
/*
brdp->state |= BST_FOUND;
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_startbrd(stlibrd_t *brdp)
{
- volatile cdkhdr_t *hdrp;
- volatile cdkmem_t *memp;
- volatile cdkasy_t *ap;
- unsigned long flags;
- stliport_t *portp;
- int portnr, nrdevs, i, rc;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp);
-#endif
-
- rc = 0;
-
- save_flags(flags);
- cli();
+ cdkhdr_t __iomem *hdrp;
+ cdkmem_t __iomem *memp;
+ cdkasy_t __iomem *ap;
+ unsigned long flags;
+ stliport_t *portp;
+ int portnr, nrdevs, i, rc = 0;
+ u32 memoff;
+
+ spin_lock_irqsave(&brd_lock, flags);
EBRDENABLE(brdp);
- hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
nrdevs = hdrp->nrdevs;
#if 0
printk("%s(%d): CDK version %d.%d.%d --> "
"nrdevs=%d memp=%x hostp=%x slavep=%x\n",
- __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,
- hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,
- (int) hdrp->slavep);
+ __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification),
+ readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp),
+ readl(&hdrp->slavep));
#endif
if (nrdevs < (brdp->nrports + 1)) {
brdp->hostoffset = hdrp->hostp - CDK_CDKADDR;
brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR;
brdp->bitsize = (nrdevs + 7) / 8;
- memp = (volatile cdkmem_t *) hdrp->memp;
- if (((unsigned long) memp) > brdp->memsize) {
+ memoff = readl(&hdrp->memp);
+ if (memoff > brdp->memsize) {
printk(KERN_ERR "STALLION: corrupted shared memory region?\n");
rc = -EIO;
goto stli_donestartup;
}
- memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp);
- if (memp->dtype != TYP_ASYNCTRL) {
+ memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
+ if (readw(&memp->dtype) != TYP_ASYNCTRL) {
printk(KERN_ERR "STALLION: no slave control device found\n");
goto stli_donestartup;
}
* change pages while reading memory map.
*/
for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) {
- if (memp->dtype != TYP_ASYNC)
+ if (readw(&memp->dtype) != TYP_ASYNC)
break;
portp = brdp->ports[portnr];
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
break;
portp->devnr = i;
- portp->addr = memp->offset;
+ portp->addr = readl(&memp->offset);
portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs));
portp->portidx = (unsigned char) (i / 8);
portp->portbit = (unsigned char) (0x1 << (i % 8));
}
- hdrp->slavereq = 0xff;
+ writeb(0xff, &hdrp->slavereq);
/*
* For each port setup a local copy of the RX and TX buffer offsets
*/
for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) {
portp = brdp->ports[portnr];
- if (portp == (stliport_t *) NULL)
+ if (portp == NULL)
break;
if (portp->addr == 0)
break;
- ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
- if (ap != (volatile cdkasy_t *) NULL) {
- portp->rxsize = ap->rxq.size;
- portp->txsize = ap->txq.size;
- portp->rxoffset = ap->rxq.offset;
- portp->txoffset = ap->txq.offset;
+ ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr);
+ if (ap != NULL) {
+ portp->rxsize = readw(&ap->rxq.size);
+ portp->txsize = readw(&ap->txq.size);
+ portp->rxoffset = readl(&ap->rxq.offset);
+ portp->txoffset = readl(&ap->txq.offset);
}
}
stli_donestartup:
EBRDDISABLE(brdp);
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
if (rc == 0)
brdp->state |= BST_STARTED;
add_timer(&stli_timerlist);
}
- return(rc);
+ return rc;
}
/*****************************************************************************/
static int __init stli_brdinit(stlibrd_t *brdp)
{
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp);
-#endif
-
stli_brds[brdp->brdnr] = brdp;
switch (brdp->brdtype) {
case BRD_ECHPCI:
printk(KERN_ERR "STALLION: %s board type not supported in "
"this driver\n", stli_brdnames[brdp->brdtype]);
- return(ENODEV);
+ return -ENODEV;
default:
printk(KERN_ERR "STALLION: board=%d is unknown board "
"type=%d\n", brdp->brdnr, brdp->brdtype);
- return(ENODEV);
+ return -ENODEV;
}
if ((brdp->state & BST_FOUND) == 0) {
"io=%x mem=%x\n",
stli_brdnames[brdp->brdtype], brdp->brdnr,
brdp->iobase, (int) brdp->memaddr);
- return(ENODEV);
+ return -ENODEV;
}
stli_initports(brdp);
"nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
brdp->nrpanels, brdp->nrports);
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_eisamemprobe(stlibrd_t *brdp)
{
- cdkecpsig_t ecpsig, *ecpsigp;
- cdkonbsig_t onbsig, *onbsigp;
+ cdkecpsig_t ecpsig, __iomem *ecpsigp;
+ cdkonbsig_t onbsig, __iomem *onbsigp;
int i, foundit;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp);
-#endif
-
/*
* First up we reset the board, to get it into a known state. There
* is only 2 board types here we need to worry about. Don;t use the
mdelay(1);
stli_onbeenable(brdp);
} else {
- return(-ENODEV);
+ return -ENODEV;
}
foundit = 0;
*/
for (i = 0; (i < stli_eisamempsize); i++) {
brdp->memaddr = stli_eisamemprobeaddrs[i];
- brdp->membase = (void *) brdp->memaddr;
brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
- if (brdp->membase == (void *) NULL)
+ if (brdp->membase == NULL)
continue;
if (brdp->brdtype == BRD_ECPE) {
- ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp,
+ ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp,
CDK_SIGADDR, __LINE__);
- memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
- if (ecpsig.magic == ECP_MAGIC)
+ memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
+ if (ecpsig.magic == cpu_to_le32(ECP_MAGIC))
foundit = 1;
} else {
- onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp,
+ onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp,
CDK_SIGADDR, __LINE__);
- memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));
- if ((onbsig.magic0 == ONB_MAGIC0) &&
- (onbsig.magic1 == ONB_MAGIC1) &&
- (onbsig.magic2 == ONB_MAGIC2) &&
- (onbsig.magic3 == ONB_MAGIC3))
+ memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t));
+ if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) &&
+ (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) &&
+ (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) &&
+ (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3)))
foundit = 1;
}
printk(KERN_ERR "STALLION: failed to probe shared memory "
"region for %s in EISA slot=%d\n",
stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
- return(-ENODEV);
+ return -ENODEV;
}
- return(0);
+ return 0;
}
static int stli_getbrdnr(void)
static int stli_findeisabrds(void)
{
- stlibrd_t *brdp;
- unsigned int iobase, eid;
- int i;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_findeisabrds()\n");
-#endif
+ stlibrd_t *brdp;
+ unsigned int iobase, eid;
+ int i;
/*
- * Firstly check if this is an EISA system. Do this by probing for
- * the system board EISA ID. If this is not an EISA system then
+ * Firstly check if this is an EISA system. If this is not an EISA system then
* don't bother going any further!
*/
- outb(0xff, 0xc80);
- if (inb(0xc80) == 0xff)
- return(0);
+ if (EISA_bus)
+ return 0;
/*
* Looks like an EISA system, so go searching for EISA boards.
*/
for (i = 0; (i < STL_MAXBRDS); i++) {
brdp = stli_brds[i];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
continue;
if (brdp->iobase == iobase)
break;
* We have found a Stallion board and it is not configured already.
* Allocate a board structure and initialize it.
*/
- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
- return(-ENOMEM);
+ if ((brdp = stli_allocbrd()) == NULL)
+ return -ENOMEM;
if ((brdp->brdnr = stli_getbrdnr()) < 0)
- return(-ENOMEM);
+ return -ENOMEM;
eid = inb(iobase + 0xc82);
if (eid == ECP_EISAID)
brdp->brdtype = BRD_ECPE;
stli_brdinit(brdp);
}
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_initpcibrd(int brdtype, struct pci_dev *devp)
{
- stlibrd_t *brdp;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n",
- brdtype, dev->bus->number, dev->devfn);
-#endif
+ stlibrd_t *brdp;
if (pci_enable_device(devp))
- return(-EIO);
- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
- return(-ENOMEM);
+ return -EIO;
+ if ((brdp = stli_allocbrd()) == NULL)
+ return -ENOMEM;
if ((brdp->brdnr = stli_getbrdnr()) < 0) {
printk(KERN_INFO "STALLION: too many boards found, "
"maximum supported %d\n", STL_MAXBRDS);
- return(0);
+ return 0;
}
brdp->brdtype = brdtype;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__,
- pci_resource_start(devp, 0),
- pci_resource_start(devp, 1),
- pci_resource_start(devp, 2),
- pci_resource_start(devp, 3));
-#endif
-
/*
* We have all resources from the board, so lets setup the actual
* board structure now.
brdp->memaddr = pci_resource_start(devp, 2);
stli_brdinit(brdp);
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_findpcibrds(void)
{
- struct pci_dev *dev = NULL;
- int rc;
-
-#ifdef DEBUG
- printk("stli_findpcibrds()\n");
-#endif
+ struct pci_dev *dev = NULL;
- while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION,
- PCI_DEVICE_ID_ECRA, dev))) {
- if ((rc = stli_initpcibrd(BRD_ECPPCI, dev)))
- return(rc);
+ while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) {
+ stli_initpcibrd(BRD_ECPPCI, dev);
}
-
- return(0);
+ return 0;
}
#endif
static stlibrd_t *stli_allocbrd(void)
{
- stlibrd_t *brdp;
+ stlibrd_t *brdp;
brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);
if (!brdp) {
printk(KERN_ERR "STALLION: failed to allocate memory "
- "(size=%d)\n", sizeof(stlibrd_t));
+ "(size=%Zd)\n", sizeof(stlibrd_t));
return NULL;
}
-
brdp->magic = STLI_BOARDMAGIC;
- return(brdp);
+ return brdp;
}
/*****************************************************************************/
static int stli_initbrds(void)
{
- stlibrd_t *brdp, *nxtbrdp;
- stlconf_t *confp;
- int i, j;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_initbrds()\n");
-#endif
+ stlibrd_t *brdp, *nxtbrdp;
+ stlconf_t *confp;
+ int i, j;
if (stli_nrbrds > STL_MAXBRDS) {
printk(KERN_INFO "STALLION: too many boards in configuration "
*/
for (i = 0; (i < stli_nrbrds); i++) {
confp = &stli_brdconf[i];
-#ifdef MODULE
stli_parsebrd(confp, stli_brdsp[i]);
-#endif
- if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
- return(-ENOMEM);
+ if ((brdp = stli_allocbrd()) == NULL)
+ return -ENOMEM;
brdp->brdnr = i;
brdp->brdtype = confp->brdtype;
brdp->iobase = confp->ioaddr1;
* Static configuration table done, so now use dynamic methods to
* see if any more boards should be configured.
*/
-#ifdef MODULE
stli_argbrds();
-#endif
if (STLI_EISAPROBE)
stli_findeisabrds();
#ifdef CONFIG_PCI
if (stli_nrbrds > 1) {
for (i = 0; (i < stli_nrbrds); i++) {
brdp = stli_brds[i];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
continue;
for (j = i + 1; (j < stli_nrbrds); j++) {
nxtbrdp = stli_brds[j];
- if (nxtbrdp == (stlibrd_t *) NULL)
+ if (nxtbrdp == NULL)
continue;
if ((brdp->membase >= nxtbrdp->membase) &&
(brdp->membase <= (nxtbrdp->membase +
if (stli_shared == 0) {
for (i = 0; (i < stli_nrbrds); i++) {
brdp = stli_brds[i];
- if (brdp == (stlibrd_t *) NULL)
+ if (brdp == NULL)
continue;
if (brdp->state & BST_FOUND) {
EBRDENABLE(brdp);
}
}
- return(0);
+ return 0;
}
/*****************************************************************************/
static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)
{
- unsigned long flags;
- void *memptr;
- stlibrd_t *brdp;
- int brdnr, size, n;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n",
- (int) fp, (int) buf, count, (int) offp);
-#endif
+ unsigned long flags;
+ void *memptr;
+ stlibrd_t *brdp;
+ int brdnr, size, n;
+ void *p;
+ loff_t off = *offp;
brdnr = iminor(fp->f_dentry->d_inode);
if (brdnr >= stli_nrbrds)
- return(-ENODEV);
+ return -ENODEV;
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
if (brdp->state == 0)
- return(-ENODEV);
- if (fp->f_pos >= brdp->memsize)
- return(0);
+ return -ENODEV;
+ if (off >= brdp->memsize || off + count < off)
+ return 0;
- size = MIN(count, (brdp->memsize - fp->f_pos));
+ size = MIN(count, (brdp->memsize - off));
+
+ /*
+ * Copy the data a page at a time
+ */
+
+ p = (void *)__get_free_page(GFP_KERNEL);
+ if(p == NULL)
+ return -ENOMEM;
- save_flags(flags);
- cli();
- EBRDENABLE(brdp);
while (size > 0) {
- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
- if (copy_to_user(buf, memptr, n)) {
+ spin_lock_irqsave(&brd_lock, flags);
+ EBRDENABLE(brdp);
+ memptr = (void *) EBRDGETMEMPTR(brdp, off);
+ n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+ n = MIN(n, PAGE_SIZE);
+ memcpy_fromio(p, memptr, n);
+ EBRDDISABLE(brdp);
+ spin_unlock_irqrestore(&brd_lock, flags);
+ if (copy_to_user(buf, p, n)) {
count = -EFAULT;
goto out;
}
- fp->f_pos += n;
+ off += n;
buf += n;
size -= n;
}
out:
- EBRDDISABLE(brdp);
- restore_flags(flags);
-
- return(count);
+ *offp = off;
+ free_page((unsigned long)p);
+ return count;
}
/*****************************************************************************/
* Code to handle an "staliomem" write operation. This device is the
* contents of the board shared memory. It is used for down loading
* the slave image (and debugging :-)
+ *
+ * FIXME: copy under lock
*/
static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)
{
- unsigned long flags;
- void *memptr;
- stlibrd_t *brdp;
- char __user *chbuf;
- int brdnr, size, n;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n",
- (int) fp, (int) buf, count, (int) offp);
-#endif
+ unsigned long flags;
+ void *memptr;
+ stlibrd_t *brdp;
+ char __user *chbuf;
+ int brdnr, size, n;
+ void *p;
+ loff_t off = *offp;
brdnr = iminor(fp->f_dentry->d_inode);
+
if (brdnr >= stli_nrbrds)
- return(-ENODEV);
+ return -ENODEV;
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
if (brdp->state == 0)
- return(-ENODEV);
- if (fp->f_pos >= brdp->memsize)
- return(0);
+ return -ENODEV;
+ if (off >= brdp->memsize || off + count < off)
+ return 0;
chbuf = (char __user *) buf;
- size = MIN(count, (brdp->memsize - fp->f_pos));
+ size = MIN(count, (brdp->memsize - off));
+
+ /*
+ * Copy the data a page at a time
+ */
+
+ p = (void *)__get_free_page(GFP_KERNEL);
+ if(p == NULL)
+ return -ENOMEM;
- save_flags(flags);
- cli();
- EBRDENABLE(brdp);
while (size > 0) {
- memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
- n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
- if (copy_from_user(memptr, chbuf, n)) {
- count = -EFAULT;
+ n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+ n = MIN(n, PAGE_SIZE);
+ if (copy_from_user(p, chbuf, n)) {
+ if (count == 0)
+ count = -EFAULT;
goto out;
}
- fp->f_pos += n;
+ spin_lock_irqsave(&brd_lock, flags);
+ EBRDENABLE(brdp);
+ memptr = (void *) EBRDGETMEMPTR(brdp, off);
+ memcpy_toio(memptr, p, n);
+ EBRDDISABLE(brdp);
+ spin_unlock_irqrestore(&brd_lock, flags);
+ off += n;
chbuf += n;
size -= n;
}
out:
- EBRDDISABLE(brdp);
- restore_flags(flags);
-
- return(count);
+ free_page((unsigned long) p);
+ *offp = off;
+ return count;
}
/*****************************************************************************/
static int stli_getbrdstats(combrd_t __user *bp)
{
- stlibrd_t *brdp;
- int i;
+ stlibrd_t *brdp;
+ int i;
if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))
return -EFAULT;
if (stli_brdstats.brd >= STL_MAXBRDS)
- return(-ENODEV);
+ return -ENODEV;
brdp = stli_brds[stli_brdstats.brd];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
memset(&stli_brdstats, 0, sizeof(combrd_t));
stli_brdstats.brd = brdp->brdnr;
if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t)))
return -EFAULT;
- return(0);
+ return 0;
}
/*****************************************************************************/
static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
{
- stlibrd_t *brdp;
- int i;
+ stlibrd_t *brdp;
+ int i;
- if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
- return((stliport_t *) NULL);
+ if (brdnr < 0 || brdnr >= STL_MAXBRDS)
+ return NULL;
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return((stliport_t *) NULL);
+ if (brdp == NULL)
+ return NULL;
for (i = 0; (i < panelnr); i++)
portnr += brdp->panels[i];
if ((portnr < 0) || (portnr >= brdp->nrports))
- return((stliport_t *) NULL);
- return(brdp->ports[portnr]);
+ return NULL;
+ return brdp->ports[portnr];
}
/*****************************************************************************/
memset(&stli_comstats, 0, sizeof(comstats_t));
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
+ if (portp == NULL)
+ return -ENODEV;
brdp = stli_brds[portp->brdnr];
- if (brdp == (stlibrd_t *) NULL)
- return(-ENODEV);
+ if (brdp == NULL)
+ return -ENODEV;
if (brdp->state & BST_STARTED) {
if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
&stli_cdkstats, sizeof(asystats_t), 1)) < 0)
- return(rc);
+ return rc;
} else {
memset(&stli_cdkstats, 0, sizeof(asystats_t));
}
stli_comstats.state = portp->state;
stli_comstats.flags = portp->flags;
- save_flags(flags);
- cli();
- if (portp->tty != (struct tty_struct *) NULL) {
+ spin_lock_irqsave(&brd_lock, flags);
+ if (portp->tty != NULL) {
if (portp->tty->driver_data == portp) {
stli_comstats.ttystate = portp->tty->flags;
- stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/;
- if (portp->tty->termios != (struct termios *) NULL) {
+ stli_comstats.rxbuffered = -1;
+ if (portp->tty->termios != NULL) {
stli_comstats.cflags = portp->tty->termios->c_cflag;
stli_comstats.iflags = portp->tty->termios->c_iflag;
stli_comstats.oflags = portp->tty->termios->c_oflag;
}
}
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&brd_lock, flags);
stli_comstats.txtotal = stli_cdkstats.txchars;
stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
stli_comstats.hwid = stli_cdkstats.hwid;
stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
- return(0);
+ return 0;
}
/*****************************************************************************/
static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)
{
- stlibrd_t *brdp;
- int rc;
+ stlibrd_t *brdp;
+ int rc;
if (!portp) {
if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)
{
- stlibrd_t *brdp;
- int rc;
+ stlibrd_t *brdp;
+ int rc;
if (!portp) {
if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t)))
static int stli_getportstruct(stliport_t __user *arg)
{
- stliport_t *portp;
+ stliport_t *portp;
if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t)))
return -EFAULT;
static int stli_getbrdstruct(stlibrd_t __user *arg)
{
- stlibrd_t *brdp;
+ stlibrd_t *brdp;
if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t)))
return -EFAULT;
static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
{
- stlibrd_t *brdp;
- int brdnr, rc, done;
+ stlibrd_t *brdp;
+ int brdnr, rc, done;
void __user *argp = (void __user *)arg;
-#ifdef DEBUG
- printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n",
- (int) ip, (int) fp, cmd, (int) arg);
-#endif
-
/*
* First up handle the board independent ioctls.
*/
}
if (done)
- return(rc);
+ return rc;
/*
* Now handle the board specific ioctls. These all depend on the
*/
brdnr = iminor(ip);
if (brdnr >= STL_MAXBRDS)
- return(-ENODEV);
+ return -ENODEV;
brdp = stli_brds[brdnr];
if (!brdp)
- return(-ENODEV);
+ return -ENODEV;
if (brdp->state == 0)
- return(-ENODEV);
+ return -ENODEV;
switch (cmd) {
case STL_BINTR:
rc = -ENOIOCTLCMD;
break;
}
-
- return(rc);
+ return rc;
}
static struct tty_operations stli_ops = {
int i;
printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
+ spin_lock_init(&stli_lock);
+ spin_lock_init(&brd_lock);
+
stli_initbrds();
stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
/*
* Allocate a temporary write buffer.
*/
- stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
- if (!stli_tmpwritebuf)
- printk(KERN_ERR "STALLION: failed to allocate memory "
- "(size=%d)\n", STLI_TXBUFSIZE);
stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
if (!stli_txcookbuf)
printk(KERN_ERR "STALLION: failed to allocate memory "
printk(KERN_ERR "STALLION: failed to register serial driver\n");
return -EBUSY;
}
- return(0);
+ return 0;
}
/*****************************************************************************/
info->session = current->signal->session;
info->pgrp = process_group(current);
- clear_bit(TTY_DONT_FLIP, &tty->flags);
/*
status = mxser_get_msr(info->base, 0, info->port);
* buffer, and once to drain the space from the (physical) beginning of
* the buffer to head pointer.
*
- * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set
+ * Called under the tty->atomic_read_lock sem
*
*/
}
add_wait_queue(&tty->read_wait, &wait);
- set_bit(TTY_DONT_FLIP, &tty->flags);
while (nr) {
/* First test for status change. */
if (tty->packet && tty->link->ctrl_status) {
break;
}
n_tty_set_room(tty);
- clear_bit(TTY_DONT_FLIP, &tty->flags);
timeout = schedule_timeout(timeout);
- set_bit(TTY_DONT_FLIP, &tty->flags);
continue;
}
__set_current_state(TASK_RUNNING);
if (time)
timeout = time;
}
- clear_bit(TTY_DONT_FLIP, &tty->flags);
mutex_unlock(&tty->atomic_read_lock);
remove_wait_queue(&tty->read_wait, &wait);
*
* FIXME: Our pty_write method is called with our ldisc lock held but
* not our partners. We can't just take the other one blindly without
- * risking deadlocks. There is also the small matter of TTY_DONT_FLIP
+ * risking deadlocks.
*/
static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count)
{
int i;
printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
+ spin_lock_init(&stallion_lock);
+ spin_lock_init(&brd_lock);
+
stl_initbrds();
stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
p->used = 0;
p->size = size;
p->next = NULL;
- p->active = 0;
p->commit = 0;
p->read = 0;
p->char_buf_ptr = (char *)(p->data);
/* OPTIMISATION: We could keep a per tty "zero" sized buffer to
remove this conditional if its worth it. This would be invisible
to the callers */
- if ((b = tty->buf.tail) != NULL) {
+ if ((b = tty->buf.tail) != NULL)
left = b->size - b->used;
- b->active = 1;
- } else
+ else
left = 0;
if (left < size) {
if ((n = tty_buffer_find(tty, size)) != NULL) {
if (b != NULL) {
b->next = n;
- b->active = 0;
b->commit = b->used;
} else
tty->buf.head = n;
tty->buf.tail = n;
- n->active = 1;
} else
size = left;
}
{
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
- if (tty->buf.tail != NULL) {
- tty->buf.tail->active = 0;
+ if (tty->buf.tail != NULL)
tty->buf.tail->commit = tty->buf.tail->used;
- }
spin_unlock_irqrestore(&tty->buf.lock, flags);
schedule_delayed_work(&tty->buf.work, 1);
}
}
clear_bit(TTY_LDISC, &tty->flags);
- clear_bit(TTY_DONT_FLIP, &tty->flags);
- if (o_tty) {
+ if (o_tty)
clear_bit(TTY_LDISC, &o_tty->flags);
- clear_bit(TTY_DONT_FLIP, &o_tty->flags);
- }
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
/*
* race with the set_ldisc code path.
*/
clear_bit(TTY_LDISC, &tty->flags);
- clear_bit(TTY_DONT_FLIP, &tty->flags);
cancel_delayed_work(&tty->buf.work);
/*
struct tty_struct *tty = (struct tty_struct *) private_;
unsigned long flags;
struct tty_ldisc *disc;
- struct tty_buffer *tbuf;
- int count;
+ struct tty_buffer *tbuf, *head;
char *char_buf;
unsigned char *flag_buf;
if (disc == NULL) /* !TTY_LDISC */
return;
- if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
- /*
- * Do it after the next timer tick:
- */
- schedule_delayed_work(&tty->buf.work, 1);
- goto out;
- }
spin_lock_irqsave(&tty->buf.lock, flags);
- while((tbuf = tty->buf.head) != NULL) {
- while ((count = tbuf->commit - tbuf->read) != 0) {
- char_buf = tbuf->char_buf_ptr + tbuf->read;
- flag_buf = tbuf->flag_buf_ptr + tbuf->read;
- tbuf->read += count;
+ head = tty->buf.head;
+ if (head != NULL) {
+ tty->buf.head = NULL;
+ for (;;) {
+ int count = head->commit - head->read;
+ if (!count) {
+ if (head->next == NULL)
+ break;
+ tbuf = head;
+ head = head->next;
+ tty_buffer_free(tty, tbuf);
+ continue;
+ }
+ if (!tty->receive_room) {
+ schedule_delayed_work(&tty->buf.work, 1);
+ break;
+ }
+ if (count > tty->receive_room)
+ count = tty->receive_room;
+ char_buf = head->char_buf_ptr + head->read;
+ flag_buf = head->flag_buf_ptr + head->read;
+ head->read += count;
spin_unlock_irqrestore(&tty->buf.lock, flags);
disc->receive_buf(tty, char_buf, flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
- if (tbuf->active)
- break;
- tty->buf.head = tbuf->next;
- if (tty->buf.head == NULL)
- tty->buf.tail = NULL;
- tty_buffer_free(tty, tbuf);
+ tty->buf.head = head;
}
spin_unlock_irqrestore(&tty->buf.lock, flags);
-out:
+
tty_ldisc_deref(disc);
}
{
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
- if (tty->buf.tail != NULL) {
- tty->buf.tail->active = 0;
+ if (tty->buf.tail != NULL)
tty->buf.tail->commit = tty->buf.tail->used;
- }
spin_unlock_irqrestore(&tty->buf.lock, flags);
if (tty->low_latency)
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
-#define WDT_DEFAULT_TIME 5 /* 5 seconds */
-#define WDT_MAX_TIME 256 /* 256 seconds */
+#define WDT_DEFAULT_TIME 5 /* seconds */
+#define WDT_MAX_TIME 256 /* seconds */
static int wdt_time = WDT_DEFAULT_TIME;
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(wdt_time, int, 0);
MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+#endif
static unsigned long at91wdt_busy;
case WDIOC_SETTIMEOUT:
if (get_user(new_value, p))
return -EFAULT;
-
+
if (at91_wdt_settimeout(new_value))
return -EINVAL;
.fops = &at91wdt_fops,
};
-static int __init at91_wdt_init(void)
+static int __init at91wdt_probe(struct platform_device *pdev)
{
int res;
- /* Check that the heartbeat value is within range; if not reset to the default */
- if (at91_wdt_settimeout(wdt_time)) {
- at91_wdt_settimeout(WDT_DEFAULT_TIME);
- printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
- }
+ if (at91wdt_miscdev.dev)
+ return -EBUSY;
+ at91wdt_miscdev.dev = &pdev->dev;
res = misc_register(&at91wdt_miscdev);
if (res)
return res;
- printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout);
+ printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : "");
return 0;
}
+static int __exit at91wdt_remove(struct platform_device *pdev)
+{
+ int res;
+
+ res = misc_deregister(&at91wdt_miscdev);
+ if (!res)
+ at91wdt_miscdev.dev = NULL;
+
+ return res;
+}
+
+static void at91wdt_shutdown(struct platform_device *pdev)
+{
+ at91_wdt_stop();
+}
+
+#ifdef CONFIG_PM
+
+static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message)
+{
+ at91_wdt_stop();
+ return 0;
+}
+
+static int at91wdt_resume(struct platform_device *pdev)
+{
+ if (at91wdt_busy)
+ at91_wdt_start();
+ return 0;
+}
+
+#else
+#define at91wdt_suspend NULL
+#define at91wdt_resume NULL
+#endif
+
+static struct platform_driver at91wdt_driver = {
+ .probe = at91wdt_probe,
+ .remove = __exit_p(at91wdt_remove),
+ .shutdown = at91wdt_shutdown,
+ .suspend = at91wdt_suspend,
+ .resume = at91wdt_resume,
+ .driver = {
+ .name = "at91_wdt",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init at91_wdt_init(void)
+{
+ /* Check that the heartbeat value is within range; if not reset to the default */
+ if (at91_wdt_settimeout(wdt_time)) {
+ at91_wdt_settimeout(WDT_DEFAULT_TIME);
+ pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
+ }
+
+ return platform_driver_register(&at91wdt_driver);
+}
+
static void __exit at91_wdt_exit(void)
{
- misc_deregister(&at91wdt_miscdev);
+ platform_driver_unregister(&at91wdt_driver);
}
module_init(at91_wdt_init);
return 0;
}
+static int tco_timer_get_timeleft (int *time_left)
+{
+ unsigned char val;
+
+ spin_lock(&tco_lock);
+
+ /* read the TCO Timer */
+ val = inb (TCO1_RLD);
+ val &= 0x3f;
+
+ spin_unlock(&tco_lock);
+
+ *time_left = (int)((val * 6) / 10);
+
+ return 0;
+}
+
/*
* /dev/watchdog handling
*/
{
int new_options, retval = -EINVAL;
int new_heartbeat;
+ int time_left;
void __user *argp = (void __user *)arg;
int __user *p = argp;
static struct watchdog_info ident = {
return -EFAULT;
if (tco_timer_set_heartbeat(new_heartbeat))
- return -EINVAL;
+ return -EINVAL;
tco_timer_keepalive ();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
+ case WDIOC_GETTIMELEFT:
+ {
+ if (tco_timer_get_timeleft(&time_left))
+ return -EINVAL;
+
+ return put_user(time_left, p);
+ }
+
default:
return -ENOIOCTLCMD;
}
*/
/*
- * A bells and whistles driver is available from:
+ * A bells and whistles driver is available from:
* http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
*
* More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
return 0;
}
+static int pcipcwd_get_timeleft(int *time_left)
+{
+ int msb;
+ int lsb;
+
+ /* Read the time that's left before rebooting */
+ /* Note: if the board is not yet armed then we will read 0xFFFF */
+ send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);
+
+ *time_left = (msb << 8) + lsb;
+
+ if (debug >= VERBOSE)
+ printk(KERN_DEBUG PFX "Time left before next reboot: %d\n",
+ *time_left);
+
+ return 0;
+}
+
/*
* /dev/watchdog handling
*/
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
+ case WDIOC_GETTIMELEFT:
+ {
+ int time_left;
+
+ if (pcipcwd_get_timeleft(&time_left))
+ return -EFAULT;
+
+ return put_user(time_left, p);
+ }
+
default:
return -ENOIOCTLCMD;
}
return 0;
}
+static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left)
+{
+ unsigned char msb, lsb;
+
+ /* Read the time that's left before rebooting */
+ /* Note: if the board is not yet armed then we will read 0xFFFF */
+ usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);
+
+ *time_left = (msb << 8) + lsb;
+
+ return 0;
+}
+
/*
* /dev/watchdog handling
*/
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
+ case WDIOC_GETTIMELEFT:
+ {
+ int time_left;
+
+ if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))
+ return -EFAULT;
+
+ return put_user(time_left, p);
+ }
+
default:
return -ENOIOCTLCMD;
}
}
}
- if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
+ if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
try_to_flush_leftover_data(drive);
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
{
if(HWIF(drive)->udma_four == 0)
return 0;
+
+ /* Check for SATA but only if we are ATA5 or higher */
+ if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0))
+ return 1;
if (!(drive->id->hw_config & 0x6000))
return 0;
#ifndef CONFIG_IDEDMA_IVB
u8 ultra_settings;
};
-static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
+static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
{ XFER_UDMA_6, 0x31, 0x07 },
{ XFER_UDMA_5, 0x31, 0x06 },
{ XFER_UDMA_4, 0x31, 0x05 },
{ 0, 0x00, 0x00 }
};
-static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
+static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
{ XFER_UDMA_6, 0x41, 0x06 },
{ XFER_UDMA_5, 0x41, 0x05 },
{ XFER_UDMA_4, 0x41, 0x04 },
return d->init_setup(dev, d);
}
-static struct pci_device_id aec62xx_pci_tbl[] = {
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+static const struct pci_device_id aec62xx_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl);
#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
-/*
- * Registers and masks for easy access by drive index:
- */
-#if 0
-static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
-static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
-#endif
-
/*
* This routine writes the prepared setup/active/recovery counts
* for a drive into the cmd646 chipset registers to active them.
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
-#ifdef __i386__
- if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
- }
-#endif
-
switch(dev->device) {
case PCI_DEVICE_ID_CMD_643:
break;
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
+ hwif->err_stops_fifo = 1;
+
hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq;
hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout;
#define MC1 0x02 /* DMA"C" timing */
#define MC0 0x01 /* DMA"C" timing */
-#if 0
- unsigned long bibma = pci_resource_start(dev, 4);
- u8 hi = 0, lo = 0;
-
- u8 sc1c = inb_p((u16)bibma + 0x1c);
- u8 sc1e = inb_p((u16)bibma + 0x1e);
- u8 sc1f = inb_p((u16)bibma + 0x1f);
-
- p += sprintf(p, "Host Mode : %s\n",
- (sc1f & 0x08) ? "Tri-Stated" : "Normal");
- p += sprintf(p, "Bus Clocking : %s\n",
- ((sc1f & 0xC0) == 0xC0) ? "100 External" :
- ((sc1f & 0x80) == 0x80) ? "66 External" :
- ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
- p += sprintf(p, "IO pad select : %s mA\n",
- ((sc1c & 0x03) == 0x03) ? "10" :
- ((sc1c & 0x02) == 0x02) ? "8" :
- ((sc1c & 0x01) == 0x01) ? "6" :
- ((sc1c & 0x00) == 0x00) ? "4" : "??");
- hi = sc1e >> 4;
- lo = sc1e & 0xf;
- p += sprintf(p, "Status Polling Period : %d\n", hi);
- p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
-#endif
-
static u8 pdc202xx_ratemask (ide_drive_t *drive)
{
u8 mode;
pdc202xx_reset_host(hwif);
pdc202xx_reset_host(mate);
-#if 0
- /*
- * FIXME: Have to kick all the drives again :-/
- * What a pain in the ACE!
- */
- if (hwif->present) {
- u16 hunit = 0;
- for (hunit = 0; hunit < MAX_DRIVES; ++hunit) {
- ide_drive_t *hdrive = &hwif->drives[hunit];
- if (hdrive->present) {
- if (hwif->ide_dma_check)
- hwif->ide_dma_check(hdrive);
- else
- hwif->tuneproc(hdrive, 5);
- }
- }
- }
- if (mate->present) {
- u16 munit = 0;
- for (munit = 0; munit < MAX_DRIVES; ++munit) {
- ide_drive_t *mdrive = &mate->drives[munit];
- if (mdrive->present) {
- if (mate->ide_dma_check)
- mate->ide_dma_check(mdrive);
- else
- mate->tuneproc(mdrive, 5);
- }
- }
- }
-#else
hwif->tuneproc(drive, 5);
-#endif
}
-static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
+ const char *name)
{
+ /* This doesn't appear needed */
if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
name, dev->resource[PCI_ROM_RESOURCE].start);
}
- /*
- * software reset - this is required because the bios
- * will set UDMA timing on if the hdd supports it. The
- * user may want to turn udma off. A bug in the pdc20262
- * is that it cannot handle a downgrade in timing from
- * UDMA to DMA. Disk accesses after issuing a set
- * feature command will result in errors. A software
- * reset leaves the timing registers intact,
- * but resets the drives.
- */
-#if 0
- if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
- (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
- (dev->device == PCI_DEVICE_ID_PROMISE_20263) ||
- (dev->device == PCI_DEVICE_ID_PROMISE_20262)) {
- unsigned long high_16 = pci_resource_start(dev, 4);
- byte udma_speed_flag = inb(high_16 + 0x001f);
- outb(udma_speed_flag | 0x10, high_16 + 0x001f);
- mdelay(100);
- outb(udma_speed_flag & ~0x10, high_16 + 0x001f);
- mdelay(2000); /* 2 seconds ?! */
- }
-
-#endif
return dev->irq;
}
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
+ hwif->err_stops_fifo = 1;
+
hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq;
hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout;
"mirror fixed.\n", d->name);
}
}
-
-#if 0
- if (dev->device == PCI_DEVICE_ID_PROMISE_20262)
- if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
- (tmp & e->mask) != e->val))
-
- if (d->enablebits[0].reg != d->enablebits[1].reg) {
- d->enablebits[0].reg = d->enablebits[1].reg;
- d->enablebits[0].mask = d->enablebits[1].mask;
- d->enablebits[0].val = d->enablebits[1].val;
- }
-#endif
-
return ide_setup_pci_device(dev, d);
}
"attached to I2O RAID controller.\n");
return -ENODEV;
}
-
-#if 0
- {
- u8 pri = 0, sec = 0;
-
- if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
- (tmp & e->mask) != e->val))
-
- if (d->enablebits[0].reg != d->enablebits[1].reg) {
- d->enablebits[0].reg = d->enablebits[1].reg;
- d->enablebits[0].mask = d->enablebits[1].mask;
- d->enablebits[0].val = d->enablebits[1].val;
- }
- }
-#endif
-
return ide_setup_pci_device(dev, d);
}
{
ide_hwif_t *hwif = NULL;
-printk("SC1200: resume\n");
pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state
dev->current_state = PM_EVENT_ON;
pci_enable_device(dev);
while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
unsigned int basereg, r, d, format;
sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data;
-printk("%s: SC1200: resume\n", hwif->name);
//
// Restore timing registers: this may be unnecessary if BIOS also does it
}
static struct pci_device_id sc1200_pci_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl);
}
static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
- u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
- u8 dma_modes[] = { 0x77, 0x21, 0x20 };
- u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
- u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
- u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
+ static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+ static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
+ static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
+ static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
}
outb_p(0x06, 0x0c00);
dev->irq = inb_p(0x0c01);
-#if 0
- printk("%s: device class (0x%04x)\n",
- name, dev->class);
- if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
- dev->class &= ~0x000F0F00;
- // dev->class |= ~0x00000400;
- dev->class |= ~0x00010100;
- /**/
- }
-#endif
} else {
struct pci_dev * findev = NULL;
u8 reg41 = 0;
pci_write_config_byte(dev, 0x5A, btr);
}
- return (dev->irq) ? dev->irq : 0;
+ return dev->irq;
}
static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
- /* Per Specified Design by OEM, and ASIC Architect */
- if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
- (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2))
- return 1;
-
/* Server Works */
if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS)
return ata66_svwks_svwks (hwif);
if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN)
return ata66_svwks_cobalt (hwif);
+ /* Per Specified Design by OEM, and ASIC Architect */
+ if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
+ (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2))
+ return 1;
+
return 0;
}
-#undef CAN_SW_DMA
static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
{
u8 dma_stat = 0;
hwif->ultra_mask = 0x3f;
hwif->mwdma_mask = 0x07;
-#ifdef CAN_SW_DMA
- hwif->swdma_mask = 0x07;
-#endif /* CAN_SW_DMA */
hwif->autodma = 0;
hwif->drives[1].autodma = (dma_stat & 0x40);
hwif->drives[0].autotune = (!(dma_stat & 0x20));
hwif->drives[1].autotune = (!(dma_stat & 0x40));
-// hwif->drives[0].autodma = hwif->autodma;
-// hwif->drives[1].autodma = hwif->autodma;
}
/*
if (dev->resource[0].start == 0x01f1)
d->bootable = ON_BOARD;
}
-#if 0
- if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- d->autodma = AUTODMA;
-#endif
d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
}
static struct pci_device_id svwks_pci_tbl[] = {
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1},
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3},
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, svwks_pci_tbl);
#include <asm/io.h>
-#undef SIIMAGE_VIRTUAL_DMAPIO
-#undef SIIMAGE_LARGE_DMA
-
/**
* pdev_is_sata - check if device is SATA
* @pdev: PCI device to check
return 0;
}
-#if 0
-/**
- * siimage_mmio_ide_dma_count - DMA bytes done
- * @drive
- *
- * If we are doing VDMA the CMD680 requires a little bit
- * of more careful handling and we have to read the counts
- * off ourselves. For non VDMA life is normal.
- */
-
-static int siimage_mmio_ide_dma_count (ide_drive_t *drive)
-{
-#ifdef SIIMAGE_VIRTUAL_DMAPIO
- struct request *rq = HWGROUP(drive)->rq;
- ide_hwif_t *hwif = HWIF(drive);
- u32 count = (rq->nr_sectors * SECTOR_SIZE);
- u32 rcount = 0;
- unsigned long addr = siimage_selreg(hwif, 0x1C);
-
- hwif->OUTL(count, addr);
- rcount = hwif->INL(addr);
-
- printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",
- drive->name, count, rcount, rq->nr_sectors);
-
-#endif /* SIIMAGE_VIRTUAL_DMAPIO */
- return __ide_dma_count(drive);
-}
-#endif
-
/**
* siimage_mmio_ide_dma_test_irq - check we caused an IRQ
* @drive: drive we are testing
u32 sata_error = hwif->INL(SATA_ERROR_REG);
hwif->OUTL(sata_error, SATA_ERROR_REG);
watchdog = (sata_error & 0x00680000) ? 1 : 0;
-#if 1
printk(KERN_WARNING "%s: sata_error = 0x%08x, "
"watchdog = %d, %s\n",
drive->name, sata_error, watchdog,
__FUNCTION__);
-#endif
} else {
watchdog = (ext_stat & 0x8000) ? 1 : 0;
* time.
*
* The hardware supports buffered taskfiles and also some rather nice
- * extended PRD tables. Unfortunately right now we don't.
+ * extended PRD tables. For better SI3112 support use the libata driver
*/
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
* so we can't currently use it sanely since we want to
* use LBA48 mode.
*/
-// base += 0x10;
-// hwif->no_lba48 = 1;
-
hw.io_ports[IDE_DATA_OFFSET] = base;
hw.io_ports[IDE_ERROR_OFFSET] = base + 1;
hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
base = (unsigned long) addr;
-#ifdef SIIMAGE_LARGE_DMA
-/* Watch the brackets - even Ken and Dennis get some language design wrong */
- hwif->dma_base = base + (ch ? 0x18 : 0x10);
- hwif->dma_base2 = base + (ch ? 0x08 : 0x00);
- hwif->dma_prdtable = hwif->dma_base2 + 4;
-#else /* ! SIIMAGE_LARGE_DMA */
hwif->dma_base = base + (ch ? 0x08 : 0x00);
hwif->dma_base2 = base + (ch ? 0x18 : 0x10);
-#endif /* SIIMAGE_LARGE_DMA */
hwif->mmio = 2;
}
hwif->reset_poll = &siimage_reset_poll;
hwif->pre_reset = &siimage_pre_reset;
- if(is_sata(hwif))
+ if(is_sata(hwif)) {
+ static int first = 1;
+
hwif->busproc = &siimage_busproc;
+ if (first) {
+ printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
+ first = 0;
+ }
+ }
if (!hwif->dma_base) {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
}
static struct pci_device_id siimage_pci_tbl[] = {
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), 0},
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+ { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112), 1},
+ { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA), 2},
#endif
{ 0, },
};
printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
hwif->name, rev);
} else {
-#ifdef CONFIG_BLK_DEV_IDEDMA
dma_state |= 0x60;
hwif->atapi_dma = 1;
if (hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
hwif->OUTB(dma_state, hwif->dma_base + 2);
}
}
static struct pci_device_id sl82c105_pci_tbl[] = {
- { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl);
u16 master_data;
u8 slave_data;
/* ISP RTC */
- u8 timings[][2] = { { 0, 0 },
+ static const u8 timings[][2]= {
+ { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
pci_read_config_word(dev, 0x4a, ®4a);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break;
case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break;
case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));
/* IORDY not supported */
return 0;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
{
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!(hwif->udma_four))
/* bit[0(1)]: 0:80, 1:40 */
hwif->udma_four = (reg47 & mask) ? 0 : 1;
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
static ide_pci_device_t slc90e66_chipset __devinitdata = {
}
static struct pci_device_id slc90e66_pci_tbl[] = {
- { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl);
goto err_out;
}
- if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
+ if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
err = -EINVAL;
goto err_put_pp;
}
input_regs(dev, regs);
- input_report_key(dev, keycode, value);
+ input_event(dev, EV_KEY, keycode, value);
input_sync(dev);
if (value && add_release_event) {
{ KE_END, 0 }
};
+static struct key_entry keymap_wistron_ms2111[] = {
+ { KE_KEY, 0x11, KEY_PROG1 },
+ { KE_KEY, 0x12, KEY_PROG2 },
+ { KE_KEY, 0x13, KEY_PROG3 },
+ { KE_KEY, 0x31, KEY_MAIL },
+ { KE_KEY, 0x36, KEY_WWW },
+ { KE_END, 0 }
+};
+
static struct key_entry keymap_wistron_ms2141[] = {
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
{ KE_WIFI, 0x30, 0 },
{ KE_KEY, 0x31, KEY_MAIL },
{ KE_KEY, 0x36, KEY_WWW },
+ { KE_END, 0 },
};
/*
},
.driver_data = keymap_aopen_1559as
},
+ {
+ .callback = dmi_matched,
+ .ident = "Medion MD 9783",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
+ },
+ .driver_data = keymap_wistron_ms2111
+ },
{ NULL, }
};
This driver can also be built as a module. If so, the module
will be called rtc-pcf8583.
+config RTC_DRV_RS5C348
+ tristate "Ricoh RS5C348A/B"
+ depends on RTC_CLASS && SPI
+ help
+ If you say yes here you get support for the
+ Ricoh RS5C348A and RS5C348B RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rs5c348.
+
config RTC_DRV_RS5C372
tristate "Ricoh RS5C372A/B"
depends on RTC_CLASS && I2C
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
+obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
--- /dev/null
+/*
+ * A SPI driver for the Ricoh RS5C348 RTC
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * 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.
+ *
+ * The board specific init code should provide characteristics of this
+ * device:
+ * Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS
+ */
+
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#define DRV_VERSION "0.1"
+
+#define RS5C348_REG_SECS 0
+#define RS5C348_REG_MINS 1
+#define RS5C348_REG_HOURS 2
+#define RS5C348_REG_WDAY 3
+#define RS5C348_REG_DAY 4
+#define RS5C348_REG_MONTH 5
+#define RS5C348_REG_YEAR 6
+#define RS5C348_REG_CTL1 14
+#define RS5C348_REG_CTL2 15
+
+#define RS5C348_SECS_MASK 0x7f
+#define RS5C348_MINS_MASK 0x7f
+#define RS5C348_HOURS_MASK 0x3f
+#define RS5C348_WDAY_MASK 0x03
+#define RS5C348_DAY_MASK 0x3f
+#define RS5C348_MONTH_MASK 0x1f
+
+#define RS5C348_BIT_PM 0x20 /* REG_HOURS */
+#define RS5C348_BIT_Y2K 0x80 /* REG_MONTH */
+#define RS5C348_BIT_24H 0x20 /* REG_CTL1 */
+#define RS5C348_BIT_XSTP 0x10 /* REG_CTL2 */
+#define RS5C348_BIT_VDET 0x40 /* REG_CTL2 */
+
+#define RS5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
+#define RS5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
+#define RS5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
+#define RS5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
+
+struct rs5c348_plat_data {
+ struct rtc_device *rtc;
+ int rtc_24h;
+};
+
+static int
+rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+ u8 txbuf[5+7], *txp;
+ int ret;
+
+ /* Transfer 5 bytes before writing SEC. This gives 31us for carry. */
+ txp = txbuf;
+ txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+ txbuf[1] = 0; /* dummy */
+ txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+ txbuf[3] = 0; /* dummy */
+ txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */
+ txp = &txbuf[5];
+ txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec);
+ txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min);
+ if (pdata->rtc_24h) {
+ txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour);
+ } else {
+ /* hour 0 is AM12, noon is PM12 */
+ txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) |
+ (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0);
+ }
+ txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday);
+ txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday);
+ txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) |
+ (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0);
+ txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
+ /* write in one transfer to avoid data inconsistency */
+ ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0);
+ udelay(62); /* Tcsr 62us */
+ return ret;
+}
+
+static int
+rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+ u8 txbuf[5], rxbuf[7];
+ int ret;
+
+ /* Transfer 5 byte befores reading SEC. This gives 31us for carry. */
+ txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+ txbuf[1] = 0; /* dummy */
+ txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+ txbuf[3] = 0; /* dummy */
+ txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */
+
+ /* read in one transfer to avoid data inconsistency */
+ ret = spi_write_then_read(spi, txbuf, sizeof(txbuf),
+ rxbuf, sizeof(rxbuf));
+ udelay(62); /* Tcsr 62us */
+ if (ret < 0)
+ return ret;
+
+ tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK);
+ tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
+ tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
+ if (!pdata->rtc_24h) {
+ tm->tm_hour %= 12;
+ if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM)
+ tm->tm_hour += 12;
+ }
+ tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
+ tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
+ tm->tm_mon =
+ BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1;
+ /* year is 1900 + tm->tm_year */
+ tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) +
+ ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0);
+
+ if (rtc_valid_tm(tm) < 0) {
+ dev_err(&spi->dev, "retrieved date/time is not valid.\n");
+ rtc_time_to_tm(0, tm);
+ }
+
+ return 0;
+}
+
+static struct rtc_class_ops rs5c348_rtc_ops = {
+ .read_time = rs5c348_rtc_read_time,
+ .set_time = rs5c348_rtc_set_time,
+};
+
+static struct spi_driver rs5c348_driver;
+
+static int __devinit rs5c348_probe(struct spi_device *spi)
+{
+ int ret;
+ struct rtc_device *rtc;
+ struct rs5c348_plat_data *pdata;
+
+ pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ spi->dev.platform_data = pdata;
+
+ /* Check D7 of SECOND register */
+ ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
+ if (ret < 0 || (ret & 0x80)) {
+ dev_err(&spi->dev, "not found.\n");
+ goto kfree_exit;
+ }
+
+ dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
+ dev_info(&spi->dev, "spiclk %u KHz.\n",
+ (spi->max_speed_hz + 500) / 1000);
+
+ /* turn RTC on if it was not on */
+ ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+ if (ret < 0)
+ goto kfree_exit;
+ if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
+ u8 buf[2];
+ if (ret & RS5C348_BIT_VDET)
+ dev_warn(&spi->dev, "voltage-low detected.\n");
+ buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
+ buf[1] = 0;
+ ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
+ if (ret < 0)
+ goto kfree_exit;
+ }
+
+ ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
+ if (ret < 0)
+ goto kfree_exit;
+ if (ret & RS5C348_BIT_24H)
+ pdata->rtc_24h = 1;
+
+ rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev,
+ &rs5c348_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(rtc)) {
+ ret = PTR_ERR(rtc);
+ goto kfree_exit;
+ }
+
+ pdata->rtc = rtc;
+
+ return 0;
+ kfree_exit:
+ kfree(pdata);
+ return ret;
+}
+
+static int __devexit rs5c348_remove(struct spi_device *spi)
+{
+ struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+ struct rtc_device *rtc = pdata->rtc;
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+ kfree(pdata);
+ return 0;
+}
+
+static struct spi_driver rs5c348_driver = {
+ .driver = {
+ .name = "rs5c348",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = rs5c348_probe,
+ .remove = __devexit_p(rs5c348_remove),
+};
+
+static __init int rs5c348_init(void)
+{
+ return spi_register_driver(&rs5c348_driver);
+}
+
+static __exit void rs5c348_exit(void)
+{
+ spi_unregister_driver(&rs5c348_driver);
+}
+
+module_init(rs5c348_init);
+module_exit(rs5c348_exit);
+
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
static int m68328_console_cbaud = DEFAULT_CBAUD;
-/*
- * tmp_buf is used as a temporary buffer by serial_write. We need to
- * lock it in case the memcpy_fromfs blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */
-
static inline int serial_paranoia_check(struct m68k_serial *info,
char *name, const char *routine)
{
if (serial_paranoia_check(info, tty->name, "rs_stop"))
return;
- save_flags(flags); cli();
+ local_irq_save(flags);
uart->ustcnt &= ~USTCNT_TXEN;
- restore_flags(flags);
+ local_irq_restore(flags);
}
static void rs_put_char(char ch)
{
int flags, loops = 0;
- save_flags(flags); cli();
+ local_irq_save(flags);
while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) {
loops++;
UTX_TXDATA = ch;
udelay(5);
- restore_flags(flags);
+ local_irq_restore(flags);
}
static void rs_start(struct tty_struct *tty)
if (serial_paranoia_check(info, tty->name, "rs_start"))
return;
- save_flags(flags); cli();
+ local_irq_save(flags);
if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) {
#ifdef USE_INTS
uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK;
uart->ustcnt |= USTCNT_TXEN;
#endif
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
/* Drop into either the boot monitor or kadb upon receiving a break
if(!tty)
goto clear_and_exit;
- /*
- * Make sure that we do not overflow the buffer
- */
- if (tty_request_buffer_room(tty, 1) == 0) {
- tty_schedule_flip(tty);
- return;
- }
-
flag = TTY_NORMAL;
if(rx & URX_PARITY_ERROR) {
return -ENOMEM;
}
- save_flags(flags); cli();
+ local_irq_save(flags);
/*
* Clear the FIFO buffers and disable them
change_speed(info);
info->flags |= S_INITIALIZED;
- restore_flags(flags);
+ local_irq_restore(flags);
return 0;
}
if (!(info->flags & S_INITIALIZED))
return;
- save_flags(flags); cli(); /* Disable interrupts */
+ local_irq_save(flags);
if (info->xmit_buf) {
free_page((unsigned long) info->xmit_buf);
set_bit(TTY_IO_ERROR, &info->tty->flags);
info->flags &= ~S_INITIALIZED;
- restore_flags(flags);
+ local_irq_restore(flags);
}
struct {
if (info == 0) return;
if (info->xmit_buf == 0) return;
- save_flags(flags); cli();
+ local_irq_save(flags);
left = info->xmit_cnt;
while (left != 0) {
c = info->xmit_buf[info->xmit_tail];
info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1);
info->xmit_cnt--;
- restore_flags(flags);
+ local_irq_restore(flags);
rs_put_char(c);
- save_flags(flags); cli();
+ local_irq_save(flags);
left = min(info->xmit_cnt, left-1);
}
/* Last character is being transmitted now (hopefully). */
udelay(5);
- restore_flags(flags);
+ local_irq_restore(flags);
return;
}
#endif
/* Enable transmitter */
- save_flags(flags); cli();
+ local_irq_save(flags);
if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
!info->xmit_buf) {
- restore_flags(flags);
+ local_irq_restore(flags);
return;
}
while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5);
}
#endif
- restore_flags(flags);
+ local_irq_restore(flags);
}
extern void console_printn(const char * b, int count);
if (!tty || !info->xmit_buf)
return 0;
- save_flags(flags);
+ local_save_flags(flags);
while (1) {
- cli();
+ local_irq_disable();
c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
SERIAL_XMIT_SIZE - info->xmit_head));
+ local_irq_restore(flags);
+
if (c <= 0)
break;
memcpy(info->xmit_buf + info->xmit_head, buf, c);
+
+ local_irq_disable();
info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
info->xmit_cnt += c;
- restore_flags(flags);
+ local_irq_restore(flags);
buf += c;
count -= c;
total += c;
if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
/* Enable transmitter */
- cli();
+ local_irq_disable();
#ifndef USE_INTS
while(info->xmit_cnt) {
#endif
#ifndef USE_INTS
}
#endif
- restore_flags(flags);
+ local_irq_restore(flags);
}
- restore_flags(flags);
+
return total;
}
static void rs_flush_buffer(struct tty_struct *tty)
{
struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
+ unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
return;
- cli();
+ local_irq_save(flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- sti();
+ local_irq_restore(flags);
tty_wakeup(tty);
}
m68328_uart *uart = &uart_addr[info->line];
#endif
unsigned char status;
+ unsigned long flags;
- cli();
+ local_irq_save(flags);
#ifdef CONFIG_SERIAL_68328_RTS_CTS
status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0;
#else
status = 0;
#endif
- sti();
+ local_irq_restore(flags);
put_user(status,value);
return 0;
}
unsigned long flags;
if (!info->port)
return;
- save_flags(flags);
- cli();
+ local_irq_save(flags);
#ifdef USE_INTS
uart->utx.w |= UTX_SEND_BREAK;
msleep_interruptible(duration);
uart->utx.w &= ~UTX_SEND_BREAK;
#endif
- restore_flags(flags);
+ local_irq_restore(flags);
}
static int rs_ioctl(struct tty_struct *tty, struct file * file,
(struct serial_struct *) arg);
case TIOCSERGETLSR: /* Get line status register */
if (access_ok(VERIFY_WRITE, (void *) arg,
- sizeof(unsigned int));
+ sizeof(unsigned int)))
return get_lsr_info(info, (unsigned int *) arg);
return -EFAULT;
case TIOCSERGSTRUCT:
if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
return;
- save_flags(flags); cli();
+ local_irq_save(flags);
if (tty_hung_up_p(filp)) {
- restore_flags(flags);
+ local_irq_restore(flags);
return;
}
info->count = 0;
}
if (info->count) {
- restore_flags(flags);
+ local_irq_restore(flags);
return;
}
info->flags |= S_CLOSING;
}
info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING);
wake_up_interruptible(&info->close_wait);
- restore_flags(flags);
+ local_irq_restore(flags);
}
/*
info->count--;
info->blocked_open++;
while (1) {
- cli();
+ local_irq_disable();
m68k_rtsdtr(info, 1);
- sti();
+ local_irq_enable();
current->state = TASK_INTERRUPTIBLE;
if (tty_hung_up_p(filp) ||
!(info->flags & S_INITIALIZED)) {
return -ENOMEM;
}
- save_flags(flags); cli();
+ local_irq_save(flags);
for(i=0;i<NR_PORTS;i++) {
serial_pm[i]->data = info;
#endif
}
- restore_flags(flags);
+ local_irq_restore(flags);
return 0;
}
DFLIP(
if (1) {
-
- if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
- DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count);
- DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt);
- } else {
- }
DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx);
DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty));
DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty));
len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
ld = tty_ldisc_ref(tp);
- /*
- * If the DONT_FLIP flag is on, don't flush our buffer, and act
- * like the ld doesn't have any space to put the data right now.
- */
- if (test_bit(TTY_DONT_FLIP, &tp->flags))
- len = 0;
-
/*
* If we were unable to get a reference to the ld,
* don't flush our buffer, and act like the ld doesn't
proxy->master = master;
proxy->chip_select = chip->chip_select;
proxy->max_speed_hz = chip->max_speed_hz;
+ proxy->mode = chip->mode;
proxy->irq = chip->irq;
proxy->modalias = chip->modalias;
tty = port->tty;
/*
- * FIXME: must not do this in IRQ context,
- * must honour TTY_DONT_FLIP
+ * FIXME: must not do this in IRQ context
*/
tty->ldisc.receive_buf(
tty,
mutex_unlock(&info->bl_mutex);
- if (pdata->negative)
- rlevel = MAX_RADEON_LEVEL - rlevel;
-
if (rlevel < 0)
rlevel = 0;
else if (rlevel > MAX_RADEON_LEVEL)
rlevel = MAX_RADEON_LEVEL;
+ if (pdata->negative)
+ rlevel = MAX_RADEON_LEVEL - rlevel;
+
return rlevel;
}
r.rcall || r.err);
} while (!r.rcall && !r.err && err==-ERESTARTSYS &&
m->trans->status==Connected && !m->err);
+
+ err = -ERESTARTSYS;
}
sigpending = 1;
}
*/
extern struct file_system_type v9fs_fs_type;
-extern struct address_space_operations v9fs_addr_operations;
+extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
extern const struct file_operations v9fs_dir_operations;
extern struct dentry_operations v9fs_dentry_operations;
return retval;
}
-struct address_space_operations v9fs_addr_operations = {
+const struct address_space_operations v9fs_addr_operations = {
.readpage = v9fs_vfs_readpage,
};
fid = V9FS_NOFID;
put_fid:
- if (fid >= 0)
+ if (fid != V9FS_NOFID)
v9fs_put_idpool(fid, &v9ses->fidpool);
kfree(fcall);
return generic_block_bmap(mapping, block, adfs_get_block);
}
-static struct address_space_operations adfs_aops = {
+static const struct address_space_operations adfs_aops = {
.readpage = adfs_readpage,
.writepage = adfs_writepage,
.sync_page = block_sync_page,
extern const struct file_operations affs_file_operations;
extern const struct file_operations affs_file_operations_ofs;
extern const struct file_operations affs_dir_operations;
-extern struct address_space_operations affs_symlink_aops;
-extern struct address_space_operations affs_aops;
-extern struct address_space_operations affs_aops_ofs;
+extern const struct address_space_operations affs_symlink_aops;
+extern const struct address_space_operations affs_aops;
+extern const struct address_space_operations affs_aops_ofs;
extern struct dentry_operations affs_dentry_operations;
extern struct dentry_operations affs_dentry_operations_intl;
{
return generic_block_bmap(mapping,block,affs_get_block);
}
-struct address_space_operations affs_aops = {
+const struct address_space_operations affs_aops = {
.readpage = affs_readpage,
.writepage = affs_writepage,
.sync_page = block_sync_page,
goto done;
}
-struct address_space_operations affs_aops_ofs = {
+const struct address_space_operations affs_aops_ofs = {
.readpage = affs_readpage_ofs,
//.writepage = affs_writepage_ofs,
//.sync_page = affs_sync_page_ofs,
return err;
}
-struct address_space_operations affs_symlink_aops = {
+const struct address_space_operations affs_symlink_aops = {
.readpage = affs_symlink_readpage,
};
.getattr = afs_inode_getattr,
};
-struct address_space_operations afs_fs_aops = {
+const struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
.sync_page = block_sync_page,
.set_page_dirty = __set_page_dirty_nobuffers,
/*
* file.c
*/
-extern struct address_space_operations afs_fs_aops;
+extern const struct address_space_operations afs_fs_aops;
extern struct inode_operations afs_file_inode_operations;
#ifdef AFS_CACHING_SUPPORT
.lookup = befs_lookup,
};
-static struct address_space_operations befs_aops = {
+static const struct address_space_operations befs_aops = {
.readpage = befs_readpage,
.sync_page = block_sync_page,
.bmap = befs_bmap,
/* file.c */
extern struct inode_operations bfs_file_inops;
extern const struct file_operations bfs_file_operations;
-extern struct address_space_operations bfs_aops;
+extern const struct address_space_operations bfs_aops;
/* dir.c */
extern struct inode_operations bfs_dir_inops;
return generic_block_bmap(mapping, block, bfs_get_block);
}
-struct address_space_operations bfs_aops = {
+const struct address_space_operations bfs_aops = {
.readpage = bfs_readpage,
.writepage = bfs_writepage,
.sync_page = block_sync_page,
return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
}
-struct address_space_operations def_blk_aops = {
+const struct address_space_operations def_blk_aops = {
.readpage = blkdev_readpage,
.writepage = blkdev_writepage,
.sync_page = block_sync_page,
unsigned offset = from & (PAGE_CACHE_SIZE-1);
unsigned to;
struct page *page;
- struct address_space_operations *a_ops = mapping->a_ops;
+ const struct address_space_operations *a_ops = mapping->a_ops;
char *kaddr;
int ret = 0;
#define TRUE 1
#endif
-extern struct address_space_operations cifs_addr_ops;
-extern struct address_space_operations cifs_addr_ops_smallbuf;
+extern const struct address_space_operations cifs_addr_ops;
+extern const struct address_space_operations cifs_addr_ops_smallbuf;
/* Functions related to super block operations */
extern struct super_operations cifs_super_ops;
return 0;
}
-struct address_space_operations cifs_addr_ops = {
+const struct address_space_operations cifs_addr_ops = {
.readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage,
* contain the header plus one complete page of data. Otherwise, we need
* to leave cifs_readpages out of the address space operations.
*/
-struct address_space_operations cifs_addr_ops_smallbuf = {
+const struct address_space_operations cifs_addr_ops_smallbuf = {
.readpage = cifs_readpage,
.writepage = cifs_writepage,
.writepages = cifs_writepages,
return error;
}
-struct address_space_operations coda_symlink_aops = {
+const struct address_space_operations coda_symlink_aops = {
.readpage = coda_symlink_filler,
};
extern struct super_block * configfs_sb;
-static struct address_space_operations configfs_aops = {
+static const struct address_space_operations configfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
.commit_write = simple_commit_write
static struct super_operations cramfs_ops;
static struct inode_operations cramfs_dir_inode_operations;
static const struct file_operations cramfs_directory_operations;
-static struct address_space_operations cramfs_aops;
+static const struct address_space_operations cramfs_aops;
static DEFINE_MUTEX(read_mutex);
return 0;
}
-static struct address_space_operations cramfs_aops = {
+static const struct address_space_operations cramfs_aops = {
.readpage = cramfs_readpage
};
{
return generic_block_bmap(mapping,block,efs_get_block);
}
-static struct address_space_operations efs_aops = {
+static const struct address_space_operations efs_aops = {
.readpage = efs_readpage,
.sync_page = block_sync_page,
.bmap = _efs_bmap
return err;
}
-struct address_space_operations efs_symlink_aops = {
+const struct address_space_operations efs_symlink_aops = {
.readpage = efs_symlink_readpage
};
extern const struct file_operations ext2_xip_file_operations;
/* inode.c */
-extern struct address_space_operations ext2_aops;
-extern struct address_space_operations ext2_aops_xip;
-extern struct address_space_operations ext2_nobh_aops;
+extern const struct address_space_operations ext2_aops;
+extern const struct address_space_operations ext2_aops_xip;
+extern const struct address_space_operations ext2_nobh_aops;
/* namei.c */
extern struct inode_operations ext2_dir_inode_operations;
return mpage_writepages(mapping, wbc, ext2_get_block);
}
-struct address_space_operations ext2_aops = {
+const struct address_space_operations ext2_aops = {
.readpage = ext2_readpage,
.readpages = ext2_readpages,
.writepage = ext2_writepage,
.migratepage = buffer_migrate_page,
};
-struct address_space_operations ext2_aops_xip = {
+const struct address_space_operations ext2_aops_xip = {
.bmap = ext2_bmap,
.get_xip_page = ext2_get_xip_page,
};
-struct address_space_operations ext2_nobh_aops = {
+const struct address_space_operations ext2_nobh_aops = {
.readpage = ext2_readpage,
.readpages = ext2_readpages,
.writepage = ext2_nobh_writepage,
return __set_page_dirty_nobuffers(page);
}
-static struct address_space_operations ext3_ordered_aops = {
+static const struct address_space_operations ext3_ordered_aops = {
.readpage = ext3_readpage,
.readpages = ext3_readpages,
.writepage = ext3_ordered_writepage,
.migratepage = buffer_migrate_page,
};
-static struct address_space_operations ext3_writeback_aops = {
+static const struct address_space_operations ext3_writeback_aops = {
.readpage = ext3_readpage,
.readpages = ext3_readpages,
.writepage = ext3_writeback_writepage,
.migratepage = buffer_migrate_page,
};
-static struct address_space_operations ext3_journalled_aops = {
+static const struct address_space_operations ext3_journalled_aops = {
.readpage = ext3_readpage,
.readpages = ext3_readpages,
.writepage = ext3_journalled_writepage,
return generic_block_bmap(mapping, block, fat_get_block);
}
-static struct address_space_operations fat_aops = {
+static const struct address_space_operations fat_aops = {
.readpage = fat_readpage,
.readpages = fat_readpages,
.writepage = fat_writepage,
/*
* Adress space operations for immed files and directories.
*/
-struct address_space_operations vxfs_immed_aops = {
+const struct address_space_operations vxfs_immed_aops = {
.readpage = vxfs_immed_readpage,
};
#include "vxfs_extern.h"
-extern struct address_space_operations vxfs_aops;
-extern struct address_space_operations vxfs_immed_aops;
+extern const struct address_space_operations vxfs_aops;
+extern const struct address_space_operations vxfs_immed_aops;
extern struct inode_operations vxfs_immed_symlink_iops;
{
struct super_block *sbp = ip->i_sb;
struct vxfs_inode_info *vip;
- struct address_space_operations *aops;
+ const struct address_space_operations *aops;
ino_t ino = ip->i_ino;
if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist)))
static int vxfs_readpage(struct file *, struct page *);
static sector_t vxfs_bmap(struct address_space *, sector_t);
-struct address_space_operations vxfs_aops = {
+const struct address_space_operations vxfs_aops = {
.readpage = vxfs_readpage,
.bmap = vxfs_bmap,
.sync_page = block_sync_page,
/* no mmap and sendfile */
};
-static struct address_space_operations fuse_file_aops = {
+static const struct address_space_operations fuse_file_aops = {
.readpage = fuse_readpage,
.prepare_write = fuse_prepare_write,
.commit_write = fuse_commit_write,
extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
/* inode.c */
-extern struct address_space_operations hfs_aops;
-extern struct address_space_operations hfs_btree_aops;
+extern const struct address_space_operations hfs_aops;
+extern const struct address_space_operations hfs_btree_aops;
extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int);
extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
return mpage_writepages(mapping, wbc, hfs_get_block);
}
-struct address_space_operations hfs_btree_aops = {
+const struct address_space_operations hfs_btree_aops = {
.readpage = hfs_readpage,
.writepage = hfs_writepage,
.sync_page = block_sync_page,
.releasepage = hfs_releasepage,
};
-struct address_space_operations hfs_aops = {
+const struct address_space_operations hfs_aops = {
.readpage = hfs_readpage,
.writepage = hfs_writepage,
.sync_page = block_sync_page,
void hfsplus_file_truncate(struct inode *);
/* inode.c */
-extern struct address_space_operations hfsplus_aops;
-extern struct address_space_operations hfsplus_btree_aops;
+extern const struct address_space_operations hfsplus_aops;
+extern const struct address_space_operations hfsplus_btree_aops;
void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *);
void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *);
return mpage_writepages(mapping, wbc, hfsplus_get_block);
}
-struct address_space_operations hfsplus_btree_aops = {
+const struct address_space_operations hfsplus_btree_aops = {
.readpage = hfsplus_readpage,
.writepage = hfsplus_writepage,
.sync_page = block_sync_page,
.releasepage = hfsplus_releasepage,
};
-struct address_space_operations hfsplus_aops = {
+const struct address_space_operations hfsplus_aops = {
.readpage = hfsplus_readpage,
.writepage = hfsplus_writepage,
.sync_page = block_sync_page,
static struct inode_operations hostfs_iops;
static struct inode_operations hostfs_dir_iops;
-static struct address_space_operations hostfs_link_aops;
+static const struct address_space_operations hostfs_link_aops;
#ifndef MODULE
static int __init hostfs_args(char *options, int *add)
return(err);
}
-static struct address_space_operations hostfs_aops = {
+static const struct address_space_operations hostfs_aops = {
.writepage = hostfs_writepage,
.readpage = hostfs_readpage,
.set_page_dirty = __set_page_dirty_nobuffers,
return(err);
}
-static struct address_space_operations hostfs_link_aops = {
+static const struct address_space_operations hostfs_link_aops = {
.readpage = hostfs_link_readpage,
};
{
return generic_block_bmap(mapping,block,hpfs_get_block);
}
-struct address_space_operations hpfs_aops = {
+const struct address_space_operations hpfs_aops = {
.readpage = hpfs_readpage,
.writepage = hpfs_writepage,
.sync_page = block_sync_page,
int hpfs_file_fsync(struct file *, struct dentry *, int);
extern const struct file_operations hpfs_file_ops;
extern struct inode_operations hpfs_file_iops;
-extern struct address_space_operations hpfs_aops;
+extern const struct address_space_operations hpfs_aops;
/* inode.c */
/* namei.c */
extern struct inode_operations hpfs_dir_iops;
-extern struct address_space_operations hpfs_symlink_aops;
+extern const struct address_space_operations hpfs_symlink_aops;
static inline struct hpfs_inode_info *hpfs_i(struct inode *inode)
{
return err;
}
-struct address_space_operations hpfs_symlink_aops = {
+const struct address_space_operations hpfs_symlink_aops = {
.readpage = hpfs_symlink_readpage
};
#define HUGETLBFS_MAGIC 0x958458f6
static struct super_operations hugetlbfs_ops;
-static struct address_space_operations hugetlbfs_aops;
+static const struct address_space_operations hugetlbfs_aops;
const struct file_operations hugetlbfs_file_operations;
static struct inode_operations hugetlbfs_dir_inode_operations;
static struct inode_operations hugetlbfs_inode_operations;
kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
}
-static struct address_space_operations hugetlbfs_aops = {
+static const struct address_space_operations hugetlbfs_aops = {
.readpage = hugetlbfs_readpage,
.prepare_write = hugetlbfs_prepare_write,
.commit_write = hugetlbfs_commit_write,
static struct inode *alloc_inode(struct super_block *sb)
{
- static struct address_space_operations empty_aops;
+ static const struct address_space_operations empty_aops;
static struct inode_operations empty_iops;
static const struct file_operations empty_fops;
struct inode *inode;
return err;
}
-struct address_space_operations zisofs_aops = {
+const struct address_space_operations zisofs_aops = {
.readpage = zisofs_readpage,
/* No sync_page operation supported? */
/* No bmap operation supported */
return generic_block_bmap(mapping,block,isofs_get_block);
}
-static struct address_space_operations isofs_aops = {
+static const struct address_space_operations isofs_aops = {
.readpage = isofs_readpage,
.sync_page = block_sync_page,
.bmap = _isofs_bmap
extern struct inode_operations isofs_dir_inode_operations;
extern const struct file_operations isofs_dir_operations;
-extern struct address_space_operations isofs_symlink_aops;
+extern const struct address_space_operations isofs_symlink_aops;
extern struct export_operations isofs_export_ops;
return -EIO;
}
-struct address_space_operations isofs_symlink_aops = {
+const struct address_space_operations isofs_symlink_aops = {
.readpage = rock_ridge_symlink_readpage
};
*/
#ifdef CONFIG_ZISOFS
-extern struct address_space_operations zisofs_aops;
+extern const struct address_space_operations zisofs_aops;
extern int __init zisofs_init(void);
extern void zisofs_cleanup(void);
#endif
static struct inode_operations jffs_file_inode_operations;
static const struct file_operations jffs_dir_operations;
static struct inode_operations jffs_dir_inode_operations;
-static struct address_space_operations jffs_address_operations;
+static const struct address_space_operations jffs_address_operations;
kmem_cache_t *node_cache = NULL;
kmem_cache_t *fm_cache = NULL;
} /* jffs_ioctl() */
-static struct address_space_operations jffs_address_operations = {
+static const struct address_space_operations jffs_address_operations = {
.readpage = jffs_readpage,
.prepare_write = jffs_prepare_write,
.commit_write = jffs_commit_write,
.removexattr = jffs2_removexattr
};
-struct address_space_operations jffs2_file_address_operations =
+const struct address_space_operations jffs2_file_address_operations =
{
.readpage = jffs2_readpage,
.prepare_write =jffs2_prepare_write,
/* file.c */
extern const struct file_operations jffs2_file_operations;
extern struct inode_operations jffs2_file_inode_operations;
-extern struct address_space_operations jffs2_file_address_operations;
+extern const struct address_space_operations jffs2_file_address_operations;
int jffs2_fsync(struct file *, struct dentry *, int);
int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
offset, nr_segs, jfs_get_block, NULL);
}
-struct address_space_operations jfs_aops = {
+const struct address_space_operations jfs_aops = {
.readpage = jfs_readpage,
.readpages = jfs_readpages,
.writepage = jfs_writepage,
extern struct dentry *jfs_get_parent(struct dentry *dentry);
extern void jfs_set_inode_flags(struct inode *);
-extern struct address_space_operations jfs_aops;
+extern const struct address_space_operations jfs_aops;
extern struct inode_operations jfs_dir_inode_operations;
extern const struct file_operations jfs_dir_operations;
extern struct inode_operations jfs_file_inode_operations;
metapage_releasepage(page, 0);
}
-struct address_space_operations jfs_metapage_aops = {
+const struct address_space_operations jfs_metapage_aops = {
.readpage = metapage_readpage,
.writepage = metapage_writepage,
.sync_page = block_sync_page,
put_metapage(mp);
}
-extern struct address_space_operations jfs_metapage_aops;
+extern const struct address_space_operations jfs_metapage_aops;
/*
* This routines invalidate all pages for an extent.
{
return generic_block_bmap(mapping,block,minix_get_block);
}
-static struct address_space_operations minix_aops = {
+static const struct address_space_operations minix_aops = {
.readpage = minix_readpage,
.writepage = minix_writepage,
.sync_page = block_sync_page,
extern struct dentry_operations ncp_root_dentry_operations;
#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
-extern struct address_space_operations ncp_symlink_aops;
+extern const struct address_space_operations ncp_symlink_aops;
extern int ncp_symlink(struct inode*, struct dentry*, const char*);
#endif
/*
* symlinks can't do much...
*/
-struct address_space_operations ncp_symlink_aops = {
+const struct address_space_operations ncp_symlink_aops = {
.readpage = ncp_symlink_readpage,
};
return !nfs_wb_page(page->mapping->host, page);
}
-struct address_space_operations nfs_file_aops = {
+const struct address_space_operations nfs_file_aops = {
.readpage = nfs_readpage,
.readpages = nfs_readpages,
.set_page_dirty = __set_page_dirty_nobuffers,
/**
* ntfs_aops - general address space operations for inodes and attributes
*/
-struct address_space_operations ntfs_aops = {
+const struct address_space_operations ntfs_aops = {
.readpage = ntfs_readpage, /* Fill page with data. */
.sync_page = block_sync_page, /* Currently, just unplugs the
disk request queue. */
* ntfs_mst_aops - general address space operations for mst protecteed inodes
* and attributes
*/
-struct address_space_operations ntfs_mst_aops = {
+const struct address_space_operations ntfs_mst_aops = {
.readpage = ntfs_readpage, /* Fill page with data. */
.sync_page = block_sync_page, /* Currently, just unplugs the
disk request queue. */
extern struct kmem_cache *ntfs_index_ctx_cache;
/* The various operations structs defined throughout the driver files. */
-extern struct address_space_operations ntfs_aops;
-extern struct address_space_operations ntfs_mst_aops;
+extern const struct address_space_operations ntfs_aops;
+extern const struct address_space_operations ntfs_mst_aops;
extern const struct file_operations ntfs_file_ops;
extern struct inode_operations ntfs_file_inode_ops;
return ret;
}
-struct address_space_operations ocfs2_aops = {
+const struct address_space_operations ocfs2_aops = {
.readpage = ocfs2_readpage,
.writepage = ocfs2_writepage,
.prepare_write = ocfs2_prepare_write,
extern kmem_cache_t *ocfs2_inode_cache;
-extern struct address_space_operations ocfs2_aops;
+extern const struct address_space_operations ocfs2_aops;
struct buffer_head *ocfs2_bread(struct inode *inode, int block,
int *err, int reada);
{
return generic_block_bmap(mapping,block,qnx4_get_block);
}
-static struct address_space_operations qnx4_aops = {
+static const struct address_space_operations qnx4_aops = {
.readpage = qnx4_readpage,
.writepage = qnx4_writepage,
.sync_page = block_sync_page,
#include <linux/fs.h>
-struct address_space_operations ramfs_aops = {
+const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
.commit_write = simple_commit_write
static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
-struct address_space_operations ramfs_aops = {
+const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
.commit_write = simple_commit_write
*/
-extern struct address_space_operations ramfs_aops;
+extern const struct address_space_operations ramfs_aops;
extern const struct file_operations ramfs_file_operations;
extern struct inode_operations ramfs_file_inode_operations;
return error;
}
-struct address_space_operations reiserfs_address_space_operations = {
+const struct address_space_operations reiserfs_address_space_operations = {
.writepage = reiserfs_writepage,
.readpage = reiserfs_readpage,
.readpages = reiserfs_readpages,
/* Mapping from our types to the kernel */
-static struct address_space_operations romfs_aops = {
+static const struct address_space_operations romfs_aops = {
.readpage = romfs_readpage
};
return status;
}
-struct address_space_operations smb_file_aops = {
+const struct address_space_operations smb_file_aops = {
.readpage = smb_readpage,
.writepage = smb_writepage,
.prepare_write = smb_prepare_write,
extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
/* file.c */
-extern struct address_space_operations smb_file_aops;
+extern const struct address_space_operations smb_file_aops;
extern const struct file_operations smb_file_operations;
extern struct inode_operations smb_file_inode_operations;
/* ioctl.c */
extern struct super_block * sysfs_sb;
-static struct address_space_operations sysfs_aops = {
+static const struct address_space_operations sysfs_aops = {
.readpage = simple_readpage,
.prepare_write = simple_prepare_write,
.commit_write = simple_commit_write
{
return generic_block_bmap(mapping,block,get_block);
}
-struct address_space_operations sysv_aops = {
+const struct address_space_operations sysv_aops = {
.readpage = sysv_readpage,
.writepage = sysv_writepage,
.sync_page = block_sync_page,
extern struct inode_operations sysv_fast_symlink_inode_operations;
extern const struct file_operations sysv_file_operations;
extern const struct file_operations sysv_dir_operations;
-extern struct address_space_operations sysv_aops;
+extern const struct address_space_operations sysv_aops;
extern struct super_operations sysv_sops;
extern struct dentry_operations sysv_dentry_operations;
return 0;
}
-struct address_space_operations udf_adinicb_aops = {
+const struct address_space_operations udf_adinicb_aops = {
.readpage = udf_adinicb_readpage,
.writepage = udf_adinicb_writepage,
.sync_page = block_sync_page,
return generic_block_bmap(mapping,block,udf_get_block);
}
-struct address_space_operations udf_aops = {
+const struct address_space_operations udf_aops = {
.readpage = udf_readpage,
.writepage = udf_writepage,
.sync_page = block_sync_page,
/*
* symlinks can't do much...
*/
-struct address_space_operations udf_symlink_aops = {
+const struct address_space_operations udf_symlink_aops = {
.readpage = udf_symlink_filler,
};
extern const struct file_operations udf_dir_operations;
extern struct inode_operations udf_file_inode_operations;
extern const struct file_operations udf_file_operations;
-extern struct address_space_operations udf_aops;
-extern struct address_space_operations udf_adinicb_aops;
-extern struct address_space_operations udf_symlink_aops;
+extern const struct address_space_operations udf_aops;
+extern const struct address_space_operations udf_adinicb_aops;
+extern const struct address_space_operations udf_symlink_aops;
struct udf_fileident_bh
{
{
return generic_block_bmap(mapping,block,ufs_getfrag_block);
}
-struct address_space_operations ufs_aops = {
+const struct address_space_operations ufs_aops = {
.readpage = ufs_readpage,
.writepage = ufs_writepage,
.sync_page = block_sync_page,
block_invalidatepage(page, offset);
}
-struct address_space_operations xfs_address_space_operations = {
+const struct address_space_operations xfs_address_space_operations = {
.readpage = xfs_vm_readpage,
.readpages = xfs_vm_readpages,
.writepage = xfs_vm_writepage,
struct work_struct io_work; /* xfsdatad work queue */
} xfs_ioend_t;
-extern struct address_space_operations xfs_address_space_operations;
+extern const struct address_space_operations xfs_address_space_operations;
extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
#endif /* __XFS_AOPS_H__ */
struct backing_dev_info *bdi;
struct inode *inode;
struct address_space *mapping;
- static struct address_space_operations mapping_aops = {
+ static const struct address_space_operations mapping_aops = {
.sync_page = block_sync_page,
.migratepage = fail_migrate_page,
};
VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
} \
\
+ /* Kernel symbol table: Normal unused symbols */ \
+ __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \
+ *(__ksymtab_unused) \
+ VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \
+ } \
+ \
+ /* Kernel symbol table: GPL-only unused symbols */ \
+ __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \
+ *(__ksymtab_unused_gpl) \
+ VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \
+ } \
+ \
/* Kernel symbol table: GPL-future-only symbols */ \
__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
} \
\
+ /* Kernel symbol table: Normal unused symbols */ \
+ __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \
+ *(__kcrctab_unused) \
+ VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \
+ } \
+ \
+ /* Kernel symbol table: GPL-only unused symbols */ \
+ __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \
+ *(__kcrctab_unused_gpl) \
+ VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \
+ } \
+ \
/* Kernel symbol table: GPL-future-only symbols */ \
__kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
#define SN_SAL_GET_PROM_FEATURE_SET 0x02000065
#define SN_SAL_SET_OS_FEATURE_SET 0x02000066
#define SN_SAL_INJECT_ERROR 0x02000067
+#define SN_SAL_SET_CPU_NUMBER 0x02000068
/*
* Service-specific constants
local_irq_restore(irq_flags);
return ret_stuff.status;
}
+
+static inline int
+ia64_sn_set_cpu_number(int cpu)
+{
+ struct ia64_sal_retval rv;
+
+ SAL_CALL_NOLOCK(rv, SN_SAL_SET_CPU_NUMBER, cpu, 0, 0, 0, 0, 0, 0);
+ return rv.status;
+}
#endif /* _ASM_IA64_SN_SN_SAL_H */
__asm__ __volatile__ ("trap #2" \
: "=g" (__res) \
: "0" (__res) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
__asm__ __volatile__ ("trap #2" \
: "=g" (__res) \
: "0" (__res), "d" (__a) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
__asm__ __volatile__ ("trap #2" \
: "=g" (__res) \
: "0" (__res), "d" (__a), "d" (__b) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
: "=g" (__res) \
: "0" (__res), "d" (__a), "d" (__b), \
"d" (__c) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
: "=g" (__res) \
: "0" (__res), "d" (__a), "d" (__b), \
"d" (__c), "d" (__d) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
: "=g" (__res) \
: "0" (__res), "d" (__a), "d" (__b), \
"d" (__c), "d" (__d), "d" (__e) \
- : "%d0"); \
+ ); \
__bsc_return(type,__res); \
}
int type;
u32 model;
- int modem:1;
+ unsigned int modem:1;
struct ac97_ops *codec_ops;
extern struct inode_operations coda_file_inode_operations;
extern struct inode_operations coda_ioctl_inode_operations;
-extern struct address_space_operations coda_file_aops;
-extern struct address_space_operations coda_symlink_aops;
+extern const struct address_space_operations coda_file_aops;
+extern const struct address_space_operations coda_symlink_aops;
extern const struct file_operations coda_dir_operations;
extern const struct file_operations coda_file_operations;
extern struct inode_operations efs_dir_inode_operations;
extern const struct file_operations efs_dir_operations;
-extern struct address_space_operations efs_symlink_aops;
+extern const struct address_space_operations efs_symlink_aops;
extern void efs_read_inode(struct inode *);
extern efs_block_t efs_map_block(struct inode *, efs_block_t);
unsigned int truncate_count; /* Cover race condition with truncate */
unsigned long nrpages; /* number of total pages */
pgoff_t writeback_index;/* writeback starts here */
- struct address_space_operations *a_ops; /* methods */
+ const struct address_space_operations *a_ops; /* methods */
unsigned long flags; /* error bits/gfp mask */
struct backing_dev_info *backing_dev_info; /* device readahead, etc */
spinlock_t private_lock; /* for use by the address_space */
extern void bdput(struct block_device *);
extern struct block_device *open_by_devnum(dev_t, unsigned);
extern const struct file_operations def_blk_fops;
-extern struct address_space_operations def_blk_aops;
+extern const struct address_space_operations def_blk_aops;
extern const struct file_operations def_chr_fops;
extern const struct file_operations bad_sock_fops;
extern const struct file_operations def_fifo_fops;
unsigned auto_poll : 1; /* supports nop auto-poll */
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
+ unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
struct device gendev;
struct completion gendev_rel_comp; /* To deal with device release() */
{
unsigned long flags;
spin_lock_irqsave(&t->buf.lock, flags);
- if (t->buf.tail != NULL) {
- t->buf.tail->active = 0;
+ if (t->buf.tail != NULL)
t->buf.tail->commit = t->buf.tail->used;
- }
spin_unlock_irqrestore(&t->buf.lock, flags);
schedule_work(&t->buf.work);
}
#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
__EXPORT_SYMBOL(sym, "_gpl_future")
+
+#ifdef CONFIG_UNUSED_SYMBOLS
+#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
+#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
+#else
+#define EXPORT_UNUSED_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+#endif
+
#endif
struct module_ref
unsigned int num_gpl_syms;
const unsigned long *gpl_crcs;
+ /* unused exported symbols. */
+ const struct kernel_symbol *unused_syms;
+ unsigned int num_unused_syms;
+ const unsigned long *unused_crcs;
+ /* GPL-only, unused exported symbols. */
+ const struct kernel_symbol *unused_gpl_syms;
+ unsigned int num_unused_gpl_syms;
+ const unsigned long *unused_gpl_crcs;
+
/* symbols that will be GPL-only in the near future. */
const struct kernel_symbol *gpl_future_syms;
unsigned int num_gpl_future_syms;
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
#define EXPORT_SYMBOL_GPL_FUTURE(sym)
+#define EXPORT_UNUSED_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)
/* Given an address, look for it in the exception tables. */
static inline const struct exception_table_entry *
extern struct inode_operations nfs3_file_inode_operations;
#endif /* CONFIG_NFS_V3 */
extern const struct file_operations nfs_file_operations;
-extern struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_file_aops;
static inline struct rpc_cred *nfs_file_cred(struct file *file)
{
#ifndef _LINUX_PLIST_H_
#define _LINUX_PLIST_H_
+#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/spinlock_types.h>
/* file.c */
extern struct inode_operations reiserfs_file_inode_operations;
extern const struct file_operations reiserfs_file_operations;
-extern struct address_space_operations reiserfs_address_space_operations;
+extern const struct address_space_operations reiserfs_address_space_operations;
/* fix_nodes.c */
u16 bus_num;
u16 chip_select;
+ /* mode becomes spi_device.mode, and is essential for chips
+ * where the default of SPI_CS_HIGH = 0 is wrong.
+ */
+ u8 mode;
+
/* ... may need additional spi_device chip config data here.
* avoid stuff protocol drivers can set; but include stuff
* needed to behave without being bound to a driver:
- * - chipselect polarity
* - quirks like clock rate mattering when not selected
*/
};
unsigned char *flag_buf_ptr;
int used;
int size;
- int active;
int commit;
int read;
/* Data points here */
#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */
#define TTY_PUSH 6 /* n_tty private */
#define TTY_CLOSING 7 /* ->close() in progress */
-#define TTY_DONT_FLIP 8 /* Defer buffer flip */
#define TTY_LDISC 9 /* Line discipline attached */
#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */
#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
unsigned char ch, char flag)
{
struct tty_buffer *tb = tty->buf.tail;
- if (tb && tb->active && tb->used < tb->size) {
+ if (tb && tb->used < tb->size) {
tb->flag_buf_ptr[tb->used] = flag;
tb->char_buf_ptr[tb->used++] = ch;
return 1;
extern struct inode_operations ufs_file_inode_operations;
extern const struct file_operations ufs_file_operations;
-extern struct address_space_operations ufs_aops;
+extern const struct address_space_operations ufs_aops;
/* ialloc.c */
extern void ufs_free_inode (struct inode *inode);
#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
+#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
+#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
+#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int)
#define WDIOF_UNKNOWN -1 /* Unknown flag error */
#define WDIOS_UNKNOWN -1 /* Unknown status error */
#define WDIOF_EXTERN2 0x0008 /* External relay 2 */
#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */
#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */
-#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
-#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
-#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
+#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
+#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
+#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
+#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */
#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */
#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */
-/* Rewritten by Rusty Russell, on the backs of many others...
+/*
Copyright (C) 2002 Richard Henderson
Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
extern const struct kernel_symbol __stop___ksymtab_gpl[];
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
+extern const struct kernel_symbol __start___ksymtab_unused[];
+extern const struct kernel_symbol __stop___ksymtab_unused[];
+extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
+extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
+extern const struct kernel_symbol __start___ksymtab_gpl_future[];
+extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const unsigned long __start___kcrctab[];
extern const unsigned long __start___kcrctab_gpl[];
extern const unsigned long __start___kcrctab_gpl_future[];
+extern const unsigned long __start___kcrctab_unused[];
+extern const unsigned long __start___kcrctab_unused_gpl[];
#ifndef CONFIG_MODVERSIONS
#define symversion(base, idx) NULL
return NULL;
}
+static void printk_unused_warning(const char *name)
+{
+ printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
+ "however this module is using it.\n", name);
+ printk(KERN_WARNING "This symbol will go away in the future.\n");
+ printk(KERN_WARNING "Please evalute if this is the right api to use, "
+ "and if it really is, submit a report the linux kernel "
+ "mailinglist together with submitting your code for "
+ "inclusion.\n");
+}
+
/* Find a symbol, return value, crc and module which owns it */
static unsigned long __find_symbol(const char *name,
struct module **owner,
return ks->value;
}
+ ks = lookup_symbol(name, __start___ksymtab_unused,
+ __stop___ksymtab_unused);
+ if (ks) {
+ printk_unused_warning(name);
+ *crc = symversion(__start___kcrctab_unused,
+ (ks - __start___ksymtab_unused));
+ return ks->value;
+ }
+
+ if (gplok)
+ ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
+ __stop___ksymtab_unused_gpl);
+ if (ks) {
+ printk_unused_warning(name);
+ *crc = symversion(__start___kcrctab_unused_gpl,
+ (ks - __start___ksymtab_unused_gpl));
+ return ks->value;
+ }
+
/* Now try modules. */
list_for_each_entry(mod, &modules, list) {
*owner = mod;
return ks->value;
}
}
+ ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
+ if (ks) {
+ printk_unused_warning(name);
+ *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
+ return ks->value;
+ }
+
+ if (gplok) {
+ ks = lookup_symbol(name, mod->unused_gpl_syms,
+ mod->unused_gpl_syms + mod->num_unused_gpl_syms);
+ if (ks) {
+ printk_unused_warning(name);
+ *crc = symversion(mod->unused_gpl_crcs,
+ (ks - mod->unused_gpl_syms));
+ return ks->value;
+ }
+ }
ks = lookup_symbol(name, mod->gpl_future_syms,
(mod->gpl_future_syms +
mod->num_gpl_future_syms));
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
char *secstrings, *args, *modmagic, *strtab = NULL;
- unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
- exportindex, modindex, obsparmindex, infoindex, gplindex,
- crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
- gplfuturecrcindex, unwindex = 0;
+ unsigned int i;
+ unsigned int symindex = 0;
+ unsigned int strindex = 0;
+ unsigned int setupindex;
+ unsigned int exindex;
+ unsigned int exportindex;
+ unsigned int modindex;
+ unsigned int obsparmindex;
+ unsigned int infoindex;
+ unsigned int gplindex;
+ unsigned int crcindex;
+ unsigned int gplcrcindex;
+ unsigned int versindex;
+ unsigned int pcpuindex;
+ unsigned int gplfutureindex;
+ unsigned int gplfuturecrcindex;
+ unsigned int unwindex = 0;
+ unsigned int unusedindex;
+ unsigned int unusedcrcindex;
+ unsigned int unusedgplindex;
+ unsigned int unusedgplcrcindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
+ unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
+ unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
+ unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
+ unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
sizeof(*mod->gpl_future_syms);
+ mod->num_unused_syms = sechdrs[unusedindex].sh_size /
+ sizeof(*mod->unused_syms);
+ mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
+ sizeof(*mod->unused_gpl_syms);
mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
if (gplfuturecrcindex)
mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
+ mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
+ if (unusedcrcindex)
+ mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
+ mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
+ if (unusedgplcrcindex)
+ mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
+
#ifdef CONFIG_MODVERSIONS
if ((mod->num_syms && !crcindex) ||
(mod->num_gpl_syms && !gplcrcindex) ||
- (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
+ (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
+ (mod->num_unused_syms && !unusedcrcindex) ||
+ (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
add_taint(TAINT_FORCED_MODULE);
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does.
+config UNUSED_SYMBOLS
+ bool "Enable unused/obsolete exported symbols"
+ default y if X86
+ help
+ Unused but exported symbols make the kernel needlessly bigger. For
+ that reason most of these unused exports will soon be removed. This
+ option is provided temporarily to provide a transition period in case
+ some external kernel module needs one of these symbols anyway. If you
+ encounter such a case in your module, consider if you are actually
+ using the right API. (rationale: since nobody in the kernel is using
+ this in a module, there is a pretty good chance it's actually the
+ wrong interface to use). If you really need the symbol, please send a
+ mail to the linux kernel mailing list mentioning the symbol and why
+ you really need it, and what the merge plan to the mainline kernel for
+ your module is.
+
config DEBUG_KERNEL
bool "Kernel debugging"
help
{
struct file *file = iocb->ki_filp;
struct address_space * mapping = file->f_mapping;
- struct address_space_operations *a_ops = mapping->a_ops;
+ const struct address_space_operations *a_ops = mapping->a_ops;
struct inode *inode = mapping->host;
long status = 0;
struct page *page;
unsigned long nr_segs, loff_t *ppos)
{
struct file *file = iocb->ki_filp;
- struct address_space * mapping = file->f_mapping;
+ const struct address_space * mapping = file->f_mapping;
size_t ocount; /* original count */
size_t count; /* after file limit checks */
struct inode *inode = mapping->host;
size_t count, loff_t pos, loff_t *ppos)
{
struct address_space * mapping = filp->f_mapping;
- struct address_space_operations *a_ops = mapping->a_ops;
+ const struct address_space_operations *a_ops = mapping->a_ops;
struct inode *inode = mapping->host;
long status = 0;
struct page *page;
}
static struct super_operations shmem_ops;
-static struct address_space_operations shmem_aops;
+static const struct address_space_operations shmem_aops;
static struct file_operations shmem_file_operations;
static struct inode_operations shmem_inode_operations;
static struct inode_operations shmem_dir_inode_operations;
printk(KERN_INFO "shmem_inode_cache: not all structures were freed\n");
}
-static struct address_space_operations shmem_aops = {
+static const struct address_space_operations shmem_aops = {
.writepage = shmem_writepage,
.set_page_dirty = __set_page_dirty_nobuffers,
#ifdef CONFIG_TMPFS
* vmscan's shrink_list, to make sync_page look nicer, and to allow
* future use of radix_tree tags in the swap cache.
*/
-static struct address_space_operations swap_aops = {
+static const struct address_space_operations swap_aops = {
.writepage = swap_writepage,
.sync_page = block_sync_page,
.set_page_dirty = __set_page_dirty_nobuffers,
BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
- if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
- tty_buffer_request_room(tty, skb->len);
- tty_insert_flip_string(tty, skb->data, skb->len);
- tty_flip_buffer_push(tty);
- } else
- tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
+ tty_insert_flip_string(tty, skb->data, skb->len);
+ tty_flip_buffer_push(tty);
kfree_skb(skb);
}
MODULE_DEVICE_TABLE(pnp, cs4232_pnp_table);
-static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
+static int __init cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct address_info *isapnpcfg;
unsigned sixchannel: 1; /* 8233/35 with 6 channel support */
unsigned volume: 1;
- int locked_rate : 1;
+ unsigned locked_rate : 1;
int mixer_vol; /* 8233/35 volume - not yet implemented */