diff options
| author | Benjamin LaHaise <bcrl@redhat.com> | 2002-10-10 05:33:37 -0400 |
|---|---|---|
| committer | Benjamin LaHaise <bcrl@redhat.com> | 2002-10-10 05:33:37 -0400 |
| commit | 994b3fb017e7ea4a1124b79a257fdf69dbbea16f (patch) | |
| tree | 692e5e965b1dbbd63e111296a427a727284e10c6 | |
| parent | ecb796f5bc603e978b41e868f2f234a249ab288c (diff) | |
| parent | 469d2810663a7084344107cd702dabeeb7e261ed (diff) | |
Merge redhat.com:/md0/linus-2.5 into redhat.com:/md0/aio-2.5
35 files changed, 1965 insertions, 2280 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 4cde8648511a..447e10f10b23 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -738,7 +738,7 @@ S: Maintained IBM ServeRAID RAID DRIVER P: Jack Hammer -P: Dave Jeffrey +P: Dave Jeffery M: ipslinux@adaptec.com W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html S: Supported diff --git a/arch/alpha/Config.help b/arch/alpha/Config.help index c530295a343d..ae1eb3c6bcc6 100644 --- a/arch/alpha/Config.help +++ b/arch/alpha/Config.help @@ -251,6 +251,10 @@ CONFIG_ALPHA_PRIMO CONFIG_ALPHA_GAMMA Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx. +CONFIG_ALPHA_EV67 + Is this a machine based on the EV67 core? If in doubt, select N here + and the machine will be treated as an EV6. + CONFIG_ALPHA_SRM There are two different types of booting firmware on Alphas: SRM, which is command line driven, and ARC, which uses menus and arrow @@ -610,3 +614,14 @@ CONFIG_DEBUG_SPINLOCK best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +CONFIG_DEBUG_RWLOCK + If you say Y here then read-write lock processing will count how many + times it has tried to get the lock and issue an error message after + too many attempts. If you suspect a rwlock problem or a kernel + hacker asks for this option then say Y. Otherwise say N. + +CONFIG_DEBUG_SEMAPHORE + If you say Y here then semaphore processing will issue lots of + verbose debugging messages. If you suspect a semaphore problem or a + kernel hacker asks for this option then say Y. Otherwise say N. + diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index a9a29bad03b9..58aadf1dd0d0 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -99,30 +99,32 @@ export libs-y MAKEBOOT = $(MAKE) -C arch/alpha/boot -rawboot: +rawboot: vmlinux @$(MAKEBOOT) rawboot +boot: vmlinux + @$(MAKEBOOT) + # # My boot writes directly to a specific disk partition, I doubt most # people will want to do that without changes.. # -msb my-special-boot: +msb my-special-boot: vmlinux @$(MAKEBOOT) msb -bootimage: +bootimage: vmlinux @$(MAKEBOOT) bootimage -srmboot: +srmboot: vmlinux @$(MAKEBOOT) srmboot archclean: - @$(MAKE) -C arch/alpha/kernel clean @$(MAKEBOOT) clean archmrproper: rm -f include/asm-alpha/asm_offsets.h -bootpfile: +bootpfile: vmlinux @$(MAKEBOOT) bootpfile diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index 47c978f51d6a..8ea7df0b78a2 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -8,7 +8,9 @@ # Copyright (C) 1994 by Linus Torvalds # -LINKFLAGS = -static -T bootloader.lds #-N -relax +LINKFLAGS = -static -T bootloader.lds -uvsprintf #-N -relax + +CFLAGS := $(CFLAGS) -I$(TOPDIR)/include .S.s: $(CPP) $(AFLAGS) -traditional -o $*.o $< diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index c0d786677f47..da7c971ed9ca 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -8,8 +8,9 @@ EXTRA_AFLAGS := $(CFLAGS) export-objs := alpha_ksyms.o -obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o irq_alpha.o \ - signal.o setup.o ptrace.o time.o semaphore.o alpha_ksyms.o +obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ + irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \ + alpha_ksyms.o systbls.o # # FIXME! diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index f9797ec48684..f897d9116aae 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -161,7 +161,6 @@ EXPORT_SYMBOL(sys_read); EXPORT_SYMBOL(sys_lseek); EXPORT_SYMBOL(__kernel_execve); EXPORT_SYMBOL(sys_setsid); -EXPORT_SYMBOL(sys_sync); EXPORT_SYMBOL(sys_wait4); /* Networking helper routines. */ diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 0e931707a28f..0ff07ce13175 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -9,8 +9,7 @@ #include <asm/cache.h> #include <asm/asm_offsets.h> #include <asm/thread_info.h> - -#define NR_SYSCALLS 381 +#include <asm/unistd.h> /* * stack offsets @@ -677,6 +676,7 @@ ret_success: .end entSys .align 3 +.globl sys_sigreturn .ent sys_sigreturn sys_sigreturn: mov $30,$17 @@ -688,6 +688,7 @@ sys_sigreturn: .end sys_sigreturn .align 3 +.globl sys_rt_sigreturn .ent sys_rt_sigreturn sys_rt_sigreturn: mov $30,$17 @@ -699,6 +700,7 @@ sys_rt_sigreturn: .end sys_rt_sigreturn .align 3 +.globl sys_sigsuspend .ent sys_sigsuspend sys_sigsuspend: mov $30,$17 @@ -713,6 +715,7 @@ sys_sigsuspend: .end sys_sigsuspend .align 3 +.globl sys_rt_sigsuspend .ent sys_rt_sigsuspend sys_rt_sigsuspend: mov $30,$18 @@ -725,421 +728,3 @@ sys_rt_sigsuspend: lda $30,SWITCH_STACK_SIZE+16($30) ret $31,($26),1 .end sys_rt_sigsuspend - - .data - .align 3 - .globl sys_call_table -sys_call_table: - .quad alpha_ni_syscall /* 0 */ - .quad sys_exit - .quad sys_fork - .quad sys_read - .quad sys_write - .quad alpha_ni_syscall /* 5 */ - .quad sys_close - .quad osf_wait4 - .quad alpha_ni_syscall - .quad sys_link - .quad sys_unlink /* 10 */ - .quad alpha_ni_syscall - .quad sys_chdir - .quad sys_fchdir - .quad sys_mknod - .quad sys_chmod /* 15 */ - .quad sys_chown - .quad osf_brk - .quad alpha_ni_syscall - .quad sys_lseek - .quad sys_getxpid /* 20 */ - .quad osf_mount - .quad sys_umount - .quad sys_setuid - .quad sys_getxuid - .quad alpha_ni_syscall /* 25 */ - .quad sys_ptrace - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 30 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad sys_access - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 35 */ - .quad sys_sync - .quad sys_kill - .quad alpha_ni_syscall - .quad sys_setpgid - .quad alpha_ni_syscall /* 40 */ - .quad sys_dup - .quad sys_pipe - .quad osf_set_program_attributes - .quad alpha_ni_syscall - .quad sys_open /* 45 */ - .quad alpha_ni_syscall - .quad sys_getxgid - .quad osf_sigprocmask - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 50 */ - .quad sys_acct - .quad sys_sigpending - .quad alpha_ni_syscall - .quad sys_ioctl - .quad alpha_ni_syscall /* 55 */ - .quad alpha_ni_syscall - .quad sys_symlink - .quad sys_readlink - .quad sys_execve - .quad sys_umask /* 60 */ - .quad sys_chroot - .quad alpha_ni_syscall - .quad sys_getpgrp - .quad sys_getpagesize - .quad alpha_ni_syscall /* 65 */ - .quad sys_vfork - .quad sys_newstat - .quad sys_newlstat - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 70 */ - .quad osf_mmap - .quad alpha_ni_syscall - .quad sys_munmap - .quad sys_mprotect - .quad sys_madvise /* 75 */ - .quad sys_vhangup - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad sys_getgroups - /* map BSD's setpgrp to sys_setpgid for binary compatibility: */ - .quad sys_setgroups /* 80 */ - .quad alpha_ni_syscall - .quad sys_setpgid - .quad osf_setitimer - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 85 */ - .quad osf_getitimer - .quad sys_gethostname - .quad sys_sethostname - .quad sys_getdtablesize - .quad sys_dup2 /* 90 */ - .quad sys_newfstat - .quad sys_fcntl - .quad osf_select - .quad sys_poll - .quad sys_fsync /* 95 */ - .quad sys_setpriority - .quad sys_socket - .quad sys_connect - .quad sys_accept - .quad osf_getpriority /* 100 */ - .quad sys_send - .quad sys_recv - .quad sys_sigreturn - .quad sys_bind - .quad sys_setsockopt /* 105 */ - .quad sys_listen - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 110 */ - .quad sys_sigsuspend - .quad osf_sigstack - .quad sys_recvmsg - .quad sys_sendmsg - .quad alpha_ni_syscall /* 115 */ - .quad osf_gettimeofday - .quad osf_getrusage - .quad sys_getsockopt - .quad alpha_ni_syscall -#ifdef CONFIG_OSF4_COMPAT - .quad osf_readv /* 120 */ - .quad osf_writev -#else - .quad sys_readv /* 120 */ - .quad sys_writev -#endif - .quad osf_settimeofday - .quad sys_fchown - .quad sys_fchmod - .quad sys_recvfrom /* 125 */ - .quad sys_setreuid - .quad sys_setregid - .quad sys_rename - .quad sys_truncate - .quad sys_ftruncate /* 130 */ - .quad sys_flock - .quad sys_setgid - .quad sys_sendto - .quad sys_shutdown - .quad sys_socketpair /* 135 */ - .quad sys_mkdir - .quad sys_rmdir - .quad osf_utimes - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 140 */ - .quad sys_getpeername - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad sys_getrlimit - .quad sys_setrlimit /* 145 */ - .quad alpha_ni_syscall - .quad sys_setsid - .quad sys_quotactl - .quad alpha_ni_syscall - .quad sys_getsockname /* 150 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 155 */ - .quad osf_sigaction - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad osf_getdirentries - .quad osf_statfs /* 160 */ - .quad osf_fstatfs - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad osf_getdomainname /* 165 */ - .quad sys_setdomainname - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 170 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 175 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 180 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 185 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 190 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 195 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad osf_swapon - .quad sys_msgctl /* 200 */ - .quad sys_msgget - .quad sys_msgrcv - .quad sys_msgsnd - .quad sys_semctl - .quad sys_semget /* 205 */ - .quad sys_semop - .quad osf_utsname - .quad sys_lchown - .quad osf_shmat - .quad sys_shmctl /* 210 */ - .quad sys_shmdt - .quad sys_shmget - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 215 */ - .quad alpha_ni_syscall - .quad sys_msync - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 220 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 225 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 230 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad sys_getpgid - .quad sys_getsid - .quad sys_sigaltstack /* 235 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 240 */ - .quad osf_sysinfo - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad osf_proplist_syscall - .quad alpha_ni_syscall /* 245 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 250 */ - .quad osf_usleep_thread - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad sys_sysfs - .quad alpha_ni_syscall /* 255 */ - .quad osf_getsysinfo - .quad osf_setsysinfo - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 260 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 265 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 270 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 275 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 280 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 285 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 290 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall /* 295 */ - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall - .quad alpha_ni_syscall -/* linux-specific system calls start at 300 */ - .quad sys_bdflush /* 300 */ - .quad sys_sethae - .quad sys_mount - .quad sys_old_adjtimex - .quad sys_swapoff - .quad sys_getdents /* 305 */ - .quad alpha_create_module - .quad sys_init_module - .quad sys_delete_module - .quad sys_get_kernel_syms - .quad sys_syslog /* 310 */ - .quad sys_reboot - .quad sys_clone - .quad sys_uselib - .quad sys_mlock - .quad sys_munlock /* 315 */ - .quad sys_mlockall - .quad sys_munlockall - .quad sys_sysinfo - .quad sys_sysctl - .quad sys_ni_syscall /* 320 */ - .quad sys_oldumount - .quad sys_swapon - .quad sys_times - .quad sys_personality - .quad sys_setfsuid /* 325 */ - .quad sys_setfsgid - .quad sys_ustat - .quad sys_statfs - .quad sys_fstatfs - .quad sys_sched_setparam /* 330 */ - .quad sys_sched_getparam - .quad sys_sched_setscheduler - .quad sys_sched_getscheduler - .quad sys_sched_yield - .quad sys_sched_get_priority_max /* 335 */ - .quad sys_sched_get_priority_min - .quad sys_sched_rr_get_interval - .quad sys_ni_syscall /* sys_afs_syscall */ - .quad sys_newuname - .quad sys_nanosleep /* 340 */ - .quad sys_mremap - .quad sys_nfsservctl - .quad sys_setresuid - .quad sys_getresuid - .quad sys_pciconfig_read /* 345 */ - .quad sys_pciconfig_write - .quad sys_query_module - .quad sys_prctl - .quad sys_pread64 - .quad sys_pwrite64 /* 350 */ - .quad sys_rt_sigreturn - .quad sys_rt_sigaction - .quad sys_rt_sigprocmask - .quad sys_rt_sigpending - .quad sys_rt_sigtimedwait /* 355 */ - .quad sys_rt_sigqueueinfo - .quad sys_rt_sigsuspend - .quad sys_select - .quad sys_gettimeofday - .quad sys_settimeofday /* 360 */ - .quad sys_getitimer - .quad sys_setitimer - .quad sys_utimes - .quad sys_getrusage - .quad sys_wait4 /* 365 */ - .quad sys_adjtimex - .quad sys_getcwd - .quad sys_capget - .quad sys_capset - .quad sys_sendfile /* 370 */ - .quad sys_setresgid - .quad sys_getresgid - .quad sys_ni_syscall /* sys_dipc */ - .quad sys_pivot_root - .quad sys_mincore /* 375 */ - .quad sys_pciconfig_iobase - .quad sys_getdents64 - .quad sys_gettid - .quad sys_readahead - .quad sys_ni_syscall /* 380, sys_security */ - .quad sys_tkill - .quad sys_setxattr - .quad sys_lsetxattr - .quad sys_fsetxattr - .quad sys_getxattr - .quad sys_lgetxattr - .quad sys_fgetxattr - .quad sys_listxattr - .quad sys_llistxattr - .quad sys_flistxattr /* 390 */ - .quad sys_removexattr - .quad sys_lremovexattr - .quad sys_fremovexattr - .quad sys_futex - .quad sys_sched_setaffinity - .quad sys_sched_getaffinity - .quad sys_ni_syscall /* 397, tux */ - .quad sys_io_setup - .quad sys_io_destroy - .quad sys_io_getevents /* 400 */ - .quad sys_io_submit - .quad sys_io_cancel - .quad sys_ni_syscall /* 403, sys_alloc_hugepages */ - .quad sys_ni_syscall /* 404, sys_free_hugepages */ - .quad sys_exit_group diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 0e66b34b1d80..1ba5f94035c2 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -44,8 +44,9 @@ #include <asm/processor.h> extern int do_pipe(int *); - extern asmlinkage unsigned long sys_brk(unsigned long); +extern int sys_getpriority(int, int); +extern asmlinkage unsigned long sys_create_module(char *, unsigned long); /* * Brk needs to return an error. Still support Linux's brk(0) query idiom, @@ -53,7 +54,8 @@ extern asmlinkage unsigned long sys_brk(unsigned long); * identical to OSF as we don't return 0 on success, but doing otherwise * would require changes to libc. Hopefully this is good enough. */ -asmlinkage unsigned long osf_brk(unsigned long brk) +asmlinkage unsigned long +osf_brk(unsigned long brk) { unsigned long retval = sys_brk(brk); if (brk && brk != retval) @@ -64,9 +66,9 @@ asmlinkage unsigned long osf_brk(unsigned long brk) /* * This is pure guess-work.. */ -asmlinkage int osf_set_program_attributes( - unsigned long text_start, unsigned long text_len, - unsigned long bss_start, unsigned long bss_len) +asmlinkage int +osf_set_program_attributes(unsigned long text_start, unsigned long text_len, + unsigned long bss_start, unsigned long bss_len) { struct mm_struct *mm; @@ -106,8 +108,9 @@ struct osf_dirent_callback { int error; }; -static int osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, - ino_t ino, unsigned int d_type) +static int +osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, + ino_t ino, unsigned int d_type) { struct osf_dirent *dirent; struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; @@ -134,8 +137,9 @@ static int osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, return 0; } -asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, - unsigned int count, long *basep) +asmlinkage int +osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, + unsigned int count, long *basep) { int error; struct file *file; @@ -159,9 +163,9 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, if (count != buf.count) error = count - buf.count; -out_putf: + out_putf: fput(file); -out: + out: return error; } @@ -172,8 +176,9 @@ out: * Alpha syscall convention has no problem returning negative * values: */ -asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4, - int a5, struct pt_regs regs) +asmlinkage int +osf_getpriority(int which, int who, + int a2, int a3, int a4, int a5, struct pt_regs regs) { extern int sys_getpriority(int, int); int prio; @@ -194,24 +199,24 @@ asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4, /* * No need to acquire the kernel lock, we're local.. */ -asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, - int a5, struct pt_regs regs) +asmlinkage unsigned long +sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) { struct task_struct * tsk = current; (®s)->r20 = tsk->euid; return tsk->uid; } -asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, - int a5, struct pt_regs regs) +asmlinkage unsigned long +sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) { struct task_struct * tsk = current; (®s)->r20 = tsk->egid; return tsk->gid; } -asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, - int a5, struct pt_regs regs) +asmlinkage unsigned long +sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) { struct task_struct *tsk = current; @@ -226,9 +231,9 @@ asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, return tsk->tgid; } -asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, unsigned long fd, - unsigned long off) +asmlinkage unsigned long +osf_mmap(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long off) { struct file *file = NULL; unsigned long ret = -EBADF; @@ -249,7 +254,7 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len, up_write(¤t->mm->mmap_sem); if (file) fput(file); -out: + out: return ret; } @@ -271,7 +276,9 @@ struct osf_statfs { __kernel_fsid_t f_fsid; } *osf_stat; -static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz) +static int +linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, + unsigned long bufsiz) { struct osf_statfs tmp_stat; @@ -291,7 +298,9 @@ static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0; } -static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsigned long bufsiz) +static int +do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, + unsigned long bufsiz) { struct statfs linux_stat; int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat); @@ -300,7 +309,8 @@ static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsi return error; } -asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz) +asmlinkage int +osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz) { struct nameidata nd; int retval; @@ -313,7 +323,8 @@ asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long b return retval; } -asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz) +asmlinkage int +osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz) { struct file *file; int retval; @@ -342,10 +353,9 @@ struct cdfs_args { char *devname; int flags; uid_t exroot; -/* - * This has lots more here, which Linux handles with the option block - * but I'm too lazy to do the translation into ASCII. - */ + + /* This has lots more here, which Linux handles with the option block + but I'm too lazy to do the translation into ASCII. */ }; struct procfs_args { @@ -362,7 +372,8 @@ struct procfs_args { * Just how long ago was it written? OTOH our UFS driver may be still * unhappy with OSF UFS. [CHECKME] */ -static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags) +static int +osf_ufs_mount(char *dirname, struct ufs_args *args, int flags) { int retval; struct cdfs_args tmp; @@ -377,11 +388,12 @@ static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags) goto out; retval = do_mount(devname, dirname, "ext2", flags, NULL); putname(devname); -out: + out: return retval; } -static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags) +static int +osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags) { int retval; struct cdfs_args tmp; @@ -396,11 +408,12 @@ static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags) goto out; retval = do_mount(devname, dirname, "iso9660", flags, NULL); putname(devname); -out: + out: return retval; } -static int osf_procfs_mount(char *dirname, struct procfs_args *args, int flags) +static int +osf_procfs_mount(char *dirname, struct procfs_args *args, int flags) { struct procfs_args tmp; @@ -410,7 +423,8 @@ static int osf_procfs_mount(char *dirname, struct procfs_args *args, int flags) return do_mount("", dirname, "proc", flags, NULL); } -asmlinkage int osf_mount(unsigned long typenr, char *path, int flag, void *data) +asmlinkage int +osf_mount(unsigned long typenr, char *path, int flag, void *data) { int retval = -EINVAL; char *name; @@ -435,12 +449,13 @@ asmlinkage int osf_mount(unsigned long typenr, char *path, int flag, void *data) printk("osf_mount(%ld, %x)\n", typenr, flag); } putname(name); -out: + out: unlock_kernel(); return retval; } -asmlinkage int osf_utsname(char *name) +asmlinkage int +osf_utsname(char *name) { int error; @@ -458,12 +473,13 @@ asmlinkage int osf_utsname(char *name) goto out; error = 0; -out: + out: up_read(&uts_sem); return error; } -asmlinkage int osf_swapon(const char *path, int flags, int lowat, int hiwat) +asmlinkage int +osf_swapon(const char *path, int flags, int lowat, int hiwat) { int ret; @@ -474,35 +490,36 @@ asmlinkage int osf_swapon(const char *path, int flags, int lowat, int hiwat) return ret; } -asmlinkage unsigned long sys_getpagesize(void) +asmlinkage unsigned long +sys_getpagesize(void) { return PAGE_SIZE; } -asmlinkage unsigned long sys_getdtablesize(void) +asmlinkage unsigned long +sys_getdtablesize(void) { return NR_OPEN; } -asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5, - struct pt_regs regs) +asmlinkage int +sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs) { - int fd[2]; - int error; + int fd[2], error; error = do_pipe(fd); - if (error) - goto out; - (®s)->r20 = fd[1]; - error = fd[0]; -out: + if (!error) { + regs.r20 = fd[1]; + error = fd[0]; + } return error; } /* * For compatibility with OSF/1 only. Use utsname(2) instead. */ -asmlinkage int osf_getdomainname(char *name, int namelen) +asmlinkage int +osf_getdomainname(char *name, int namelen) { unsigned len; int i, error; @@ -522,12 +539,12 @@ asmlinkage int osf_getdomainname(char *name, int namelen) break; } up_read(&uts_sem); -out: + out: return error; } - -asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg) +asmlinkage long +osf_shmat(int shmid, void *shmaddr, int shmflg) { unsigned long raddr; long err; @@ -541,7 +558,7 @@ asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg) * non-negative longs! */ err = raddr; -out: + out: unlock_kernel(); return err; } @@ -612,7 +629,8 @@ enum pl_code { PL_DEL = 5, PL_FDEL = 6 }; -asmlinkage long osf_proplist_syscall(enum pl_code code, union pl_args *args) +asmlinkage long +osf_proplist_syscall(enum pl_code code, union pl_args *args) { long error; int *min_buf_size_ptr; @@ -655,7 +673,8 @@ asmlinkage long osf_proplist_syscall(enum pl_code code, union pl_args *args) return error; } -asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss) +asmlinkage int +osf_sigstack(struct sigstack *uss, struct sigstack *uoss) { unsigned long usp = rdusp(); unsigned long oss_sp = current->sas_ss_sp + current->sas_ss_size; @@ -691,7 +710,7 @@ asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss) } error = 0; -out: + out: return error; } @@ -702,32 +721,28 @@ out: * create_module() because it's one of the few system calls * that return kernel addresses (which are negative). */ -asmlinkage unsigned long alpha_create_module(char *module_name, unsigned long size, - int a3, int a4, int a5, int a6, - struct pt_regs regs) + +asmlinkage unsigned long +alpha_create_module(char *module_name, unsigned long size, + int a3, int a4, int a5, int a6, struct pt_regs regs) { - asmlinkage unsigned long sys_create_module(char *, unsigned long); long retval; lock_kernel(); retval = sys_create_module(module_name, size); - /* - * we get either a module address or an error number, - * and we know the error number is a small negative - * number, while the address is always negative but - * much larger. - */ - if (retval + 1000 > 0) - goto out; - /* tell entry.S:syscall_error that this is NOT an error: */ - regs.r0 = 0; -out: - unlock_kernel(); + /* We get either a module address or an error number, and we know + the error number is a small negative number, while the address + is always negative but much larger. */ + if (retval + 1000 < 0) + regs.r0 = 0; + + unlock_kernel(); return retval; } -asmlinkage long osf_sysinfo(int command, char *buf, long count) +asmlinkage long +osf_sysinfo(int command, char *buf, long count) { static char * sysinfo_table[] = { system_utsname.sysname, @@ -761,13 +776,13 @@ asmlinkage long osf_sysinfo(int command, char *buf, long count) else err = 0; up_read(&uts_sem); -out: + out: return err; } -asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, - unsigned long nbytes, - int *start, void *arg) +asmlinkage unsigned long +osf_getsysinfo(unsigned long op, void *buffer, unsigned long nbytes, + int *start, void *arg) { unsigned long w; struct percpu_struct *cpu; @@ -823,9 +838,9 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, return -EOPNOTSUPP; } -asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, - unsigned long nbytes, - int *start, void *arg) +asmlinkage unsigned long +osf_setsysinfo(unsigned long op, void *buffer, unsigned long nbytes, + int *start, void *arg) { switch (op) { case SSI_IEEE_FP_CONTROL: { @@ -925,21 +940,24 @@ struct itimerval32 struct timeval32 it_value; }; -static inline long get_tv32(struct timeval *o, struct timeval32 *i) +static inline long +get_tv32(struct timeval *o, struct timeval32 *i) { return (!access_ok(VERIFY_READ, i, sizeof(*i)) || (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec))); } -static inline long put_tv32(struct timeval32 *o, struct timeval *i) +static inline long +put_tv32(struct timeval32 *o, struct timeval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec))); } -static inline long get_it32(struct itimerval *o, struct itimerval32 *i) +static inline long +get_it32(struct itimerval *o, struct itimerval32 *i) { return (!access_ok(VERIFY_READ, i, sizeof(*i)) || (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) | @@ -948,7 +966,8 @@ static inline long get_it32(struct itimerval *o, struct itimerval32 *i) __get_user(o->it_value.tv_usec, &i->it_value.tv_usec))); } -static inline long put_it32(struct itimerval32 *o, struct itimerval *i) +static inline long +put_it32(struct itimerval32 *o, struct itimerval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) | @@ -964,7 +983,8 @@ jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value) value->tv_sec = jiffies / HZ; } -asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz) +asmlinkage int +osf_gettimeofday(struct timeval32 *tv, struct timezone *tz) { if (tv) { struct timeval ktv; @@ -979,7 +999,8 @@ asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz) return 0; } -asmlinkage int osf_settimeofday(struct timeval32 *tv, struct timezone *tz) +asmlinkage int +osf_settimeofday(struct timeval32 *tv, struct timezone *tz) { struct timeval ktv; struct timezone ktz; @@ -996,7 +1017,8 @@ asmlinkage int osf_settimeofday(struct timeval32 *tv, struct timezone *tz) return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL); } -asmlinkage int osf_getitimer(int which, struct itimerval32 *it) +asmlinkage int +osf_getitimer(int which, struct itimerval32 *it) { struct itimerval kit; int error; @@ -1008,8 +1030,8 @@ asmlinkage int osf_getitimer(int which, struct itimerval32 *it) return error; } -asmlinkage int osf_setitimer(int which, struct itimerval32 *in, - struct itimerval32 *out) +asmlinkage int +osf_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out) { struct itimerval kin, kout; int error; @@ -1031,7 +1053,8 @@ asmlinkage int osf_setitimer(int which, struct itimerval32 *in, } -asmlinkage int osf_utimes(const char *filename, struct timeval32 *tvs) +asmlinkage int +osf_utimes(const char *filename, struct timeval32 *tvs) { char *kfilename; struct timeval ktvs[2]; @@ -1136,9 +1159,9 @@ osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, set_fd_set(n, outp->fds_bits, fds.res_out); set_fd_set(n, exp->fds_bits, fds.res_ex); -out: + out: kfree(bits); -out_nofds: + out_nofds: return ret; } @@ -1161,7 +1184,8 @@ struct rusage32 { long ru_nivcsw; /* involuntary " */ }; -asmlinkage int osf_getrusage(int who, struct rusage32 *ru) +asmlinkage int +osf_getrusage(int who, struct rusage32 *ru) { struct rusage32 r; @@ -1198,8 +1222,8 @@ asmlinkage int osf_getrusage(int who, struct rusage32 *ru) return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; } -asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options, - struct rusage32 *ur) +asmlinkage int +osf_wait4(pid_t pid, int *ustatus, int options, struct rusage32 *ur) { if (!ur) { return sys_wait4(pid, ustatus, options, NULL); @@ -1245,7 +1269,8 @@ asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options, * seems to be a timeval pointer, and I suspect the second * one is the time remaining.. Ho humm.. No documentation. */ -asmlinkage int osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *remain) +asmlinkage int +osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *remain) { struct timeval tmp; unsigned long ticks; @@ -1268,7 +1293,7 @@ asmlinkage int osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *rema } return 0; -fault: + fault: return -EFAULT; } @@ -1302,7 +1327,8 @@ struct timex32 { int :32; int :32; int :32; int :32; }; -asmlinkage int sys_old_adjtimex(struct timex32 *txc_p) +asmlinkage int +sys_old_adjtimex(struct timex32 *txc_p) { struct timex txc; int ret; diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index b0cd16ef9493..e3a608e79a6b 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -191,26 +191,13 @@ machine_power_off(void) common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL); } +/* Used by sysrq-p, among others. I don't believe r9-r15 are ever + saved in the context it's used. */ + void -show_regs(struct pt_regs * regs) +show_regs(struct pt_regs *regs) { - printk("\n"); - printk("Pid: %d, comm: %20s\n", current->pid, current->comm); - printk("ps: %04lx pc: [<%016lx>] CPU %d %s\n", - regs->ps, regs->pc, smp_processor_id(), print_tainted()); - printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1); - printk(" r0: %016lx r1: %016lx r2: %016lx r3: %016lx\n", - regs->r0, regs->r1, regs->r2, regs->r3); - printk(" r4: %016lx r5: %016lx r6: %016lx r7: %016lx\n", - regs->r4, regs->r5, regs->r6, regs->r7); - printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lx\n", - regs->r8, regs->r16, regs->r17, regs->r18); - printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lx\n", - regs->r19, regs->r20, regs->r21, regs->r22); - printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lx\n", - regs->r23, regs->r24, regs->r25, regs->r26); - printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lx\n", - regs->r27, regs->r28, regs->gp, regs->hae); + dik_show_regs(regs, 0); } /* diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 42517ea1254d..bec5ea08989f 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -37,6 +37,11 @@ #include <linux/blk.h> #endif +#ifdef CONFIG_MAGIC_SYSRQ +#include <linux/sysrq.h> +#include <linux/reboot.h> +#endif + #include <linux/notifier.h> extern struct notifier_block *panic_notifier_list; static int alpha_panic_event(struct notifier_block *, unsigned long, void *); @@ -539,6 +544,15 @@ setup_arch(char **cmdline_p) register_srm_console(); } +#ifdef CONFIG_MAGIC_SYSRQ + /* If we're using SRM, make sysrq-b halt back to the prom, + not auto-reboot. */ + if (alpha_using_srm) { + struct sysrq_key_op *op = __sysrq_get_key_op('b'); + op->handler = (void *) machine_halt; + } +#endif + /* * Indentify and reconfigure for the current system. */ diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S new file mode 100644 index 000000000000..59a91186ace6 --- /dev/null +++ b/arch/alpha/kernel/systbls.S @@ -0,0 +1,433 @@ +/* + * arch/alpha/kernel/systbls.S + * + * The system call table. + */ + +#include <asm/unistd.h> + + .data + .align 3 + .globl sys_call_table +sys_call_table: + .quad alpha_ni_syscall /* 0 */ + .quad sys_exit + .quad sys_fork + .quad sys_read + .quad sys_write + .quad alpha_ni_syscall /* 5 */ + .quad sys_close + .quad osf_wait4 + .quad alpha_ni_syscall + .quad sys_link + .quad sys_unlink /* 10 */ + .quad alpha_ni_syscall + .quad sys_chdir + .quad sys_fchdir + .quad sys_mknod + .quad sys_chmod /* 15 */ + .quad sys_chown + .quad osf_brk + .quad alpha_ni_syscall + .quad sys_lseek + .quad sys_getxpid /* 20 */ + .quad osf_mount + .quad sys_umount + .quad sys_setuid + .quad sys_getxuid + .quad alpha_ni_syscall /* 25 */ + .quad sys_ptrace + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 30 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_access + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 35 */ + .quad sys_sync + .quad sys_kill + .quad alpha_ni_syscall + .quad sys_setpgid + .quad alpha_ni_syscall /* 40 */ + .quad sys_dup + .quad sys_pipe + .quad osf_set_program_attributes + .quad alpha_ni_syscall + .quad sys_open /* 45 */ + .quad alpha_ni_syscall + .quad sys_getxgid + .quad osf_sigprocmask + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 50 */ + .quad sys_acct + .quad sys_sigpending + .quad alpha_ni_syscall + .quad sys_ioctl + .quad alpha_ni_syscall /* 55 */ + .quad alpha_ni_syscall + .quad sys_symlink + .quad sys_readlink + .quad sys_execve + .quad sys_umask /* 60 */ + .quad sys_chroot + .quad alpha_ni_syscall + .quad sys_getpgrp + .quad sys_getpagesize + .quad alpha_ni_syscall /* 65 */ + .quad sys_vfork + .quad sys_newstat + .quad sys_newlstat + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 70 */ + .quad osf_mmap + .quad alpha_ni_syscall + .quad sys_munmap + .quad sys_mprotect + .quad sys_madvise /* 75 */ + .quad sys_vhangup + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_getgroups + /* map BSD's setpgrp to sys_setpgid for binary compatibility: */ + .quad sys_setgroups /* 80 */ + .quad alpha_ni_syscall + .quad sys_setpgid + .quad osf_setitimer + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 85 */ + .quad osf_getitimer + .quad sys_gethostname + .quad sys_sethostname + .quad sys_getdtablesize + .quad sys_dup2 /* 90 */ + .quad sys_newfstat + .quad sys_fcntl + .quad osf_select + .quad sys_poll + .quad sys_fsync /* 95 */ + .quad sys_setpriority + .quad sys_socket + .quad sys_connect + .quad sys_accept + .quad osf_getpriority /* 100 */ + .quad sys_send + .quad sys_recv + .quad sys_sigreturn + .quad sys_bind + .quad sys_setsockopt /* 105 */ + .quad sys_listen + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 110 */ + .quad sys_sigsuspend + .quad osf_sigstack + .quad sys_recvmsg + .quad sys_sendmsg + .quad alpha_ni_syscall /* 115 */ + .quad osf_gettimeofday + .quad osf_getrusage + .quad sys_getsockopt + .quad alpha_ni_syscall +#ifdef CONFIG_OSF4_COMPAT + .quad osf_readv /* 120 */ + .quad osf_writev +#else + .quad sys_readv /* 120 */ + .quad sys_writev +#endif + .quad osf_settimeofday + .quad sys_fchown + .quad sys_fchmod + .quad sys_recvfrom /* 125 */ + .quad sys_setreuid + .quad sys_setregid + .quad sys_rename + .quad sys_truncate + .quad sys_ftruncate /* 130 */ + .quad sys_flock + .quad sys_setgid + .quad sys_sendto + .quad sys_shutdown + .quad sys_socketpair /* 135 */ + .quad sys_mkdir + .quad sys_rmdir + .quad osf_utimes + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 140 */ + .quad sys_getpeername + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_getrlimit + .quad sys_setrlimit /* 145 */ + .quad alpha_ni_syscall + .quad sys_setsid + .quad sys_quotactl + .quad alpha_ni_syscall + .quad sys_getsockname /* 150 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 155 */ + .quad osf_sigaction + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad osf_getdirentries + .quad osf_statfs /* 160 */ + .quad osf_fstatfs + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad osf_getdomainname /* 165 */ + .quad sys_setdomainname + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 170 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 175 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 180 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 185 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 190 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 195 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad osf_swapon + .quad sys_msgctl /* 200 */ + .quad sys_msgget + .quad sys_msgrcv + .quad sys_msgsnd + .quad sys_semctl + .quad sys_semget /* 205 */ + .quad sys_semop + .quad osf_utsname + .quad sys_lchown + .quad osf_shmat + .quad sys_shmctl /* 210 */ + .quad sys_shmdt + .quad sys_shmget + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 215 */ + .quad alpha_ni_syscall + .quad sys_msync + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 220 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 225 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 230 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_getpgid + .quad sys_getsid + .quad sys_sigaltstack /* 235 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 240 */ + .quad osf_sysinfo + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad osf_proplist_syscall + .quad alpha_ni_syscall /* 245 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 250 */ + .quad osf_usleep_thread + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_sysfs + .quad alpha_ni_syscall /* 255 */ + .quad osf_getsysinfo + .quad osf_setsysinfo + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 260 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 265 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 270 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 275 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 280 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 285 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 290 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 295 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall +/* linux-specific system calls start at 300 */ + .quad sys_bdflush /* 300 */ + .quad sys_sethae + .quad sys_mount + .quad sys_old_adjtimex + .quad sys_swapoff + .quad sys_getdents /* 305 */ + .quad alpha_create_module + .quad sys_init_module + .quad sys_delete_module + .quad sys_get_kernel_syms + .quad sys_syslog /* 310 */ + .quad sys_reboot + .quad sys_clone + .quad sys_uselib + .quad sys_mlock + .quad sys_munlock /* 315 */ + .quad sys_mlockall + .quad sys_munlockall + .quad sys_sysinfo + .quad sys_sysctl + .quad sys_ni_syscall /* 320 */ + .quad sys_oldumount + .quad sys_swapon + .quad sys_times + .quad sys_personality + .quad sys_setfsuid /* 325 */ + .quad sys_setfsgid + .quad sys_ustat + .quad sys_statfs + .quad sys_fstatfs + .quad sys_sched_setparam /* 330 */ + .quad sys_sched_getparam + .quad sys_sched_setscheduler + .quad sys_sched_getscheduler + .quad sys_sched_yield + .quad sys_sched_get_priority_max /* 335 */ + .quad sys_sched_get_priority_min + .quad sys_sched_rr_get_interval + .quad sys_ni_syscall /* sys_afs_syscall */ + .quad sys_newuname + .quad sys_nanosleep /* 340 */ + .quad sys_mremap + .quad sys_nfsservctl + .quad sys_setresuid + .quad sys_getresuid + .quad sys_pciconfig_read /* 345 */ + .quad sys_pciconfig_write + .quad sys_query_module + .quad sys_prctl + .quad sys_pread64 + .quad sys_pwrite64 /* 350 */ + .quad sys_rt_sigreturn + .quad sys_rt_sigaction + .quad sys_rt_sigprocmask + .quad sys_rt_sigpending + .quad sys_rt_sigtimedwait /* 355 */ + .quad sys_rt_sigqueueinfo + .quad sys_rt_sigsuspend + .quad sys_select + .quad sys_gettimeofday + .quad sys_settimeofday /* 360 */ + .quad sys_getitimer + .quad sys_setitimer + .quad sys_utimes + .quad sys_getrusage + .quad sys_wait4 /* 365 */ + .quad sys_adjtimex + .quad sys_getcwd + .quad sys_capget + .quad sys_capset + .quad sys_sendfile /* 370 */ + .quad sys_setresgid + .quad sys_getresgid + .quad sys_ni_syscall /* sys_dipc */ + .quad sys_pivot_root + .quad sys_mincore /* 375 */ + .quad sys_pciconfig_iobase + .quad sys_getdents64 + .quad sys_gettid + .quad sys_readahead + .quad sys_ni_syscall /* 380, sys_security */ + .quad sys_tkill + .quad sys_setxattr + .quad sys_lsetxattr + .quad sys_fsetxattr + .quad sys_getxattr /* 385 */ + .quad sys_lgetxattr + .quad sys_fgetxattr + .quad sys_listxattr + .quad sys_llistxattr + .quad sys_flistxattr /* 390 */ + .quad sys_removexattr + .quad sys_lremovexattr + .quad sys_fremovexattr + .quad sys_futex + .quad sys_sched_setaffinity /* 395 */ + .quad sys_sched_getaffinity + .quad sys_ni_syscall /* 397, tux */ + .quad sys_io_setup + .quad sys_io_destroy + .quad sys_io_getevents /* 400 */ + .quad sys_io_submit + .quad sys_io_cancel + .quad sys_ni_syscall /* 403, sys_alloc_hugepages */ + .quad sys_ni_syscall /* 404, sys_free_hugepages */ + .quad sys_exit_group + + .size sys_call_table, . - sys_call_table + .type sys_call_table, @object + +/* Remember to update everything, kids. */ +.ifne (. - sys_call_table) - (NR_SYSCALLS * 8) +.err +.endif diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index a18ea063c96a..f9192f135f7a 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -51,14 +51,16 @@ obj-$(CONFIG_SMP) += dec_and_lock.o include $(TOPDIR)/Rules.make -__divqu.o: $(ev6)divide.S - $(CC) $(AFLAGS) -DDIV -c -o __divqu.o $(ev6)divide.S +$(obj)/__divqu.o: $(obj)/$(ev6)divide.S + $(CC) $(AFLAGS) -DDIV -c -o $(obj)/__divqu.o $(obj)/$(ev6)divide.S -__remqu.o: $(ev6)divide.S - $(CC) $(AFLAGS) -DREM -c -o __remqu.o $(ev6)divide.S +$(obj)/__remqu.o: $(obj)/$(ev6)divide.S + $(CC) $(AFLAGS) -DREM -c -o $(obj)/__remqu.o $(obj)/$(ev6)divide.S -__divlu.o: $(ev6)divide.S - $(CC) $(AFLAGS) -DDIV -DINTSIZE -c -o __divlu.o $(ev6)divide.S +$(obj)/__divlu.o: $(obj)/$(ev6)divide.S + $(CC) $(AFLAGS) -DDIV -DINTSIZE \ + -c -o $(obj)/__divlu.o $(obj)/$(ev6)divide.S -__remlu.o: $(ev6)divide.S - $(CC) $(AFLAGS) -DREM -DINTSIZE -c -o __remlu.o $(ev6)divide.S +$(obj)/__remlu.o: $(obj)/$(ev6)divide.S + $(CC) $(AFLAGS) -DREM -DINTSIZE \ + -c -o $(obj)/__remlu.o $(obj)/$(ev6)divide.S diff --git a/arch/alpha/lib/stackcheck.S b/arch/alpha/lib/dbg_stackcheck.S index cc5ce3a5fcad..cc5ce3a5fcad 100644 --- a/arch/alpha/lib/stackcheck.S +++ b/arch/alpha/lib/dbg_stackcheck.S diff --git a/arch/alpha/lib/stackkill.S b/arch/alpha/lib/dbg_stackkill.S index e09f2ae1e09e..e09f2ae1e09e 100644 --- a/arch/alpha/lib/stackkill.S +++ b/arch/alpha/lib/dbg_stackkill.S diff --git a/arch/alpha/lib/stxncpy.S b/arch/alpha/lib/stxncpy.S index 0b5717f84412..9f0d16737cf0 100644 --- a/arch/alpha/lib/stxncpy.S +++ b/arch/alpha/lib/stxncpy.S @@ -278,7 +278,7 @@ $u_eoc: extqh t2, a1, t0 # e0 : extract low bits for last word or t1, t0, t1 # e1 : -1: cmpbge zero, t1, t7 +1: cmpbge zero, t1, t8 mov t1, t0 $u_eocfin: # end-of-count, final word diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index 77ca3cca1386..ea447440a1e6 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -125,11 +125,10 @@ do_page_fault(unsigned long address, unsigned long mmcsr, goto bad_area; if (expand_stack(vma, address)) goto bad_area; -/* - * Ok, we have a good vm_area for this memory access, so - * we can handle it.. - */ -good_area: + + /* Ok, we have a good vm_area for this memory access, so + we can handle it. */ + good_area: if (cause < 0) { if (!(vma->vm_flags & VM_EXEC)) goto bad_area; @@ -143,11 +142,9 @@ good_area: } survive: - /* - * If for any reason at all we couldn't handle the fault, - * make sure we exit gracefully rather than endlessly redo - * the fault. - */ + /* If for any reason at all we couldn't handle the fault, + make sure we exit gracefully rather than endlessly redo + the fault. */ fault = handle_mm_fault(mm, vma, address, cause > 0); up_read(&mm->mmap_sem); @@ -155,14 +152,11 @@ good_area: goto out_of_memory; if (fault == 0) goto do_sigbus; - return; -/* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. - */ -bad_area: + /* Something tried to access memory that isn't in our memory map. + Fix it, but check if it's kernel or user first. */ + bad_area: up_read(&mm->mmap_sem); if (user_mode(regs)) { @@ -170,7 +164,7 @@ bad_area: return; } -no_context: + no_context: /* Are we prepared to handle this fault as an exception? */ if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) { unsigned long newpc; @@ -183,20 +177,16 @@ no_context: return; } -/* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ + /* Oops. The kernel tried to access some bad page. We'll have to + terminate things with extreme prejudice. */ printk(KERN_ALERT "Unable to handle kernel paging request at " "virtual address %016lx\n", address); die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16); do_exit(SIGKILL); -/* - * We ran out of memory, or some other thing happened to us that made - * us unable to handle the page fault gracefully. - */ -out_of_memory: + /* We ran out of memory, or some other thing happened to us that + made us unable to handle the page fault gracefully. */ + out_of_memory: if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); @@ -208,18 +198,16 @@ out_of_memory: goto no_context; do_exit(SIGKILL); -do_sigbus: - /* - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ + do_sigbus: + /* Send a sigbus, regardless of whether we were in kernel + or user mode. */ force_sig(SIGBUS, current); if (!user_mode(regs)) goto no_context; return; #ifdef CONFIG_ALPHA_LARGE_VMALLOC -vmalloc_fault: + vmalloc_fault: if (user_mode(regs)) { force_sig(SIGSEGV, current); return; diff --git a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S index 852722876508..80e831700eda 100644 --- a/arch/alpha/vmlinux.lds.S +++ b/arch/alpha/vmlinux.lds.S @@ -58,10 +58,11 @@ SECTIONS __initcall_end = .; } - . = ALIGN(64); - __per_cpu_start = .; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = .; + .data.percpu ALIGN(64): { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } /* The initial task and kernel stack */ .data.init_thread ALIGN(2*8192) : { diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 419ef498c151..40bf53ac5c83 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1664,14 +1664,6 @@ static int idedisk_resume(struct device *dev, u32 level) /* This is just a hook for the overall driver tree. */ -static struct device_driver idedisk_devdrv = { - .bus = &ide_bus_type, - .name = "IDE disk driver", - - .suspend = idedisk_suspend, - .resume = idedisk_resume, -}; - static int idedisk_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -1717,12 +1709,6 @@ static void idedisk_setup (ide_drive_t *drive) drive->doorlocking = 1; } } - { - sprintf(drive->disk->disk_dev.name, "ide-disk"); - drive->disk->disk_dev.driver = &idedisk_devdrv; - drive->disk->disk_dev.driver_data = drive; - } - #if 1 (void) probe_lba_addressing(drive, 1); #else @@ -1806,7 +1792,6 @@ static int idedisk_cleanup (ide_drive_t *drive) { struct gendisk *g = drive->disk; - device_unregister(&drive->disk->disk_dev); if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) if (do_idedisk_flushcache(drive)) printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", @@ -1905,7 +1890,6 @@ static void __exit idedisk_exit (void) static int idedisk_init (void) { ide_register_driver(&idedisk_driver); - driver_register(&idedisk_devdrv); return 0; } diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9caa96e00518..6277ce3cb1e0 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -998,15 +998,6 @@ static void init_gendisk (ide_hwif_t *hwif) sprintf(disk->disk_name,"hd%c",'a'+hwif->index*MAX_DRIVES+unit); disk->minor_shift = PARTN_BITS; disk->fops = ide_fops; - - snprintf(disk->disk_dev.bus_id,BUS_ID_SIZE,"%u.%u", - hwif->index,unit); - snprintf(disk->disk_dev.name,DEVICE_NAME_SIZE, - "%s","IDE Drive"); - disk->disk_dev.parent = &hwif->gendev; - disk->disk_dev.bus = &ide_bus_type; - if (hwif->drives[unit].present) - device_register(&disk->disk_dev); hwif->drives[unit].disk = disk; } @@ -1020,6 +1011,20 @@ static void init_gendisk (ide_hwif_t *hwif) if (hwif->drives[unit].present) hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL); } + + for (unit = 0; unit < units; ++unit) { + ide_drive_t * drive = &hwif->drives[unit]; + + snprintf(drive->gendev.bus_id,BUS_ID_SIZE,"%u.%u", + hwif->index,unit); + snprintf(drive->gendev.name,DEVICE_NAME_SIZE, + "%s","IDE Drive"); + drive->gendev.parent = &hwif->gendev; + drive->gendev.bus = &ide_bus_type; + if (drive->present) + device_register(&drive->gendev); + } + return; err_kmalloc_gd: diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 13c58a36e550..e2380bcb9fe8 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -2463,6 +2463,7 @@ int ata_attach(ide_drive_t *drive) if (driver->attach(drive) == 0) { if (driver->owner) __MOD_DEC_USE_COUNT(driver->owner); + drive->gendev.driver = &driver->gen_driver; return 0; } spin_lock(&drivers_lock); @@ -3422,6 +3423,21 @@ int ide_unregister_subdriver (ide_drive_t *drive) EXPORT_SYMBOL(ide_unregister_subdriver); +static int ide_drive_remove(struct device * dev) +{ + ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); + ide_driver_t * driver = drive->driver; + + if (driver) { + if (driver->standby) + driver->standby(drive); + if (driver->cleanup) + driver->cleanup(drive); + } + + return 0; +} + int ide_register_driver(ide_driver_t *driver) { struct list_head list; @@ -3440,7 +3456,10 @@ int ide_register_driver(ide_driver_t *driver) list_del_init(&drive->list); ata_attach(drive); } - return 0; + driver->gen_driver.name = driver->name; + driver->gen_driver.bus = &ide_bus_type; + driver->gen_driver.remove = ide_drive_remove; + return driver_register(&driver->gen_driver); } EXPORT_SYMBOL(ide_register_driver); @@ -3491,52 +3510,6 @@ EXPORT_SYMBOL(ide_lock); EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(ide_devfs_handle); -static int ide_notify_reboot (struct notifier_block *this, unsigned long event, void *x) -{ - ide_hwif_t *hwif; - ide_drive_t *drive; - int i, unit; - - switch (event) { - case SYS_HALT: - case SYS_POWER_OFF: - case SYS_RESTART: - break; - default: - return NOTIFY_DONE; - } - - printk(KERN_INFO "flushing ide devices: "); - - for (i = 0; i < MAX_HWIFS; i++) { - hwif = &ide_hwifs[i]; - if (!hwif->present) - continue; - for (unit = 0; unit < MAX_DRIVES; ++unit) { - drive = &hwif->drives[unit]; - if (!drive->present) - continue; - - /* set the drive to standby */ - printk("%s ", drive->name); - if (event != SYS_RESTART) - if (drive->driver != NULL && DRIVER(drive)->standby(drive)) - continue; - - if (drive->driver != NULL && DRIVER(drive)->cleanup(drive)) - continue; - } - } - printk("\n"); - return NOTIFY_DONE; -} - -static struct notifier_block ide_notifier = { - ide_notify_reboot, - NULL, - 5 -}; - struct bus_type ide_bus_type = { .name = "ide", }; @@ -3562,7 +3535,6 @@ int __init ide_init (void) ide_init_builtin_drivers(); initializing = 0; - register_reboot_notifier(&ide_notifier); return 0; } @@ -3597,7 +3569,6 @@ void cleanup_module (void) { int index; - unregister_reboot_notifier(&ide_notifier); for (index = 0; index < MAX_HWIFS; ++index) { ide_unregister(index); #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index e97c7b8b155d..a407ee08d28a 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -11,12 +11,11 @@ Do not purchase this card, even as a joke. It's performance is horrible, and it breaks in many ways. - The author may be reached as becker@scyld.com, or C/O + The original author may be reached as becker@scyld.com, or C/O Scyld Computing Corporation 410 Severn Ave., Suite 210 Annapolis MD 21403 - Fixed (again!) the missing interrupt locking on TX/RX shifting. Alan Cox <Alan.Cox@linux.org> @@ -34,7 +33,16 @@ Cleaned up for 2.3.x because we broke SMP now. 20000208 Alan Cox <alan@redhat.com> + + Check up pass for 2.5. Nothing significant changed + 20021009 Alan Cox <alan@redhat.com> + For the avoidance of doubt the "preferred form" of this code is one which + is in an open non patent encumbered format. Where cryptographic key signing + forms part of the process of creating an executable the information + including keys needed to generate an equivalently functional executable + are deemed to be part of the source code. + */ @@ -88,7 +96,7 @@ */ #define DRV_NAME "3c501" -#define DRV_VERSION "2001/11/17" +#define DRV_VERSION "2002/10/09" static const char version[] = @@ -122,113 +130,21 @@ static const char version[] = #include <linux/skbuff.h> #include <linux/init.h> +#include "3c501.h" + /* A zero-terminated list of I/O addresses to be probed. The 3c501 can be at many locations, but here are the popular ones. */ static unsigned int netcard_portlist[] __initdata = { 0x280, 0x300, 0 }; - -/* - * Index to functions. - */ - -int el1_probe(struct net_device *dev); -static int el1_probe1(struct net_device *dev, int ioaddr); -static int el_open(struct net_device *dev); -static void el_timeout(struct net_device *dev); -static int el_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void el_receive(struct net_device *dev); -static void el_reset(struct net_device *dev); -static int el1_close(struct net_device *dev); -static struct net_device_stats *el1_get_stats(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); -static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); - -#define EL1_IO_EXTENT 16 - -#ifndef EL_DEBUG -#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */ -#endif /* Anything above 5 is wordy death! */ -#define debug el_debug -static int el_debug = EL_DEBUG; - -/* - * Board-specific info in dev->priv. - */ - -struct net_local -{ - struct net_device_stats stats; - int tx_pkt_start; /* The length of the current Tx packet. */ - int collisions; /* Tx collisions this packet */ - int loading; /* Spot buffer load collisions */ - int txing; /* True if card is in TX mode */ - spinlock_t lock; /* Serializing lock */ -}; - - -#define RX_STATUS (ioaddr + 0x06) -#define RX_CMD RX_STATUS -#define TX_STATUS (ioaddr + 0x07) -#define TX_CMD TX_STATUS -#define GP_LOW (ioaddr + 0x08) -#define GP_HIGH (ioaddr + 0x09) -#define RX_BUF_CLR (ioaddr + 0x0A) -#define RX_LOW (ioaddr + 0x0A) -#define RX_HIGH (ioaddr + 0x0B) -#define SAPROM (ioaddr + 0x0C) -#define AX_STATUS (ioaddr + 0x0E) -#define AX_CMD AX_STATUS -#define DATAPORT (ioaddr + 0x0F) -#define TX_RDY 0x08 /* In TX_STATUS */ - -#define EL1_DATAPTR 0x08 -#define EL1_RXPTR 0x0A -#define EL1_SAPROM 0x0C -#define EL1_DATAPORT 0x0f - -/* - * Writes to the ax command register. - */ - -#define AX_OFF 0x00 /* Irq off, buffer access on */ -#define AX_SYS 0x40 /* Load the buffer */ -#define AX_XMIT 0x44 /* Transmit a packet */ -#define AX_RX 0x48 /* Receive a packet */ -#define AX_LOOP 0x0C /* Loopback mode */ -#define AX_RESET 0x80 - -/* - * Normal receive mode written to RX_STATUS. We must intr on short packets - * to avoid bogus rx lockups. - */ - -#define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */ -#define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */ -#define RX_MULT 0xE8 /* Accept multicast packets. */ -#define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */ - -/* - * TX_STATUS register. - */ - -#define TX_COLLISION 0x02 -#define TX_16COLLISIONS 0x04 -#define TX_READY 0x08 - -#define RX_RUNT 0x08 -#define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */ -#define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */ - /* * The boilerplate probe code. */ /** - * el1_probe: + * el1_probe: - probe for a 3c501 * @dev: The device structure passed in to probe. * * This can be called from two places. The network layer will probe using @@ -556,7 +472,6 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) while(1); } - /** * el_interrupt: @@ -1072,12 +987,8 @@ void cleanup_module(void) } #endif /* MODULE */ + +MODULE_AUTHOR("Donald Becker, Alan Cox"); +MODULE_DESCRIPTION("Support for the ancient 3Com 3c501 ethernet card"); MODULE_LICENSE("GPL"); - -/* - * Local variables: - * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -m486 -c -o 3c501.o 3c501.c" - * kept-new-versions: 5 - * End: - */ diff --git a/drivers/net/3c501.h b/drivers/net/3c501.h new file mode 100644 index 000000000000..e0c8a846848c --- /dev/null +++ b/drivers/net/3c501.h @@ -0,0 +1,94 @@ + +/* + * Index to functions. + */ + +int el1_probe(struct net_device *dev); +static int el1_probe1(struct net_device *dev, int ioaddr); +static int el_open(struct net_device *dev); +static void el_timeout(struct net_device *dev); +static int el_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void el_receive(struct net_device *dev); +static void el_reset(struct net_device *dev); +static int el1_close(struct net_device *dev); +static struct net_device_stats *el1_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); + +#define EL1_IO_EXTENT 16 + +#ifndef EL_DEBUG +#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */ +#endif /* Anything above 5 is wordy death! */ +#define debug el_debug +static int el_debug = EL_DEBUG; + +/* + * Board-specific info in dev->priv. + */ + +struct net_local +{ + struct net_device_stats stats; + int tx_pkt_start; /* The length of the current Tx packet. */ + int collisions; /* Tx collisions this packet */ + int loading; /* Spot buffer load collisions */ + int txing; /* True if card is in TX mode */ + spinlock_t lock; /* Serializing lock */ +}; + + +#define RX_STATUS (ioaddr + 0x06) +#define RX_CMD RX_STATUS +#define TX_STATUS (ioaddr + 0x07) +#define TX_CMD TX_STATUS +#define GP_LOW (ioaddr + 0x08) +#define GP_HIGH (ioaddr + 0x09) +#define RX_BUF_CLR (ioaddr + 0x0A) +#define RX_LOW (ioaddr + 0x0A) +#define RX_HIGH (ioaddr + 0x0B) +#define SAPROM (ioaddr + 0x0C) +#define AX_STATUS (ioaddr + 0x0E) +#define AX_CMD AX_STATUS +#define DATAPORT (ioaddr + 0x0F) +#define TX_RDY 0x08 /* In TX_STATUS */ + +#define EL1_DATAPTR 0x08 +#define EL1_RXPTR 0x0A +#define EL1_SAPROM 0x0C +#define EL1_DATAPORT 0x0f + +/* + * Writes to the ax command register. + */ + +#define AX_OFF 0x00 /* Irq off, buffer access on */ +#define AX_SYS 0x40 /* Load the buffer */ +#define AX_XMIT 0x44 /* Transmit a packet */ +#define AX_RX 0x48 /* Receive a packet */ +#define AX_LOOP 0x0C /* Loopback mode */ +#define AX_RESET 0x80 + +/* + * Normal receive mode written to RX_STATUS. We must intr on short packets + * to avoid bogus rx lockups. + */ + +#define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */ +#define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */ +#define RX_MULT 0xE8 /* Accept multicast packets. */ +#define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */ + +/* + * TX_STATUS register. + */ + +#define TX_COLLISION 0x02 +#define TX_16COLLISIONS 0x04 +#define TX_READY 0x08 + +#define RX_RUNT 0x08 +#define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */ +#define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */ + diff --git a/drivers/scsi/cpqfcTSstructs.h b/drivers/scsi/cpqfcTSstructs.h index 62140c43a83a..e33152355945 100644 --- a/drivers/scsi/cpqfcTSstructs.h +++ b/drivers/scsi/cpqfcTSstructs.h @@ -21,7 +21,6 @@ #define CPQFCTSSTRUCTS_H #include <linux/timer.h> // timer declaration in our host data -#include <linux/tqueue.h> // task queue sched #include <asm/atomic.h> #include "cpqfcTSioctl.h" diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 6439539d2de2..781a5775aa28 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -317,13 +317,15 @@ uchar result; static void in2000_execute(struct Scsi_Host *instance); -int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { +struct Scsi_Host *instance; struct IN2000_hostdata *hostdata; Scsi_Cmnd *tmp; unsigned long flags; - hostdata = (struct IN2000_hostdata *)cmd->host->hostdata; + instance = cmd->host; + hostdata = (struct IN2000_hostdata *)instance->hostdata; DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid)) @@ -355,7 +357,7 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid)) if (cmd->use_sg) { cmd->SCp.buffer = (struct scatterlist *)cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; - cmd->SCp.ptr = (char *)cmd->SCp.buffer->address; + cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+cmd->SCp.buffer->offset; cmd->SCp.this_residual = cmd->SCp.buffer->length; } else { @@ -391,9 +393,7 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid)) * queue and calling in2000_execute(). */ - save_flags(flags); - cli(); - + spin_lock_irqsave(instance->host_lock, flags); /* * Add the cmd to the end of 'input_Q'. Note that REQUEST_SENSE * commands are added to the head of the queue so that the desired @@ -418,8 +418,7 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid)) in2000_execute(cmd->host); DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid)) - - restore_flags(flags); + spin_unlock_irqrestore(instance->host_lock, flags); return 0; } @@ -762,7 +761,7 @@ int i; ++cmd->SCp.buffer; --cmd->SCp.buffers_residual; cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = cmd->SCp.buffer->address; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; } /* Set up hardware registers */ @@ -855,7 +854,7 @@ unsigned long flags; /* Get the spin_lock and disable further ints, for SMP */ - CLISPIN_LOCK(instance, flags); + spin_lock_irqsave(instance->host_lock, flags); #ifdef PROC_STATISTICS hostdata->int_cnt++; @@ -993,7 +992,7 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT))) write1_io(0, IO_LED_OFF); /* release the SMP spin_lock and restore irq state */ - CLISPIN_UNLOCK(instance, flags); + spin_unlock_irqrestore(instance->host_lock, flags); return; } @@ -1011,7 +1010,7 @@ DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT))) write1_io(0, IO_LED_OFF); /* release the SMP spin_lock and restore irq state */ - CLISPIN_UNLOCK(instance, flags); + spin_unlock_irqrestore(instance->host_lock, flags); return; } @@ -1433,7 +1432,7 @@ DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0])) hostdata->state = S_UNCONNECTED; /* release the SMP spin_lock and restore irq state */ - CLISPIN_UNLOCK(instance, flags); + spin_unlock_irqrestore(instance->host_lock, flags); return; } DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid)) @@ -1609,7 +1608,7 @@ DB(DB_INTR,printk("-%ld",cmd->pid)) DB(DB_INTR,printk("} ")) /* release the SMP spin_lock and restore irq state */ - CLISPIN_UNLOCK(instance, flags); + spin_unlock_irqrestore(instance->host_lock, flags); } @@ -1619,11 +1618,14 @@ DB(DB_INTR,printk("} ")) #define RESET_CARD_AND_BUS 1 #define B_FLAG 0x80 +/* + * Caller must hold instance lock! + */ + static int reset_hardware(struct Scsi_Host *instance, int type) { struct IN2000_hostdata *hostdata; int qt,x; -unsigned long flags; hostdata = (struct IN2000_hostdata *)instance->hostdata; @@ -1638,16 +1640,16 @@ unsigned long flags; write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED); write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER, calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF)); - save_flags(flags); - cli(); + write1_io(0,IO_FIFO_WRITE); /* clear fifo counter */ write1_io(0,IO_FIFO_READ); /* start fifo out in read mode */ write_3393(hostdata,WD_COMMAND, WD_CMD_RESET); + /* FIXME: timeout ?? */ while (!(READ_AUX_STAT() & ASR_INT)) - ; /* wait for RESET to complete */ + cpu_relax(); /* wait for RESET to complete */ x = read_3393(hostdata,WD_SCSI_STATUS); /* clear interrupt */ - restore_flags(flags); + write_3393(hostdata,WD_QUEUE_TAG,0xa5); /* any random number */ qt = read_3393(hostdata,WD_QUEUE_TAG); if (qt == 0xa5) { @@ -1662,7 +1664,7 @@ unsigned long flags; -int in2000_reset(Scsi_Cmnd *cmd, unsigned int reset_flags) +static int in2000_bus_reset(Scsi_Cmnd *cmd) { unsigned long flags; struct Scsi_Host *instance; @@ -1672,10 +1674,9 @@ int x; instance = cmd->host; hostdata = (struct IN2000_hostdata *)instance->hostdata; - printk("scsi%d: Reset. ", instance->host_no); - save_flags(flags); - cli(); + printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no); + spin_lock_irqsave(instance->host_lock, flags); /* do scsi-reset here */ reset_hardware(instance, RESET_CARD_AND_BUS); @@ -1694,13 +1695,22 @@ int x; hostdata->outgoing_len = 0; cmd->result = DID_RESET << 16; - restore_flags(flags); - return 0; + spin_unlock_irqrestore(instance->host_lock, flags); + return SUCCESS; } +static int in2000_host_reset(Scsi_Cmnd *cmd) +{ + return FAILED; +} +static int in2000_device_reset(Scsi_Cmnd *cmd) +{ + return FAILED; +} -int in2000_abort (Scsi_Cmnd *cmd) + +static int in2000_abort (Scsi_Cmnd *cmd) { struct Scsi_Host *instance; struct IN2000_hostdata *hostdata; @@ -1709,13 +1719,10 @@ unsigned long flags; uchar sr, asr; unsigned long timeout; - save_flags (flags); - cli(); - instance = cmd->host; hostdata = (struct IN2000_hostdata *)instance->hostdata; - printk ("scsi%d: Abort-", instance->host_no); + printk(KERN_DEBUG "scsi%d: Abort-", instance->host_no); printk("(asr=%02x,count=%ld,resid=%d,buf_resid=%d,have_data=%d,FC=%02x)- ", READ_AUX_STAT(),read_3393_count(hostdata),cmd->SCp.this_residual,cmd->SCp.buffers_residual, cmd->SCp.have_data_in,read1_io(IO_FIFO_COUNT)); @@ -1725,6 +1732,7 @@ unsigned long timeout; * from the inout_Q. */ + spin_lock_irqsave(instance->host_lock, flags); tmp = (Scsi_Cmnd *)hostdata->input_Q; prev = 0; while (tmp) { @@ -1733,11 +1741,11 @@ unsigned long timeout; prev->host_scribble = cmd->host_scribble; cmd->host_scribble = NULL; cmd->result = DID_ABORT << 16; - printk("scsi%d: Abort - removing command %ld from input_Q. ", + printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->pid); cmd->scsi_done(cmd); - restore_flags(flags); - return SCSI_ABORT_SUCCESS; + spin_unlock_irqrestore(instance->host_lock, flags); + return SUCCESS; } prev = tmp; tmp = (Scsi_Cmnd *)tmp->host_scribble; @@ -1756,7 +1764,7 @@ unsigned long timeout; if (hostdata->connected == cmd) { - printk("scsi%d: Aborting connected command %ld - ", + printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->pid); printk("sending wd33c93 ABORT command - "); @@ -1800,7 +1808,6 @@ unsigned long timeout; in2000_execute (instance); - restore_flags(flags); return SCSI_ABORT_SUCCESS; } @@ -1813,9 +1820,9 @@ unsigned long timeout; for (tmp=(Scsi_Cmnd *)hostdata->disconnected_Q; tmp; tmp=(Scsi_Cmnd *)tmp->host_scribble) if (cmd == tmp) { - restore_flags(flags); - printk("Sending ABORT_SNOOZE. "); - return SCSI_ABORT_SNOOZE; + spin_unlock_irqrestore(instance->host_lock, flags); + printk(KERN_DEBUG "scsi%d: unable to abort disconnected command.\n", instance->host_no); + return FAILED; } /* @@ -1830,10 +1837,10 @@ unsigned long timeout; in2000_execute (instance); - restore_flags(flags); + spin_unlock_irqrestore(instance->host_lock, flags); printk("scsi%d: warning : SCSI command probably completed successfully" " before abortion. ", instance->host_no); - return SCSI_ABORT_NOT_RUNNING; + return SUCCESS; } @@ -1845,7 +1852,7 @@ static char setup_buffer[SETUP_BUFFER_SIZE]; static char setup_used[MAX_SETUP_ARGS]; static int done_setup = 0; -void __init in2000_setup (char *str, int *ints) +static void __init in2000_setup (char *str, int *ints) { int i; char *p1,*p2; @@ -1931,7 +1938,7 @@ static const int int_tab[] in2000__INITDATA = { }; -int __init in2000_detect(Scsi_Host_Template * tpnt) +static int __init in2000_detect(Scsi_Host_Template * tpnt) { struct Scsi_Host *instance; struct IN2000_hostdata *hostdata; @@ -2115,7 +2122,11 @@ char buf[32]; #endif + /* FIXME: not strictly needed I think but the called code expects + to be locked */ + spin_lock_irqsave(instance->host_lock, flags); x = reset_hardware(instance,(hostdata->args & A_NO_SCSI_RESET)?RESET_CARD:RESET_CARD_AND_BUS); + spin_unlock_irqrestore(instance->host_lock, flags); hostdata->microcode = read_3393(hostdata,WD_CDB_1); if (x & 0x01) { @@ -2158,7 +2169,7 @@ char buf[32]; * supposed to do... */ -int in2000_biosparam(Disk *disk, struct block_device *dev, int *iinfo) +static int in2000_biosparam(Disk *disk, struct block_device *dev, int *iinfo) { int size; @@ -2190,7 +2201,7 @@ int size; } -int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in) +static int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in) { #ifdef PROC_INTERFACE @@ -2260,8 +2271,7 @@ static int stop = 0; return len; } - save_flags(flags); - cli(); + spin_lock_irqsave(instance->host_lock, flags); bp = buf; *bp = '\0'; if (hd->proc & PR_VERSION) { @@ -2340,7 +2350,7 @@ static int stop = 0; ; /* insert your own custom function here */ } strcat(bp,"\n"); - restore_flags(flags); + spin_unlock_irqrestore(instance->host_lock, flags); *start = buf; if (stop) { stop = 0; diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h index f29f4de0bd94..d51298eaf8b0 100644 --- a/drivers/scsi/in2000.h +++ b/drivers/scsi/in2000.h @@ -397,13 +397,15 @@ struct IN2000_hostdata { # define CLISPIN_UNLOCK(host,flags) spin_unlock_irqrestore(host->host_lock, \ flags) -int in2000_detect(Scsi_Host_Template *) in2000__INIT; -int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int in2000_abort(Scsi_Cmnd *); -void in2000_setup(char *, int *) in2000__INIT; -int in2000_proc_info(char *, char **, off_t, int, int, int); -int in2000_biosparam(struct scsi_disk *, struct block_device *, int *); -int in2000_reset(Scsi_Cmnd *, unsigned int); +static int in2000_detect(Scsi_Host_Template *) in2000__INIT; +static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +static int in2000_abort(Scsi_Cmnd *); +static void in2000_setup(char *, int *) in2000__INIT; +static int in2000_proc_info(char *, char **, off_t, int, int, int); +static int in2000_biosparam(struct scsi_disk *, struct block_device *, int *); +static int in2000_host_reset(Scsi_Cmnd *); +static int in2000_bus_reset(Scsi_Cmnd *); +static int in2000_device_reset(Scsi_Cmnd *); #define IN2000_CAN_Q 16 @@ -411,19 +413,21 @@ int in2000_reset(Scsi_Cmnd *, unsigned int); #define IN2000_CPL 2 #define IN2000_HOST_ID 7 -#define IN2000 { proc_name: "in2000", /* name of /proc/scsi directory entry */ \ - proc_info: in2000_proc_info, /* pointer to proc info function */ \ - name: "Always IN2000", /* device name */ \ - detect: in2000_detect, /* returns number of in2000's found */ \ - queuecommand: in2000_queuecommand, /* queue scsi command, don't wait */ \ - abort: in2000_abort, /* abort current command */ \ - reset: in2000_reset, /* reset scsi bus */ \ - bios_param: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \ - can_queue: IN2000_CAN_Q, /* max commands we can queue up */ \ - this_id: IN2000_HOST_ID, /* host-adapter scsi id */ \ - sg_tablesize: IN2000_SG, /* scatter-gather table size */ \ - cmd_per_lun: IN2000_CPL, /* commands per lun */ \ - use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \ +#define IN2000 { proc_name: "in2000", /* name of /proc/scsi directory entry */ \ + proc_info: in2000_proc_info, /* pointer to proc info function */ \ + name: "Always IN2000", /* device name */ \ + detect: in2000_detect, /* returns number of in2000's found */ \ + queuecommand: in2000_queuecommand, /* queue scsi command, don't wait */ \ + eh_abort_handler: in2000_abort, /* abort current command */ \ + eh_bus_reset_handler: in2000_bus_reset, /* reset scsi bus */ \ + eh_device_reset_handler: in2000_device_reset, /* reset scsi device */ \ + eh_host_reset_handler: in2000_host_reset, /* reset scsi hba */ \ + bios_param: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \ + can_queue: IN2000_CAN_Q, /* max commands we can queue up */ \ + this_id: IN2000_HOST_ID, /* host-adapter scsi id */ \ + sg_tablesize: IN2000_SG, /* scatter-gather table size */ \ + cmd_per_lun: IN2000_CPL, /* commands per lun */ \ + use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \ } #endif /* IN2000_H */ diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index b97aa7b8f194..8f325660d45e 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1,11 +1,12 @@ /*****************************************************************************/ -/* ips.c -- driver for the IBM ServeRAID controller */ +/* ips.c -- driver for the Adaptec / IBM ServeRAID controller */ /* */ /* Written By: Keith Mitchell, IBM Corporation */ /* Jack Hammer, Adaptec, Inc. */ /* David Jeffery, Adaptec, Inc. */ /* */ -/* Copyright (C) 2000 IBM Corporation */ +/* Copyright (C) 2000 IBM Corporation */ +/* Copyright (C) 2002 Adaptec, Inc. */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -42,7 +43,7 @@ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ /* Bugs/Comments/Suggestions about this driver should be mailed to: */ -/* ipslinux@us.ibm.com */ +/* ipslinux@adaptec.com */ /* */ /* For system support issues, contact your local IBM Customer support. */ /* Directions to find IBM Customer Support for each country can be found at: */ @@ -66,9 +67,8 @@ /* 0.99.05 - Fix an oops when we get certain passthru commands */ /* 1.00.00 - Initial Public Release */ /* Functionally equivalent to 0.99.05 */ -/* 3.60.00 - Bump max commands to 128 for use with ServeRAID firmware 3.60 */ -/* - Change version to 3.60 to coincide with ServeRAID release */ -/* numbering. */ +/* 3.60.00 - Bump max commands to 128 for use with firmware 3.60 */ +/* - Change version to 3.60 to coincide with release numbering. */ /* 3.60.01 - Remove bogus error check in passthru routine */ /* 3.60.02 - Make DCDB direction based on lookup table */ /* - Only allow one DCDB command to a SCSI ID at a time */ @@ -76,7 +76,7 @@ /* 4.00.01 - Add support for First Failure Data Capture */ /* 4.00.02 - Fix problem with PT DCDB with no buffer */ /* 4.00.03 - Add alternative passthru interface */ -/* - Add ability to flash ServeRAID BIOS */ +/* - Add ability to flash BIOS */ /* 4.00.04 - Rename structures/constants to be prefixed with IPS_ */ /* 4.00.05 - Remove wish_block from init routine */ /* - Use linux/spinlock.h instead of asm/spinlock.h for kernels */ @@ -158,9 +158,7 @@ #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/slab.h> -#include <linux/vmalloc.h> #include <linux/delay.h> -#include <linux/sched.h> #include <linux/pci.h> #include <linux/proc_fs.h> #include <linux/reboot.h> @@ -222,7 +220,7 @@ struct proc_dir_entry proc_scsi_ips = { dma_addr_t *dmahandle) { void * ptr = kmalloc(size, GFP_ATOMIC); if(ptr){ - *dmahandle = VIRT_TO_BUS(ptr); + *dmahandle = (uint32_t)virt_to_bus(ptr); } return ptr; } @@ -231,10 +229,10 @@ struct proc_dir_entry proc_scsi_ips = { #define pci_map_sg(a,b,n,z) (n) #define pci_unmap_sg(a,b,c,d) - #define pci_map_single(a,b,c,d) (VIRT_TO_BUS(b)) + #define pci_map_single(a,b,c,d) ((uint32_t)virt_to_bus(b)) #define pci_unmap_single(a,b,c,d) #ifndef sg_dma_address - #define sg_dma_address(x) (VIRT_TO_BUS((x)->address)) + #define sg_dma_address(x) ((uint32_t)virt_to_bus((x)->address)) #define sg_dma_len(x) ((x)->length) #endif #define pci_unregister_driver(x) @@ -242,18 +240,16 @@ struct proc_dir_entry proc_scsi_ips = { #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) #define IPS_SG_ADDRESS(sg) ((sg)->address) - #define IPS_LOCK_IRQ(lock) spin_lock_irq(&io_request_lock) - #define IPS_UNLOCK_IRQ(lock) spin_unlock_irq(&io_request_lock) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) + #ifndef __devexit_p + #define __devexit_p(x) x + #endif #else #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ page_address((sg)->page)+(sg)->offset : 0) - #define IPS_LOCK_IRQ(lock) spin_lock_irq(lock) - #define IPS_UNLOCK_IRQ(lock) spin_unlock_irq(lock) - #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(lock,flags) - #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(lock,flags) - + #define IPS_LOCK_SAVE(lock,flags) spin_lock(lock) + #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock(lock) #endif #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ @@ -532,6 +528,7 @@ static void copy_mem_info(IPS_INFOSTR *, char *, int); static int copy_info(IPS_INFOSTR *, char *, ...); static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ); static void ips_version_check(ips_ha_t *ha, int intr); +static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index); static int ips_init_phase2( int index ); #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) @@ -962,14 +959,6 @@ ips_detect(Scsi_Host_Template *SHT) { ha = IPS_HA(sh); memset(ha, 0, sizeof(ips_ha_t)); - /* Initialize spin lock */ - spin_lock_init(&ha->scb_lock); - spin_lock_init(&ha->copp_lock); - spin_lock_init(&ha->ips_lock); - spin_lock_init(&ha->copp_waitlist.lock); - spin_lock_init(&ha->scb_waitlist.lock); - spin_lock_init(&ha->scb_activelist.lock); - ips_sh[ips_next_controller] = sh; ips_ha[ips_next_controller] = ha; ips_num_controllers++; @@ -1416,12 +1405,13 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) { /* Routine Description: */ /* */ /* Abort a command (using the new error code stuff) */ -/* */ +/* Note: this routine is called under the io_request_lock */ /****************************************************************************/ int ips_eh_abort(Scsi_Cmnd *SC) { ips_ha_t *ha; ips_copp_wait_item_t *item; + int ret; METHOD_TRACE("ips_eh_abort", 1); @@ -1443,36 +1433,25 @@ ips_eh_abort(Scsi_Cmnd *SC) { return (FAILED); } - if (test_and_set_bit(IPS_IN_ABORT, &ha->flags)) - return (FAILED); - /* See if the command is on the copp queue */ - IPS_QUEUE_LOCK(&ha->copp_waitlist); item = ha->copp_waitlist.head; while ((item) && (item->scsi_cmd != SC)) item = item->next; - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); if (item) { /* Found it */ ips_removeq_copp(&ha->copp_waitlist, item); - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (SUCCESS); - } + ret = (SUCCESS); /* See if the command is on the wait queue */ - if (ips_removeq_wait(&ha->scb_waitlist, SC)) { + } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) { /* command not sent yet */ - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (SUCCESS); + ret = (SUCCESS); } else { /* command must have already been sent */ - clear_bit(IPS_IN_ABORT, &ha->flags); - - return (FAILED); + ret = (FAILED); } + return ret; } /****************************************************************************/ @@ -1493,7 +1472,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { ips_ha_t *ha; ips_scb_t *scb; ips_copp_wait_item_t *item; - unsigned long cpu_flags; METHOD_TRACE("ips_eh_reset", 1); @@ -1518,36 +1496,27 @@ ips_eh_reset(Scsi_Cmnd *SC) { if (!ha->active) return (FAILED); - if (test_and_set_bit(IPS_IN_RESET, &ha->flags)) - return (FAILED); - /* See if the command is on the copp queue */ - IPS_QUEUE_LOCK(&ha->copp_waitlist); item = ha->copp_waitlist.head; while ((item) && (item->scsi_cmd != SC)) item = item->next; - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); if (item) { /* Found it */ ips_removeq_copp(&ha->copp_waitlist, item); - clear_bit(IPS_IN_RESET, &ha->flags); - return (SUCCESS); } /* See if the command is on the wait queue */ if (ips_removeq_wait(&ha->scb_waitlist, SC)) { /* command not sent yet */ - clear_bit(IPS_IN_RESET, &ha->flags); - return (SUCCESS); } /* An explanation for the casual observer: */ /* Part of the function of a RAID controller is automatic error */ /* detection and recovery. As such, the only problem that physically */ - /* resetting a ServeRAID adapter will ever fix is when, for some reason,*/ + /* resetting an adapter will ever fix is when, for some reason, */ /* the driver is not successfully communicating with the adapter. */ /* Therefore, we will attempt to flush this adapter. If that succeeds, */ /* then there's no real purpose in a physical reset. This will complete */ @@ -1574,13 +1543,12 @@ ips_eh_reset(Scsi_Cmnd *SC) { ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); if (ret == IPS_SUCCESS) { printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num); - clear_bit(IPS_IN_RESET, &ha->flags); return (SUCCESS); } } /* Either we can't communicate with the adapter or it's an IOCTL request */ - /* from a ServeRAID utility. A physical reset is needed at this point. */ + /* from a utility. A physical reset is needed at this point. */ ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ @@ -1619,8 +1587,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { } ha->active = FALSE; - clear_bit(IPS_IN_RESET, &ha->flags); - return (FAILED); } @@ -1651,8 +1617,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { } ha->active = FALSE; - clear_bit(IPS_IN_RESET, &ha->flags); - return (FAILED); } @@ -1661,10 +1625,8 @@ ips_eh_reset(Scsi_Cmnd *SC) { struct timeval tv; do_gettimeofday(&tv); - IPS_HA_LOCK(cpu_flags); ha->last_ffdc = tv.tv_sec; ha->reset_count++; - IPS_HA_UNLOCK(cpu_flags); ips_ffdc_reset(ha, IPS_INTR_IORL); } @@ -1683,25 +1645,11 @@ ips_eh_reset(Scsi_Cmnd *SC) { ha->dcdb_active[i-1] = 0; /* Reset the number of active IOCTLs */ - IPS_HA_LOCK(cpu_flags); ha->num_ioctl = 0; - IPS_HA_UNLOCK(cpu_flags); - clear_bit(IPS_IN_RESET, &ha->flags); - - if (!test_bit(IPS_IN_INTR, &ha->flags)) { - /* - * Only execute the next command when - * we are not being called from the - * interrupt handler. The interrupt - * handler wants to do this and since - * interrupts are turned off here.... - */ - ips_next(ha, IPS_INTR_IORL); - } + ips_next(ha, IPS_INTR_IORL); return (SUCCESS); - #endif /* NO_IPS_RESET */ } @@ -1721,7 +1669,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { int ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ips_ha_t *ha; - unsigned long cpu_flags; ips_passthru_t *pt; METHOD_TRACE("ips_queue", 1); @@ -1735,28 +1682,17 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { return (DID_ERROR); if (ips_is_passthru(SC)) { - IPS_QUEUE_LOCK(&ha->copp_waitlist); if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); - SC->result = DID_BUS_BUSY << 16; - done(SC); - - return (0); - } else { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); - } - } else { - IPS_QUEUE_LOCK(&ha->scb_waitlist); - if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); SC->result = DID_BUS_BUSY << 16; done(SC); return (0); - } else { - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); } + } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) { + SC->result = DID_BUS_BUSY << 16; + done(SC); + return (0); } SC->scsi_done = done; @@ -1810,27 +1746,15 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { } scratch->scsi_cmd = SC; - sema_init(&ha->ioctl_sem, 0); - scratch->sem = &ha->ioctl_sem; scratch->next = NULL; ips_putq_copp_tail(&ha->copp_waitlist, scratch); } - else + else { ips_putq_wait_tail(&ha->scb_waitlist, SC); - - if(ha->scb_waitlist.count + ha->scb_activelist.count > 32) - mod_timer(&SC->eh_timeout, jiffies + 120 * HZ); - - IPS_HA_LOCK(cpu_flags); - if ((!test_bit(IPS_IN_INTR, &ha->flags)) && - (!test_bit(IPS_IN_ABORT, &ha->flags)) && - (!test_bit(IPS_IN_RESET, &ha->flags))) { - IPS_HA_UNLOCK(cpu_flags); - ips_next(ha, IPS_INTR_IORL); - } else { - IPS_HA_UNLOCK(cpu_flags); } + + ips_next(ha, IPS_INTR_IORL); /* If We were using the CD Boot Flash Buffer, Restore the Old Values */ if ( ips_FlashData == ha->ioctl_data ) { @@ -1960,20 +1884,13 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) { host = ips_sh[ha->host_num]; IPS_LOCK_SAVE(host->host_lock, cpu_flags); - if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) { - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); - return ; - } - if (!ha->active) { - clear_bit(IPS_IN_INTR, &ha->flags); IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); return; } (*ha->func.intr)(ha); - clear_bit(IPS_IN_INTR, &ha->flags); IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* start the next command */ @@ -1997,7 +1914,6 @@ ips_intr_copperhead(ips_ha_t *ha) { ips_scb_t *scb; IPS_STATUS cstatus; int intrstatus; - unsigned long cpu_flags; METHOD_TRACE("ips_intr", 2); @@ -2007,15 +1923,12 @@ ips_intr_copperhead(ips_ha_t *ha) { if (!ha->active) return; - IPS_HA_LOCK(cpu_flags); - intrstatus = (*ha->func.isintr)(ha); if (!intrstatus) { /* * Unexpected/Shared interrupt */ - IPS_HA_UNLOCK(cpu_flags); return; } @@ -2042,12 +1955,8 @@ ips_intr_copperhead(ips_ha_t *ha) { * use the callback function to finish things up * NOTE: interrupts are OFF for this */ - IPS_HA_UNLOCK(cpu_flags); (*scb->callback) (ha, scb); - IPS_HA_LOCK(cpu_flags); } /* end while */ - - IPS_HA_UNLOCK(cpu_flags); } /****************************************************************************/ @@ -2067,7 +1976,6 @@ ips_intr_morpheus(ips_ha_t *ha) { ips_scb_t *scb; IPS_STATUS cstatus; int intrstatus; - unsigned long cpu_flags; METHOD_TRACE("ips_intr_morpheus", 2); @@ -2077,15 +1985,12 @@ ips_intr_morpheus(ips_ha_t *ha) { if (!ha->active) return; - IPS_HA_LOCK(cpu_flags); - intrstatus = (*ha->func.isintr)(ha); if (!intrstatus) { /* * Unexpected/Shared interrupt */ - IPS_HA_UNLOCK(cpu_flags); return; } @@ -2118,12 +2023,8 @@ ips_intr_morpheus(ips_ha_t *ha) { * use the callback function to finish things up * NOTE: interrupts are OFF for this */ - IPS_HA_UNLOCK(cpu_flags); (*scb->callback) (ha, scb); - IPS_HA_LOCK(cpu_flags); } /* end while */ - - IPS_HA_UNLOCK(cpu_flags); } /****************************************************************************/ @@ -3235,8 +3136,7 @@ ips_next(ips_ha_t *ha, int intr) { Scsi_Cmnd *q; ips_copp_wait_item_t *item; int ret; - unsigned long cpu_flags; - unsigned long cpu_flags2 = 0; + unsigned long cpu_flags = 0; struct Scsi_Host *host; METHOD_TRACE("ips_next", 1); @@ -3247,27 +3147,20 @@ ips_next(ips_ha_t *ha, int intr) { * Block access to the queue function so * this command won't time out */ - if (intr == IPS_INTR_ON) - IPS_LOCK_SAVE(host->host_lock, cpu_flags2); + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { struct timeval tv; do_gettimeofday(&tv); - IPS_HA_LOCK(cpu_flags); if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { ha->last_ffdc = tv.tv_sec; - IPS_HA_UNLOCK(cpu_flags); ips_ffdc_time(ha); - } else { - IPS_HA_UNLOCK(cpu_flags); } } - if (intr == IPS_INTR_ON) - IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags2); - /* * Send passthru commands * These have priority over normal I/O @@ -3275,22 +3168,21 @@ ips_next(ips_ha_t *ha, int intr) { * since we limit the number that can be active * on the card at any one time */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); while ((ha->num_ioctl < IPS_MAX_IOCTL) && (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) { - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); item = ips_removeq_copp_head(&ha->copp_waitlist); ha->num_ioctl++; - IPS_HA_UNLOCK(cpu_flags); + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); scb->scsi_cmd = item->scsi_cmd; - scb->sem = item->sem; kfree(item); ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); switch (ret) { case IPS_FAILURE: if (scb->scsi_cmd) { @@ -3313,8 +3205,6 @@ ips_next(ips_ha_t *ha, int intr) { } /* end case */ if (ret != IPS_SUCCESS) { - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); ha->num_ioctl--; continue; } @@ -3341,20 +3231,14 @@ ips_next(ips_ha_t *ha, int intr) { break; } /* end case */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->copp_waitlist); } - IPS_QUEUE_UNLOCK(&ha->copp_waitlist); - IPS_HA_UNLOCK(cpu_flags); /* * Send "Normal" I/O commands */ - IPS_HA_LOCK(cpu_flags); - IPS_QUEUE_LOCK(&ha->scb_waitlist); + p = ha->scb_waitlist.head; - IPS_QUEUE_UNLOCK(&ha->scb_waitlist); while ((p) && (scb = ips_getscb(ha))) { if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { ips_freescb(ha, scb); @@ -3364,10 +3248,9 @@ ips_next(ips_ha_t *ha, int intr) { q = p; SC = ips_removeq_wait(&ha->scb_waitlist, q); - if (SC == NULL) /* Should never happen, but good to check anyway */ - continue; - IPS_HA_UNLOCK(cpu_flags); /* Unlock HA after command is taken off queue */ + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */ SC->result = DID_OK; SC->host_scribble = NULL; @@ -3475,13 +3358,15 @@ ips_next(ips_ha_t *ha, int intr) { scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; scb->dcdb.transfer_length = 0; } - + if(intr == IPS_INTR_ON) + IPS_LOCK_SAVE(host->host_lock, cpu_flags); + ret = ips_send_cmd(ha, scb); - if (ret == IPS_SUCCESS) - ips_putq_scb_head(&ha->scb_activelist, scb); - switch(ret) { + case IPS_SUCCESS: + ips_putq_scb_head(&ha->scb_activelist, scb); + break; case IPS_FAILURE: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; @@ -3508,10 +3393,10 @@ ips_next(ips_ha_t *ha, int intr) { p = (Scsi_Cmnd *) p->host_scribble; - IPS_HA_LOCK(cpu_flags); } /* end while */ - IPS_HA_UNLOCK(cpu_flags); + if(intr == IPS_INTR_ON) + IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); } /****************************************************************************/ @@ -3522,7 +3407,7 @@ ips_next(ips_ha_t *ha, int intr) { /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3532,8 +3417,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->q_next = queue->head; queue->head = item; @@ -3541,8 +3424,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3553,7 +3434,7 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3563,8 +3444,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->q_next = NULL; if (queue->tail) @@ -3576,8 +3455,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3588,7 +3465,7 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_scb_t * @@ -3597,13 +3474,9 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { METHOD_TRACE("ips_removeq_scb_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3615,8 +3488,6 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3628,7 +3499,7 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_scb_t * @@ -3640,11 +3511,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_scb_head(queue)); } @@ -3663,13 +3530,9 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { item->q_next = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3681,7 +3544,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3691,8 +3554,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->host_scribble = (char *) queue->head; queue->head = item; @@ -3700,8 +3561,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3712,7 +3571,7 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3722,8 +3581,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->host_scribble = NULL; if (queue->tail) @@ -3735,8 +3592,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3747,7 +3602,7 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline Scsi_Cmnd * @@ -3756,13 +3611,9 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { METHOD_TRACE("ips_removeq_wait_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3774,8 +3625,6 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3787,7 +3636,7 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline Scsi_Cmnd * @@ -3799,11 +3648,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_wait_head(queue)); } @@ -3822,13 +3667,9 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { item->host_scribble = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3840,7 +3681,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { /* */ /* Add an item to the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3850,8 +3691,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->next = queue->head; queue->head = item; @@ -3859,8 +3698,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { queue->tail = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3871,7 +3708,7 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { /* */ /* Add an item to the tail of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline void @@ -3881,8 +3718,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { if (!item) return ; - IPS_QUEUE_LOCK(queue); - item->next = NULL; if (queue->tail) @@ -3894,8 +3729,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { queue->head = item; queue->count++; - - IPS_QUEUE_UNLOCK(queue); } /****************************************************************************/ @@ -3906,7 +3739,7 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { /* */ /* Remove the head of the queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * @@ -3915,13 +3748,9 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { METHOD_TRACE("ips_removeq_copp_head", 1); - IPS_QUEUE_LOCK(queue); - item = queue->head; if (!item) { - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -3933,8 +3762,6 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } @@ -3946,7 +3773,7 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { /* */ /* Remove an item from a queue */ /* */ -/* ASSUMED to be called from within a lock */ +/* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ static inline ips_copp_wait_item_t * @@ -3958,11 +3785,7 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { if (!item) return (NULL); - IPS_QUEUE_LOCK(queue); - if (item == queue->head) { - IPS_QUEUE_UNLOCK(queue); - return (ips_removeq_copp_head(queue)); } @@ -3981,13 +3804,9 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { item->next = NULL; queue->count--; - IPS_QUEUE_UNLOCK(queue); - return (item); } - IPS_QUEUE_UNLOCK(queue); - return (NULL); } @@ -4051,12 +3870,11 @@ ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) { /* Routine Description: */ /* */ /* Do housekeeping on completed commands */ -/* */ +/* ASSUMED to be called form within the request lock */ /****************************************************************************/ static void ips_done(ips_ha_t *ha, ips_scb_t *scb) { int ret; - unsigned long cpu_flags; METHOD_TRACE("ips_done", 1); @@ -4065,9 +3883,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { ips_cleanup_passthru(ha, scb); - IPS_HA_LOCK(cpu_flags); ha->num_ioctl--; - IPS_HA_UNLOCK(cpu_flags); } else { /* * Check to see if this command had too much @@ -4226,9 +4042,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { } /* end if passthru */ if (scb->bus) { - IPS_HA_LOCK(cpu_flags); ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); - IPS_HA_UNLOCK(cpu_flags); } scb->scsi_cmd->scsi_done(scb->scsi_cmd); @@ -4336,7 +4150,7 @@ ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) { (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) { tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; memcpy(scb->scsi_cmd->sense_buffer, tapeDCDB->sense_info, - sizeof(tapeDCDB->sense_info)); + sizeof(scb->scsi_cmd->sense_buffer)); } else { memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info, sizeof(scb->scsi_cmd->sense_buffer)); @@ -4408,6 +4222,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { char *sp; int device_error; IPS_DCDB_TABLE_TAPE *tapeDCDB; + int TimeOut; METHOD_TRACE("ips_send_cmd", 1); @@ -4478,8 +4293,10 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = ha->adapt->hw_status_start + sizeof(IPS_ADAPTER) - - sizeof(IPS_LD_INFO); + scb->data_busaddr = pci_map_single(ha->pcidev, + &ha->adapt->logical_drive_info, + scb->data_len, IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; scb->cmd.logical_info.buffer_addr = scb->data_busaddr; ret = IPS_SUCCESS; } @@ -4586,8 +4403,10 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.logical_info.reserved2 = 0; scb->cmd.logical_info.reserved3 = 0; scb->data_len = sizeof(ha->adapt->logical_drive_info); - scb->data_busaddr = ha->adapt->hw_status_start + sizeof(IPS_ADAPTER) - - sizeof(IPS_LD_INFO); + scb->data_busaddr = pci_map_single(ha->pcidev, + &ha->adapt->logical_drive_info, + scb->data_len, IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; scb->cmd.logical_info.buffer_addr = scb->data_busaddr; ret = IPS_SUCCESS; break; @@ -4642,11 +4461,13 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + - (unsigned long)&scb->dcdb - - (unsigned long)scb); + (unsigned long)&scb->dcdb - + (unsigned long)scb); scb->cmd.dcdb.reserved = 0; scb->cmd.dcdb.reserved2 = 0; - scb->cmd.dcdb.reserved3 = 0; + scb->cmd.dcdb.reserved3 = 0; + + TimeOut = scb->scsi_cmd->timeout_per_command; if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ if (!scb->sg_len) @@ -4657,47 +4478,52 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */ tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id; tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; - - if (scb->timeout) { - if (scb->timeout <= 10) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; - else if (scb->timeout <= 60) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; - else - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; + tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */ + + if (TimeOut) { + if (TimeOut < ( 10 * HZ )) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ } - if (!(tapeDCDB->cmd_attribute & IPS_TIMEOUT20M)) - tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; - - tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); + tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; + tapeDCDB->reserved_for_LUN = 0; tapeDCDB->transfer_length = scb->data_len; tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); tapeDCDB->sg_count = scb->sg_len; - tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; + tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); + tapeDCDB->scsi_status = 0; + tapeDCDB->reserved = 0; memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); } else { scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id; scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; - if (scb->timeout) { - if (scb->timeout <= 10) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; - else if (scb->timeout <= 60) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; - else - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; + if (TimeOut) { + if (TimeOut < (10 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */ + else if (TimeOut < (60 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */ + else if (TimeOut < (1200 * HZ)) + scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */ } - - if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M)) - scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; - - scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); + scb->dcdb.transfer_length = scb->data_len; + if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) + scb->dcdb.transfer_length = 0; scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); - scb->dcdb.sg_count = scb->sg_len; scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; + scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); + scb->dcdb.sg_count = scb->sg_len; + scb->dcdb.reserved = 0; memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); + scb->dcdb.scsi_status = 0; + scb->dcdb.reserved2[0] = 0; + scb->dcdb.reserved2[1] = 0; + scb->dcdb.reserved2[2] = 0; } } @@ -4711,7 +4537,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { /* Routine Description: */ /* */ /* Check the status of commands to logical drives */ -/* */ +/* Assumed to be called with the HA lock */ /****************************************************************************/ static void ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { @@ -5240,13 +5066,10 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { static ips_scb_t * ips_getscb(ips_ha_t *ha) { ips_scb_t *scb; - unsigned long cpu_flags; METHOD_TRACE("ips_getscb", 1); - IPS_SCB_LOCK(cpu_flags); if ((scb = ha->scb_freelist) == NULL) { - IPS_SCB_UNLOCK(cpu_flags); return (NULL); } @@ -5254,8 +5077,6 @@ ips_getscb(ips_ha_t *ha) { ha->scb_freelist = scb->q_next; scb->q_next = NULL; - IPS_SCB_UNLOCK(cpu_flags); - ips_init_scb(ha, scb); return (scb); @@ -5274,7 +5095,6 @@ ips_getscb(ips_ha_t *ha) { /****************************************************************************/ static void ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_freescb", 1); if(scb->flags & IPS_SCB_MAP_SG) @@ -5287,10 +5107,8 @@ ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { /* check to make sure this is not our "special" scb */ if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { - IPS_SCB_LOCK(cpu_flags); scb->q_next = ha->scb_freelist; ha->scb_freelist = scb; - IPS_SCB_UNLOCK(cpu_flags); } } @@ -5702,15 +5520,12 @@ ips_init_morpheus(ips_ha_t *ha) { static int ips_reset_copperhead(ips_ha_t *ha) { int reset_counter; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_copperhead", 1); DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", ips_name, ha->host_num, ha->io_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5729,14 +5544,11 @@ ips_reset_copperhead(ips_ha_t *ha) { if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5752,15 +5564,12 @@ ips_reset_copperhead(ips_ha_t *ha) { static int ips_reset_copperhead_memio(ips_ha_t *ha) { int reset_counter; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_copperhead_memio", 1); DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", ips_name, ha->host_num, ha->mem_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5779,14 +5588,11 @@ ips_reset_copperhead_memio(ips_ha_t *ha) { if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5803,15 +5609,12 @@ static int ips_reset_morpheus(ips_ha_t *ha) { int reset_counter; uint8_t junk; - unsigned long cpu_flags; METHOD_TRACE("ips_reset_morpheus", 1); DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", ips_name, ha->host_num, ha->mem_addr, ha->irq); - IPS_HA_LOCK(cpu_flags); - reset_counter = 0; while (reset_counter < 2) { @@ -5828,14 +5631,11 @@ ips_reset_morpheus(ips_ha_t *ha) { if ((*ha->func.init)(ha)) break; else if (reset_counter >= 2) { - IPS_HA_UNLOCK(cpu_flags); return (0); } } - IPS_HA_UNLOCK(cpu_flags); - return (1); } @@ -5980,7 +5780,6 @@ static int ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { uint32_t TimeOut; uint32_t val; - unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead", 1); @@ -6000,8 +5799,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - TimeOut = 0; while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { @@ -6016,8 +5813,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", ips_name, ha->host_num); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_FAILURE); } /* end if */ } /* end while */ @@ -6025,8 +5820,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6043,7 +5836,6 @@ static int ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { uint32_t TimeOut; uint32_t val; - unsigned long cpu_flags; METHOD_TRACE("ips_issue_copperhead_memio", 1); @@ -6063,8 +5855,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - TimeOut = 0; while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { @@ -6079,8 +5869,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", ips_name, ha->host_num); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_FAILURE); } /* end if */ } /* end while */ @@ -6088,8 +5876,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6104,7 +5890,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_issue_i2o", 1); @@ -6124,12 +5909,8 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6144,7 +5925,6 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { /****************************************************************************/ static int ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { - unsigned long cpu_flags; METHOD_TRACE("ips_issue_i2o_memio", 1); @@ -6164,12 +5944,8 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { scb->cmd.basic_io.command_id); } - IPS_HA_LOCK(cpu_flags); - writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); - IPS_HA_UNLOCK(cpu_flags); - return (IPS_SUCCESS); } @@ -6306,12 +6082,7 @@ ips_wait(ips_ha_t *ha, int time, int intr) { * until after we finish. */ - while (test_and_set_bit(IPS_IN_INTR, &ha->flags)) - udelay(1000); - (*ha->func.intr)(ha); - - clear_bit(IPS_IN_INTR, &ha->flags); } /* This looks like a very evil loop, but it only does this during start-up */ @@ -7394,6 +7165,14 @@ static Scsi_Host_Template driver_template = IPS; #include "scsi_module.c" #endif +static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ + ha->active = 0; + ips_free(ha); + scsi_unregister(sh); + ips_ha[index] = 0; + ips_sh[index] = 0; + return -1; +} #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) @@ -7568,14 +7347,6 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ha = IPS_HA(sh); memset(ha, 0, sizeof(ips_ha_t)); - /* Initialize spin lock */ - spin_lock_init(&ha->scb_lock); - spin_lock_init(&ha->copp_lock); - spin_lock_init(&ha->ips_lock); - spin_lock_init(&ha->copp_waitlist.lock); - spin_lock_init(&ha->scb_waitlist.lock); - spin_lock_init(&ha->scb_activelist.lock); - ips_sh[index] = sh; ips_ha[index] = ha; ha->active = 1; @@ -7584,24 +7355,14 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) if (!ha->enq) { printk(KERN_WARNING "Unable to allocate host inquiry structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->adapt = pci_alloc_consistent(ha->pcidev, sizeof(IPS_ADAPTER) + sizeof(IPS_IO_CMD), &dma_address); if (!ha->adapt) { printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n"); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->adapt->hw_status_start = dma_address; ha->dummy = (void *)(ha->adapt + 1); @@ -7610,36 +7371,21 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) if (!ha->conf) { printk(KERN_WARNING "Unable to allocate host conf structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); if (!ha->nvram) { printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); if (!ha->subsys) { printk(KERN_WARNING "Unable to allocate host subsystem structure\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } for (count = PAGE_SIZE, ha->ioctl_order = 0; @@ -7748,24 +7494,14 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) * Initialization failed */ printk(KERN_WARNING "Unable to initialize controller\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } } /* Install the interrupt handler */ if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { printk(KERN_WARNING "Unable to install interrupt handler\n" ); - ha->active = 0; - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } /* @@ -7774,13 +7510,8 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ha->max_cmds = 1; if (!ips_allocatescbs(ha)) { printk(KERN_WARNING "Unable to allocate a CCB\n" ); - ha->active = 0; free_irq(ha->irq, ha); - ips_free(ha); - scsi_unregister(sh); - ips_ha[index] = 0; - ips_sh[index] = 0; - return -1; + return ips_abort_init(ha, sh, index); } *indexPtr = index; @@ -7816,13 +7547,8 @@ static int ips_init_phase2( int index ) if (!ips_hainit(ha)) { printk(KERN_WARNING "Unable to initialize controller\n" ); - ha->active = 0; - ips_free(ha); free_irq(ha->irq, ha); - scsi_unregister(sh); - ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1; + return ips_abort_init(ha, sh, index); } /* Free the temporary SCB */ ips_deallocatescbs(ha, 1); @@ -7830,13 +7556,8 @@ static int ips_init_phase2( int index ) /* allocate CCBs */ if (!ips_allocatescbs(ha)) { printk(KERN_WARNING "Unable to allocate CCBs\n" ); - ha->active = 0; - ips_free(ha); free_irq(ha->irq, ha); - scsi_unregister(sh); - ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1; + return ips_abort_init(ha, sh, index); } /* finish setting values */ diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 9cc112d362e6..161e66b4275c 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -1,9 +1,12 @@ /*****************************************************************************/ -/* ips.h -- driver for the IBM ServeRAID controller */ +/* ips.h -- driver for the Adaptec / IBM ServeRAID controller */ /* */ /* Written By: Keith Mitchell, IBM Corporation */ +/* Jack Hammer, Adaptec, Inc. */ +/* David Jeffery, Adaptec, Inc. */ /* */ /* Copyright (C) 1999 IBM Corporation */ +/* Copyright (C) 2003 Adaptec, Inc. */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -40,7 +43,7 @@ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ /* Bugs/Comments/Suggestions should be mailed to: */ -/* ipslinux@us.ibm.com */ +/* ipslinux@adaptec.com */ /* */ /*****************************************************************************/ @@ -84,33 +87,11 @@ ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \ (ips_force_memio))) ? 1 : 0) - #ifndef VIRT_TO_BUS - #define VIRT_TO_BUS(x) (uint32_t) virt_to_bus((void *) x) - #endif - #ifndef MDELAY #define MDELAY mdelay #endif - - #ifndef verify_area_20 - #define verify_area_20(t,a,sz) (0) /* success */ - #endif - - #ifndef DECLARE_MUTEX_LOCKED - #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED; - #endif /* - * Lock macros - */ - #define IPS_SCB_LOCK(cpu_flags) spin_lock_irqsave(&ha->scb_lock, cpu_flags) - #define IPS_SCB_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->scb_lock, cpu_flags) - #define IPS_QUEUE_LOCK(queue) spin_lock_irqsave(&(queue)->lock, (queue)->cpu_flags) - #define IPS_QUEUE_UNLOCK(queue) spin_unlock_irqrestore(&(queue)->lock, (queue)->cpu_flags) - #define IPS_HA_LOCK(cpu_flags) spin_lock_irqsave(&ha->ips_lock, cpu_flags) - #define IPS_HA_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->ips_lock, cpu_flags) - - /* * Adapter address map equates */ #define IPS_REG_HISR 0x08 /* Host Interrupt Status Reg */ @@ -1063,8 +1044,6 @@ typedef struct ips_scb_queue { struct ips_scb *head; struct ips_scb *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_scb_queue_t; /* @@ -1074,13 +1053,10 @@ typedef struct ips_wait_queue { Scsi_Cmnd *head; Scsi_Cmnd *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_wait_queue_t; typedef struct ips_copp_wait_item { Scsi_Cmnd *scsi_cmd; - struct semaphore *sem; struct ips_copp_wait_item *next; } ips_copp_wait_item_t; @@ -1088,8 +1064,6 @@ typedef struct ips_copp_queue { struct ips_copp_wait_item *head; struct ips_copp_wait_item *tail; int count; - unsigned long cpu_flags; - spinlock_t lock; } ips_copp_queue_t; /* forward decl for host structure */ @@ -1138,7 +1112,6 @@ typedef struct ips_ha { char *ioctl_data; /* IOCTL data area */ uint32_t ioctl_datasize; /* IOCTL data size */ uint32_t cmd_in_progress; /* Current command in progress*/ - unsigned long flags; /* HA flags */ uint8_t waitflag; /* are we waiting for cmd */ uint8_t active; int ioctl_reset; /* IOCTL Requested Reset Flag */ @@ -1158,11 +1131,6 @@ typedef struct ips_ha { char *ioremap_ptr; /* ioremapped memory pointer */ ips_hw_func_t func; /* hw function pointers */ struct pci_dev *pcidev; /* PCI device handle */ - spinlock_t scb_lock; - spinlock_t copp_lock; - spinlock_t ips_lock; - struct semaphore ioctl_sem; /* Semaphore for new IOCTL's */ - struct semaphore flash_ioctl_sem; /* Semaphore for Flashing */ char *flash_data; /* Save Area for flash data */ u8 flash_order; /* Save Area for flash size order */ u32 flash_datasize; /* Save Area for flash data size */ @@ -1195,7 +1163,6 @@ typedef struct ips_scb { Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; - struct semaphore *sem; uint32_t sg_busaddr; int sg_count; } ips_scb_t; diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 9ec5f1281ee9..3a2cb1e31b50 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -216,8 +216,8 @@ * */ typedef volatile struct mailbox { - unchar status; - unchar scbptr[3]; /* SCSI-style - MSB first (big endian) */ + unchar status; + unchar scbptr[3]; /* SCSI-style - MSB first (big endian) */ } Mailbox; /* @@ -225,38 +225,36 @@ typedef volatile struct mailbox { * new global per-adapter data should put in here. */ typedef struct adapter { - struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */ - int iobase; /* This adapter's I/O base address */ - int irq; /* This adapter's IRQ level */ - int dma; /* This adapter's DMA channel */ - int int_counter; /* This adapter's interrupt counter */ - int bus_on; /* This adapter's BUS_ON time */ - int bus_off; /* This adapter's BUS_OFF time */ - struct { /* This adapter's mailboxes */ - Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes */ - Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes */ - } mb; - int next_ogmb; /* to reduce contention at mailboxes */ - unchar control; /* shadows CONTROL port value */ - unchar rev1, rev2; /* filled in by wd7000_revision */ + struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */ + int iobase; /* This adapter's I/O base address */ + int irq; /* This adapter's IRQ level */ + int dma; /* This adapter's DMA channel */ + int int_counter; /* This adapter's interrupt counter */ + int bus_on; /* This adapter's BUS_ON time */ + int bus_off; /* This adapter's BUS_OFF time */ + struct { /* This adapter's mailboxes */ + Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes */ + Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes */ + } mb; + int next_ogmb; /* to reduce contention at mailboxes */ + unchar control; /* shadows CONTROL port value */ + unchar rev1, rev2; /* filled in by wd7000_revision */ } Adapter; /* * (linear) base address for ROM BIOS */ -static const long wd7000_biosaddr[] = -{ - 0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000, - 0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000 +static const long wd7000_biosaddr[] = { + 0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000, + 0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000 }; #define NUM_ADDRS (sizeof(wd7000_biosaddr)/sizeof(long)) -static const unsigned short wd7000_iobase[] = -{ - 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338, - 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378, - 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8, - 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8 +static const unsigned short wd7000_iobase[] = { + 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338, + 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378, + 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8, + 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8 }; #define NUM_IOPORTS (sizeof(wd7000_iobase)/sizeof(unsigned short)) @@ -270,36 +268,35 @@ static const short wd7000_dma[] = { 5, 6, 7 }; * The following is set up by wd7000_detect, and used thereafter for * proc and other global ookups */ - + #define UNITS 8 static struct Scsi_Host *wd7000_host[UNITS]; -#define BUS_ON 64 /* x 125ns = 8000ns (BIOS default) */ -#define BUS_OFF 15 /* x 125ns = 1875ns (BIOS default) */ +#define BUS_ON 64 /* x 125ns = 8000ns (BIOS default) */ +#define BUS_OFF 15 /* x 125ns = 1875ns (BIOS default) */ /* * Standard Adapter Configurations - used by wd7000_detect */ typedef struct { - short irq; /* IRQ level */ - short dma; /* DMA channel */ - unsigned iobase; /* I/O base address */ - short bus_on; /* Time that WD7000 spends on the AT-bus when */ - /* transferring data. BIOS default is 8000ns. */ - short bus_off; /* Time that WD7000 spends OFF THE BUS after */ - /* while it is transferring data. */ - /* BIOS default is 1875ns */ + short irq; /* IRQ level */ + short dma; /* DMA channel */ + unsigned iobase; /* I/O base address */ + short bus_on; /* Time that WD7000 spends on the AT-bus when */ + /* transferring data. BIOS default is 8000ns. */ + short bus_off; /* Time that WD7000 spends OFF THE BUS after */ + /* while it is transferring data. */ + /* BIOS default is 1875ns */ } Config; /* * Add here your configuration... */ -static Config configs[] = -{ - { 15, 6, 0x350, BUS_ON, BUS_OFF }, /* defaults for single adapter */ - { 11, 5, 0x320, BUS_ON, BUS_OFF }, /* defaults for second adapter */ - { 7, 6, 0x350, BUS_ON, BUS_OFF }, /* My configuration (Zaga) */ - { -1, -1, 0x0, BUS_ON, BUS_OFF } /* Empty slot */ +static Config configs[] = { + {15, 6, 0x350, BUS_ON, BUS_OFF}, /* defaults for single adapter */ + {11, 5, 0x320, BUS_ON, BUS_OFF}, /* defaults for second adapter */ + {7, 6, 0x350, BUS_ON, BUS_OFF}, /* My configuration (Zaga) */ + {-1, -1, 0x0, BUS_ON, BUS_OFF} /* Empty slot */ }; #define NUM_CONFIGS (sizeof(configs)/sizeof(Config)) @@ -309,14 +306,13 @@ static Config configs[] = * added for the Future Domain version. */ typedef struct signature { - const char *sig; /* String to look for */ - unsigned long ofs; /* offset from BIOS base address */ - unsigned len; /* length of string */ + const char *sig; /* String to look for */ + unsigned long ofs; /* offset from BIOS base address */ + unsigned len; /* length of string */ } Signature; -static const Signature signatures[] = -{ - {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */ +static const Signature signatures[] = { + {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */ }; #define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature)) @@ -363,14 +359,14 @@ static const Signature signatures[] = * For INITIALIZATION: */ typedef struct initCmd { - unchar op; /* command opcode (= 1) */ - unchar ID; /* Adapter's SCSI ID */ - unchar bus_on; /* Bus on time, x 125ns (see below) */ - unchar bus_off; /* Bus off time, "" "" */ - unchar rsvd; /* Reserved */ - unchar mailboxes[3]; /* Address of Mailboxes, MSB first */ - unchar ogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */ - unchar icmbs; /* Number of incoming MBs, "" "" */ + unchar op; /* command opcode (= 1) */ + unchar ID; /* Adapter's SCSI ID */ + unchar bus_on; /* Bus on time, x 125ns (see below) */ + unchar bus_off; /* Bus off time, "" "" */ + unchar rsvd; /* Reserved */ + unchar mailboxes[3]; /* Address of Mailboxes, MSB first */ + unchar ogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */ + unchar icmbs; /* Number of incoming MBs, "" "" */ } InitCmd; /* @@ -430,29 +426,29 @@ typedef struct initCmd { * WD7000-specific scatter/gather element structure */ typedef struct sgb { - unchar len[3]; - unchar ptr[3]; /* Also SCSI-style - MSB first */ + unchar len[3]; + unchar ptr[3]; /* Also SCSI-style - MSB first */ } Sgb; typedef struct scb { /* Command Control Block 5.4.1 */ - unchar op; /* Command Control Block Operation Code */ - unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ - /* Outbound data transfer, length is checked */ - /* Inbound data transfer, length is checked */ - /* Logical Unit Number */ - unchar cdb[12]; /* SCSI Command Block */ - volatile unchar status; /* SCSI Return Status */ - volatile unchar vue; /* Vendor Unique Error Code */ - unchar maxlen[3]; /* Maximum Data Transfer Length */ - unchar dataptr[3]; /* SCSI Data Block Pointer */ - unchar linkptr[3]; /* Next Command Link Pointer */ - unchar direc; /* Transfer Direction */ - unchar reserved2[6]; /* SCSI Command Descriptor Block */ - /* end of hardware SCB */ - Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */ - Sgb sgb[WD7000_SG]; /* Scatter/gather list for this SCB */ - Adapter *host; /* host adapter */ - struct scb *next; /* for lists of scbs */ + unchar op; /* Command Control Block Operation Code */ + unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ + /* Outbound data transfer, length is checked */ + /* Inbound data transfer, length is checked */ + /* Logical Unit Number */ + unchar cdb[12]; /* SCSI Command Block */ + volatile unchar status; /* SCSI Return Status */ + volatile unchar vue; /* Vendor Unique Error Code */ + unchar maxlen[3]; /* Maximum Data Transfer Length */ + unchar dataptr[3]; /* SCSI Data Block Pointer */ + unchar linkptr[3]; /* Next Command Link Pointer */ + unchar direc; /* Transfer Direction */ + unchar reserved2[6]; /* SCSI Command Descriptor Block */ + /* end of hardware SCB */ + Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */ + Sgb sgb[WD7000_SG]; /* Scatter/gather list for this SCB */ + Adapter *host; /* host adapter */ + struct scb *next; /* for lists of scbs */ } Scb; /* @@ -484,56 +480,56 @@ typedef struct scb { /* Command Control Block 5.4.1 */ #define ICB_OP_GET_EPARMS 0x8F /* read execution parameters */ typedef struct icbRecvCmd { - unchar op; - unchar IDlun; /* Initiator SCSI ID/lun */ - unchar len[3]; /* command buffer length */ - unchar ptr[3]; /* command buffer address */ - unchar rsvd[7]; /* reserved */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + unchar IDlun; /* Initiator SCSI ID/lun */ + unchar len[3]; /* command buffer length */ + unchar ptr[3]; /* command buffer address */ + unchar rsvd[7]; /* reserved */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbRecvCmd; typedef struct icbSendStat { - unchar op; - unchar IDlun; /* Target SCSI ID/lun */ - unchar stat; /* (outgoing) completion status byte 1 */ - unchar rsvd[12]; /* reserved */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + unchar IDlun; /* Target SCSI ID/lun */ + unchar stat; /* (outgoing) completion status byte 1 */ + unchar rsvd[12]; /* reserved */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbSendStat; typedef struct icbRevLvl { - unchar op; - volatile unchar primary; /* primary revision level (returned) */ - volatile unchar secondary; /* secondary revision level (returned) */ - unchar rsvd[12]; /* reserved */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + volatile unchar primary; /* primary revision level (returned) */ + volatile unchar secondary; /* secondary revision level (returned) */ + unchar rsvd[12]; /* reserved */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbRevLvl; typedef struct icbUnsMask { /* I'm totally guessing here */ - unchar op; - volatile unchar mask[14]; /* mask bits */ + unchar op; + volatile unchar mask[14]; /* mask bits */ #if 0 - unchar rsvd[12]; /* reserved */ + unchar rsvd[12]; /* reserved */ #endif - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbUnsMask; typedef struct icbDiag { - unchar op; - unchar type; /* diagnostics type code (0-3) */ - unchar len[3]; /* buffer length */ - unchar ptr[3]; /* buffer address */ - unchar rsvd[7]; /* reserved */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + unchar type; /* diagnostics type code (0-3) */ + unchar len[3]; /* buffer length */ + unchar ptr[3]; /* buffer address */ + unchar rsvd[7]; /* reserved */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbDiag; #define ICB_DIAG_POWERUP 0 /* Power-up diags only */ @@ -542,34 +538,34 @@ typedef struct icbDiag { #define ICB_DIAG_FULL 3 /* do both 1 & 2 */ typedef struct icbParms { - unchar op; - unchar rsvd1; /* reserved */ - unchar len[3]; /* parms buffer length */ - unchar ptr[3]; /* parms buffer address */ - unchar idx[2]; /* index (MSB-LSB) */ - unchar rsvd2[5]; /* reserved */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + unchar rsvd1; /* reserved */ + unchar len[3]; /* parms buffer length */ + unchar ptr[3]; /* parms buffer address */ + unchar idx[2]; /* index (MSB-LSB) */ + unchar rsvd2[5]; /* reserved */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbParms; typedef struct icbAny { - unchar op; - unchar data[14]; /* format-specific data */ - volatile unchar vue; /* vendor-unique error code */ - volatile unchar status; /* returned (icmb) status */ - volatile unchar phase; /* used by interrupt handler */ + unchar op; + unchar data[14]; /* format-specific data */ + volatile unchar vue; /* vendor-unique error code */ + volatile unchar status; /* returned (icmb) status */ + volatile unchar phase; /* used by interrupt handler */ } IcbAny; typedef union icb { - unchar op; /* ICB opcode */ - IcbRecvCmd recv_cmd; /* format for receive command */ - IcbSendStat send_stat; /* format for send status */ - IcbRevLvl rev_lvl; /* format for get revision level */ - IcbDiag diag; /* format for execute diagnostics */ - IcbParms eparms; /* format for get/set exec parms */ - IcbAny icb; /* generic format */ - unchar data[18]; + unchar op; /* ICB opcode */ + IcbRecvCmd recv_cmd; /* format for receive command */ + IcbSendStat send_stat; /* format for send status */ + IcbRevLvl rev_lvl; /* format for get revision level */ + IcbDiag diag; /* format for execute diagnostics */ + IcbParms eparms; /* format for get/set exec parms */ + IcbAny icb; /* generic format */ + unchar data[18]; } Icb; #ifdef MODULE @@ -586,22 +582,19 @@ MODULE_PARM(wd7000, "s"); static Scb scbs[MAX_SCBS]; static Scb *scbfree; /* free list */ static int freescbs = MAX_SCBS; /* free list counter */ -static spinlock_t scbpool_lock; /* guards the scb free list and count */ +static spinlock_t scbpool_lock; /* guards the scb free list and count */ /* * END of data/declarations - code follows. */ static void __init setup_error(char *mesg, int *ints) { - if (ints[0] == 3) - printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x\" -> %s\n", - ints[1], ints[2], ints[3], mesg); - else if (ints[0] == 4) - printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d\" -> %s\n", - ints[1], ints[2], ints[3], ints[4], mesg); - else - printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d,%d\" -> %s\n", - ints[1], ints[2], ints[3], ints[4], ints[5], mesg); + if (ints[0] == 3) + printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x\" -> %s\n", ints[1], ints[2], ints[3], mesg); + else if (ints[0] == 4) + printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d\" -> %s\n", ints[1], ints[2], ints[3], ints[4], mesg); + else + printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d,%d\" -> %s\n", ints[1], ints[2], ints[3], ints[4], ints[5], mesg); } @@ -621,23 +614,19 @@ static void __init setup_error(char *mesg, int *ints) */ static int __init wd7000_setup(char *str) { - static short wd7000_card_num; /* .bss will zero this */ + static short wd7000_card_num; /* .bss will zero this */ short i; int ints[6]; - (void)get_options(str, ARRAY_SIZE(ints), ints); + (void) get_options(str, ARRAY_SIZE(ints), ints); if (wd7000_card_num >= NUM_CONFIGS) { - printk(KERN_ERR - "%s: Too many \"wd7000=\" configurations in " - "command line!\n", __FUNCTION__); + printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __FUNCTION__); return 0; } if ((ints[0] < 3) || (ints[0] > 5)) { - printk(KERN_ERR "%s: Error in command line! " - "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" - "[,<BUS_OFF>]]\n", __FUNCTION__); + printk(KERN_ERR "%s: Error in command line! " "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" "[,<BUS_OFF>]]\n", __FUNCTION__); } else { for (i = 0; i < NUM_IRQS; i++) if (ints[1] == wd7000_irq[i]) @@ -671,8 +660,7 @@ static int __init wd7000_setup(char *str) if (ints[0] > 3) { if ((ints[4] < 500) || (ints[4] > 31875)) { - setup_error("BUS_ON value is out of range (500" - " to 31875 nanoseconds)!", ints); + setup_error("BUS_ON value is out of range (500" " to 31875 nanoseconds)!", ints); configs[wd7000_card_num].bus_on = BUS_ON; } else configs[wd7000_card_num].bus_on = ints[4] / 125; @@ -681,12 +669,10 @@ static int __init wd7000_setup(char *str) if (ints[0] > 4) { if ((ints[5] < 500) || (ints[5] > 31875)) { - setup_error("BUS_OFF value is out of range (500" - " to 31875 nanoseconds)!", ints); + setup_error("BUS_OFF value is out of range (500" " to 31875 nanoseconds)!", ints); configs[wd7000_card_num].bus_off = BUS_OFF; } else - configs[wd7000_card_num].bus_off = ints[5] / - 125; + configs[wd7000_card_num].bus_off = ints[5] / 125; } else configs[wd7000_card_num].bus_off = BUS_OFF; @@ -696,32 +682,22 @@ static int __init wd7000_setup(char *str) for (; j < wd7000_card_num; j++) if (configs[i].irq == configs[j].irq) { - setup_error("duplicated IRQ!", - ints); - return 0; - } - if (configs[i].dma == configs[j].dma) { - setup_error("duplicated DMA " - "channel!", ints); - return 0; - } - if (configs[i].iobase == - configs[j].iobase) { - setup_error("duplicated I/O " - "base address!", - ints); + setup_error("duplicated IRQ!", ints); return 0; } + if (configs[i].dma == configs[j].dma) { + setup_error("duplicated DMA " "channel!", ints); + return 0; + } + if (configs[i].iobase == configs[j].iobase) { + setup_error("duplicated I/O " "base address!", ints); + return 0; + } } } dprintk(KERN_DEBUG "wd7000_setup: IRQ=%d, DMA=%d, I/O=0x%x, " - "BUS_ON=%dns, BUS_OFF=%dns\n", - configs[wd7000_card_num].irq, - configs[wd7000_card_num].dma, - configs[wd7000_card_num].iobase, - configs[wd7000_card_num].bus_on * 125, - configs[wd7000_card_num].bus_off * 125); + "BUS_ON=%dns, BUS_OFF=%dns\n", configs[wd7000_card_num].irq, configs[wd7000_card_num].dma, configs[wd7000_card_num].iobase, configs[wd7000_card_num].bus_on * 125, configs[wd7000_card_num].bus_off * 125); wd7000_card_num++; } @@ -740,29 +716,29 @@ __setup("wd7000=", wd7000_setup); * (They were simply 4-byte versions of these routines). */ typedef union { /* let's cheat... */ - int i; - unchar u[sizeof (int)]; /* the sizeof(int) makes it more portable */ + int i; + unchar u[sizeof(int)]; /* the sizeof(int) makes it more portable */ } i_u; -static inline void any2scsi (unchar * scsi, int any) +static inline void any2scsi(unchar * scsi, int any) { - *scsi++ = ((i_u) any).u[2]; - *scsi++ = ((i_u) any).u[1]; - *scsi++ = ((i_u) any).u[0]; + *scsi++ = ((i_u) any).u[2]; + *scsi++ = ((i_u) any).u[1]; + *scsi++ = ((i_u) any).u[0]; } -static inline int scsi2int (unchar * scsi) +static inline int scsi2int(unchar * scsi) { - i_u result; + i_u result; - result.i = 0; /* clears unused bytes */ - result.u[2] = *scsi++; - result.u[1] = *scsi++; - result.u[0] = *scsi++; + result.i = 0; /* clears unused bytes */ + result.u[2] = *scsi++; + result.u[1] = *scsi++; + result.u[0] = *scsi++; - return (result.i); + return (result.i); } #else /* @@ -780,63 +756,63 @@ static inline int scsi2int (unchar * scsi) #endif -static inline void wd7000_enable_intr (Adapter *host) +static inline void wd7000_enable_intr(Adapter * host) { - host->control |= INT_EN; - outb (host->control, host->iobase + ASC_CONTROL); + host->control |= INT_EN; + outb(host->control, host->iobase + ASC_CONTROL); } -static inline void wd7000_enable_dma (Adapter *host) +static inline void wd7000_enable_dma(Adapter * host) { - unsigned long flags; - host->control |= DMA_EN; - outb (host->control, host->iobase + ASC_CONTROL); - - flags = claim_dma_lock(); - set_dma_mode (host->dma, DMA_MODE_CASCADE); - enable_dma (host->dma); - release_dma_lock(flags); - + unsigned long flags; + host->control |= DMA_EN; + outb(host->control, host->iobase + ASC_CONTROL); + + flags = claim_dma_lock(); + set_dma_mode(host->dma, DMA_MODE_CASCADE); + enable_dma(host->dma); + release_dma_lock(flags); + } #define WAITnexttimeout 200 /* 2 seconds */ -static inline short WAIT (unsigned port, unsigned mask, unsigned allof, unsigned noneof) +static inline short WAIT(unsigned port, unsigned mask, unsigned allof, unsigned noneof) { - register unsigned WAITbits; - register unsigned long WAITtimeout = jiffies + WAITnexttimeout; + register unsigned WAITbits; + register unsigned long WAITtimeout = jiffies + WAITnexttimeout; - while (time_before_eq(jiffies, WAITtimeout)) { - WAITbits = inb (port) & mask; + while (time_before_eq(jiffies, WAITtimeout)) { + WAITbits = inb(port) & mask; - if (((WAITbits & allof) == allof) && ((WAITbits & noneof) == 0)) - return (0); - } + if (((WAITbits & allof) == allof) && ((WAITbits & noneof) == 0)) + return (0); + } - return (1); + return (1); } -static inline int command_out (Adapter * host, unchar * cmd, int len) +static inline int command_out(Adapter * host, unchar * cmd, int len) { - if (!WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { - while (len--) { - do { - outb (*cmd, host->iobase + ASC_COMMAND); - WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0); - } while (inb (host->iobase + ASC_STAT) & CMD_REJ); - - cmd++; - } + if (!WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { + while (len--) { + do { + outb(*cmd, host->iobase + ASC_COMMAND); + WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0); + } while (inb(host->iobase + ASC_STAT) & CMD_REJ); + + cmd++; + } - return (1); - } + return (1); + } - printk(KERN_WARNING "wd7000 command_out: WAIT failed(%d)\n", len + 1); + printk(KERN_WARNING "wd7000 command_out: WAIT failed(%d)\n", len + 1); - return (0); + return (0); } @@ -852,654 +828,645 @@ static inline int command_out (Adapter * host, unchar * cmd, int len) */ static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed) { - register Scb *scb, *p = NULL; - register unsigned long flags; - register unsigned long timeout = jiffies + WAITnexttimeout; - register unsigned long now; - int i; - - if (needed <= 0) - return (NULL); /* sanity check */ - - spin_unlock_irq(host->host_lock); - -retry: - while (freescbs < needed) { - timeout = jiffies + WAITnexttimeout; - do { - /* FIXME: can we actually just yield here ?? */ - for (now = jiffies; now == jiffies; ) - cpu_relax(); /* wait a jiffy */ - } while (freescbs < needed && time_before_eq(jiffies, timeout)); - /* - * If we get here with enough free Scbs, we can take them. - * Otherwise, we timed out and didn't get enough. - */ + register Scb *scb, *p = NULL; + register unsigned long flags; + register unsigned long timeout = jiffies + WAITnexttimeout; + register unsigned long now; + int i; + + if (needed <= 0) + return (NULL); /* sanity check */ + + spin_unlock_irq(host->host_lock); + + retry: + while (freescbs < needed) { + timeout = jiffies + WAITnexttimeout; + do { + /* FIXME: can we actually just yield here ?? */ + for (now = jiffies; now == jiffies;) + cpu_relax(); /* wait a jiffy */ + } while (freescbs < needed && time_before_eq(jiffies, timeout)); + /* + * If we get here with enough free Scbs, we can take them. + * Otherwise, we timed out and didn't get enough. + */ + if (freescbs < needed) { + printk(KERN_ERR "wd7000: can't get enough free SCBs.\n"); + return (NULL); + } + } + + /* Take the lock, then check we didnt get beaten, if so try again */ + spin_lock_irqsave(&scbpool_lock, flags); if (freescbs < needed) { - printk (KERN_ERR "wd7000: can't get enough free SCBs.\n"); - return (NULL); + spin_unlock_irqrestore(&scbpool_lock, flags); + goto retry; } - } - - /* Take the lock, then check we didnt get beaten, if so try again */ - spin_lock_irqsave(&scbpool_lock, flags); - if(freescbs < needed) - { - spin_unlock_irqrestore(&scbpool_lock, flags); - goto retry; - } - - scb = scbfree; - freescbs -= needed; - for (i = 0; i < needed; i++) { - p = scbfree; - scbfree = p->next; - } - p->next = NULL; - - spin_unlock_irqrestore(&scbpool_lock, flags); - - spin_lock_irq(host->host_lock); - return (scb); + + scb = scbfree; + freescbs -= needed; + for (i = 0; i < needed; i++) { + p = scbfree; + scbfree = p->next; + } + p->next = NULL; + + spin_unlock_irqrestore(&scbpool_lock, flags); + + spin_lock_irq(host->host_lock); + return (scb); } -static inline void free_scb (Scb *scb) +static inline void free_scb(Scb * scb) { - register unsigned long flags; + register unsigned long flags; - spin_lock_irqsave(&scbpool_lock, flags); + spin_lock_irqsave(&scbpool_lock, flags); - memset (scb, 0, sizeof (Scb)); - scb->next = scbfree; - scbfree = scb; - freescbs++; + memset(scb, 0, sizeof(Scb)); + scb->next = scbfree; + scbfree = scb; + freescbs++; - spin_unlock_irqrestore(&scbpool_lock, flags); + spin_unlock_irqrestore(&scbpool_lock, flags); } -static inline void init_scbs (void) +static inline void init_scbs(void) { - int i; - - spin_lock_init(&scbpool_lock); - - /* This is only ever called before the SCB pool is active */ - - scbfree = &(scbs[0]); - memset (scbs, 0, sizeof (scbs)); - for (i = 0; i < MAX_SCBS - 1; i++) { - scbs[i].next = &(scbs[i + 1]); - scbs[i].SCpnt = NULL; - } - scbs[MAX_SCBS - 1].next = NULL; - scbs[MAX_SCBS - 1].SCpnt = NULL; + int i; + + spin_lock_init(&scbpool_lock); + + /* This is only ever called before the SCB pool is active */ + + scbfree = &(scbs[0]); + memset(scbs, 0, sizeof(scbs)); + for (i = 0; i < MAX_SCBS - 1; i++) { + scbs[i].next = &(scbs[i + 1]); + scbs[i].SCpnt = NULL; + } + scbs[MAX_SCBS - 1].next = NULL; + scbs[MAX_SCBS - 1].SCpnt = NULL; } -static int mail_out (Adapter *host, Scb *scbptr) +static int mail_out(Adapter * host, Scb * scbptr) /* * Note: this can also be used for ICBs; just cast to the parm type. */ { - register int i, ogmb; - register unsigned long flags; - unchar start_ogmb; - Mailbox *ogmbs = host->mb.ogmb; - int *next_ogmb = &(host->next_ogmb); - - dprintk("wd7000_mail_out: 0x%06lx", (long) scbptr); - - /* We first look for a free outgoing mailbox */ - spin_lock_irqsave(host->sh->host_lock, flags); - ogmb = *next_ogmb; - for (i = 0; i < OGMB_CNT; i++) { - if (ogmbs[ogmb].status == 0) { - dprintk(" using OGMB 0x%x", ogmb); - ogmbs[ogmb].status = 1; - any2scsi ((unchar *) ogmbs[ogmb].scbptr, (int) scbptr); - - *next_ogmb = (ogmb + 1) % OGMB_CNT; - break; + register int i, ogmb; + register unsigned long flags; + unchar start_ogmb; + Mailbox *ogmbs = host->mb.ogmb; + int *next_ogmb = &(host->next_ogmb); + + dprintk("wd7000_mail_out: 0x%06lx", (long) scbptr); + + /* We first look for a free outgoing mailbox */ + spin_lock_irqsave(host->sh->host_lock, flags); + ogmb = *next_ogmb; + for (i = 0; i < OGMB_CNT; i++) { + if (ogmbs[ogmb].status == 0) { + dprintk(" using OGMB 0x%x", ogmb); + ogmbs[ogmb].status = 1; + any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr); + + *next_ogmb = (ogmb + 1) % OGMB_CNT; + break; + } else + ogmb = (ogmb + 1) % OGMB_CNT; } - else - ogmb = (ogmb + 1) % OGMB_CNT; - } - spin_unlock_irqrestore(host->sh->host_lock, flags); - - dprintk(", scb is 0x%06lx", (long) scbptr); + spin_unlock_irqrestore(host->sh->host_lock, flags); - if (i >= OGMB_CNT) { - /* - * Alternatively, we might issue the "interrupt on free OGMB", - * and sleep, but it must be ensured that it isn't the init - * task running. Instead, this version assumes that the caller - * will be persistent, and try again. Since it's the adapter - * that marks OGMB's free, waiting even with interrupts off - * should work, since they are freed very quickly in most cases. - */ - dprintk(", no free OGMBs.\n"); - return (0); - } + dprintk(", scb is 0x%06lx", (long) scbptr); - wd7000_enable_intr (host); + if (i >= OGMB_CNT) { + /* + * Alternatively, we might issue the "interrupt on free OGMB", + * and sleep, but it must be ensured that it isn't the init + * task running. Instead, this version assumes that the caller + * will be persistent, and try again. Since it's the adapter + * that marks OGMB's free, waiting even with interrupts off + * should work, since they are freed very quickly in most cases. + */ + dprintk(", no free OGMBs.\n"); + return (0); + } - start_ogmb = START_OGMB | ogmb; - command_out (host, &start_ogmb, 1); + wd7000_enable_intr(host); - dprintk(", awaiting interrupt.\n"); + start_ogmb = START_OGMB | ogmb; + command_out(host, &start_ogmb, 1); - return (1); + dprintk(", awaiting interrupt.\n"); + + return (1); } -static int make_code (unsigned hosterr, unsigned scsierr) +static int make_code(unsigned hosterr, unsigned scsierr) { #ifdef WD7000_DEBUG - int in_error = hosterr; + int in_error = hosterr; #endif - switch ((hosterr >> 8) & 0xff) { - case 0: /* Reserved */ - hosterr = DID_ERROR; - break; - case 1: /* Command Complete, no errors */ - hosterr = DID_OK; - break; - case 2: /* Command complete, error logged in scb status (scsierr) */ - hosterr = DID_OK; - break; - case 4: /* Command failed to complete - timeout */ - hosterr = DID_TIME_OUT; - break; - case 5: /* Command terminated; Bus reset by external device */ - hosterr = DID_RESET; - break; - case 6: /* Unexpected Command Received w/ host as target */ - hosterr = DID_BAD_TARGET; - break; - case 80: /* Unexpected Reselection */ - case 81: /* Unexpected Selection */ - hosterr = DID_BAD_INTR; - break; - case 82: /* Abort Command Message */ - hosterr = DID_ABORT; - break; - case 83: /* SCSI Bus Software Reset */ - case 84: /* SCSI Bus Hardware Reset */ - hosterr = DID_RESET; - break; - default: /* Reserved */ - hosterr = DID_ERROR; - } + switch ((hosterr >> 8) & 0xff) { + case 0: /* Reserved */ + hosterr = DID_ERROR; + break; + case 1: /* Command Complete, no errors */ + hosterr = DID_OK; + break; + case 2: /* Command complete, error logged in scb status (scsierr) */ + hosterr = DID_OK; + break; + case 4: /* Command failed to complete - timeout */ + hosterr = DID_TIME_OUT; + break; + case 5: /* Command terminated; Bus reset by external device */ + hosterr = DID_RESET; + break; + case 6: /* Unexpected Command Received w/ host as target */ + hosterr = DID_BAD_TARGET; + break; + case 80: /* Unexpected Reselection */ + case 81: /* Unexpected Selection */ + hosterr = DID_BAD_INTR; + break; + case 82: /* Abort Command Message */ + hosterr = DID_ABORT; + break; + case 83: /* SCSI Bus Software Reset */ + case 84: /* SCSI Bus Hardware Reset */ + hosterr = DID_RESET; + break; + default: /* Reserved */ + hosterr = DID_ERROR; + } #ifdef WD7000_DEBUG - if (scsierr || hosterr) - dprintk("\nSCSI command error: SCSI 0x%02x host 0x%04x return %d\n", - scsierr, in_error, hosterr); + if (scsierr || hosterr) + dprintk("\nSCSI command error: SCSI 0x%02x host 0x%04x return %d\n", scsierr, in_error, hosterr); #endif - return (scsierr | (hosterr << 16)); + return (scsierr | (hosterr << 16)); } -static void wd7000_scsi_done (Scsi_Cmnd *SCpnt) +static void wd7000_scsi_done(Scsi_Cmnd * SCpnt) { - dprintk("wd7000_scsi_done: 0x%06lx\n", (long)SCpnt); - SCpnt->SCp.phase = 0; + dprintk("wd7000_scsi_done: 0x%06lx\n", (long) SCpnt); + SCpnt->SCp.phase = 0; } #define wd7000_intr_ack(host) outb (0, host->iobase + ASC_INTR_ACK) -static void wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs) +static void wd7000_intr_handle(int irq, void *dev_id, struct pt_regs *regs) { - register int flag, icmb, errstatus, icmb_status; - register int host_error, scsi_error; - register Scb *scb; /* for SCSI commands */ - register IcbAny *icb; /* for host commands */ - register Scsi_Cmnd *SCpnt; - Adapter *host = (Adapter *)dev_id; - Mailbox *icmbs = host->mb.icmb; - - host->int_counter++; - - dprintk("wd7000_intr_handle: irq = %d, host = 0x%06lx\n", irq, (long) host); - - flag = inb (host->iobase + ASC_INTR_STAT); - - dprintk("wd7000_intr_handle: intr stat = 0x%02x\n", flag); - - if (!(inb (host->iobase + ASC_STAT) & INT_IM)) { - /* NB: these are _very_ possible if IRQ 15 is being used, since - * it's the "garbage collector" on the 2nd 8259 PIC. Specifically, - * any interrupt signal into the 8259 which can't be identified - * comes out as 7 from the 8259, which is 15 to the host. Thus, it - * is a good thing the WD7000 has an interrupt status port, so we - * can sort these out. Otherwise, electrical noise and other such - * problems would be indistinguishable from valid interrupts... - */ - dprintk("wd7000_intr_handle: phantom interrupt...\n"); - wd7000_intr_ack (host); - return; - } - - if (flag & MB_INTR) { - /* The interrupt is for a mailbox */ - if (!(flag & IMB_INTR)) { - dprintk("wd7000_intr_handle: free outgoing mailbox\n"); - /* - * If sleep_on() and the "interrupt on free OGMB" command are - * used in mail_out(), wake_up() should correspondingly be called - * here. For now, we don't need to do anything special. - */ - wd7000_intr_ack (host); - return; - } - else { - /* The interrupt is for an incoming mailbox */ - icmb = flag & MB_MASK; - icmb_status = icmbs[icmb].status; - if (icmb_status & 0x80) { /* unsolicited - result in ICMB */ - dprintk("wd7000_intr_handle: unsolicited interrupt 0x%02x\n", - icmb_status); - wd7000_intr_ack (host); + register int flag, icmb, errstatus, icmb_status; + register int host_error, scsi_error; + register Scb *scb; /* for SCSI commands */ + register IcbAny *icb; /* for host commands */ + register Scsi_Cmnd *SCpnt; + Adapter *host = (Adapter *) dev_id; + Mailbox *icmbs = host->mb.icmb; + + host->int_counter++; + + dprintk("wd7000_intr_handle: irq = %d, host = 0x%06lx\n", irq, (long) host); + + flag = inb(host->iobase + ASC_INTR_STAT); + + dprintk("wd7000_intr_handle: intr stat = 0x%02x\n", flag); + + if (!(inb(host->iobase + ASC_STAT) & INT_IM)) { + /* NB: these are _very_ possible if IRQ 15 is being used, since + * it's the "garbage collector" on the 2nd 8259 PIC. Specifically, + * any interrupt signal into the 8259 which can't be identified + * comes out as 7 from the 8259, which is 15 to the host. Thus, it + * is a good thing the WD7000 has an interrupt status port, so we + * can sort these out. Otherwise, electrical noise and other such + * problems would be indistinguishable from valid interrupts... + */ + dprintk("wd7000_intr_handle: phantom interrupt...\n"); + wd7000_intr_ack(host); return; - } - /* Aaaargh! (Zaga) */ - scb = isa_bus_to_virt(scsi2int ((unchar *) icmbs[icmb].scbptr)); - icmbs[icmb].status = 0; - if (!(scb->op & ICB_OP_MASK)) { /* an SCB is done */ - SCpnt = scb->SCpnt; - if (--(SCpnt->SCp.phase) <= 0) { /* all scbs are done */ - host_error = scb->vue | (icmb_status << 8); - scsi_error = scb->status; - errstatus = make_code (host_error, scsi_error); - SCpnt->result = errstatus; - - free_scb (scb); - - SCpnt->scsi_done (SCpnt); - } - } - else { /* an ICB is done */ - icb = (IcbAny *) scb; - icb->status = icmb_status; - icb->phase = 0; - } - } /* incoming mailbox */ - } - - wd7000_intr_ack (host); - - dprintk("wd7000_intr_handle: return from interrupt handler\n"); + } + + if (flag & MB_INTR) { + /* The interrupt is for a mailbox */ + if (!(flag & IMB_INTR)) { + dprintk("wd7000_intr_handle: free outgoing mailbox\n"); + /* + * If sleep_on() and the "interrupt on free OGMB" command are + * used in mail_out(), wake_up() should correspondingly be called + * here. For now, we don't need to do anything special. + */ + wd7000_intr_ack(host); + return; + } else { + /* The interrupt is for an incoming mailbox */ + icmb = flag & MB_MASK; + icmb_status = icmbs[icmb].status; + if (icmb_status & 0x80) { /* unsolicited - result in ICMB */ + dprintk("wd7000_intr_handle: unsolicited interrupt 0x%02x\n", icmb_status); + wd7000_intr_ack(host); + return; + } + /* Aaaargh! (Zaga) */ + scb = isa_bus_to_virt(scsi2int((unchar *) icmbs[icmb].scbptr)); + icmbs[icmb].status = 0; + if (!(scb->op & ICB_OP_MASK)) { /* an SCB is done */ + SCpnt = scb->SCpnt; + if (--(SCpnt->SCp.phase) <= 0) { /* all scbs are done */ + host_error = scb->vue | (icmb_status << 8); + scsi_error = scb->status; + errstatus = make_code(host_error, scsi_error); + SCpnt->result = errstatus; + + free_scb(scb); + + SCpnt->scsi_done(SCpnt); + } + } else { /* an ICB is done */ + icb = (IcbAny *) scb; + icb->status = icmb_status; + icb->phase = 0; + } + } /* incoming mailbox */ + } + + wd7000_intr_ack(host); + + dprintk("wd7000_intr_handle: return from interrupt handler\n"); } -static void do_wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs) +static void do_wd7000_intr_handle(int irq, void *dev_id, struct pt_regs *regs) { - unsigned long flags; - struct Scsi_Host *host = dev_id; + unsigned long flags; + struct Scsi_Host *host = dev_id; - spin_lock_irqsave(host->host_lock, flags); - wd7000_intr_handle(irq, dev_id, regs); - spin_unlock_irqrestore(host->host_lock, flags); + spin_lock_irqsave(host->host_lock, flags); + wd7000_intr_handle(irq, dev_id, regs); + spin_unlock_irqrestore(host->host_lock, flags); } -static int wd7000_queuecommand (Scsi_Cmnd *SCpnt, void (*done) (Scsi_Cmnd *)) +static int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) { - register Scb *scb; - register Sgb *sgb; - register unchar *cdb = (unchar *) SCpnt->cmnd; - register unchar idlun; - register short cdblen; - Adapter *host = (Adapter *) SCpnt->host->hostdata; - - cdblen = SCpnt->cmd_len; - idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7); - SCpnt->scsi_done = done; - SCpnt->SCp.phase = 1; - scb = alloc_scbs(SCpnt->host, 1); - scb->idlun = idlun; - memcpy (scb->cdb, cdb, cdblen); - scb->direc = 0x40; /* Disable direction check */ - - scb->SCpnt = SCpnt; /* so we can find stuff later */ - SCpnt->host_scribble = (unchar *) scb; - scb->host = host; - - if (SCpnt->use_sg) { - struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer; - unsigned i; - - if (SCpnt->host->sg_tablesize == SG_NONE) { - panic ("wd7000_queuecommand: scatter/gather not supported.\n"); - } - dprintk ("Using scatter/gather with %d elements.\n", SCpnt->use_sg); + register Scb *scb; + register Sgb *sgb; + register unchar *cdb = (unchar *) SCpnt->cmnd; + register unchar idlun; + register short cdblen; + Adapter *host = (Adapter *) SCpnt->host->hostdata; + + cdblen = SCpnt->cmd_len; + idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7); + SCpnt->scsi_done = done; + SCpnt->SCp.phase = 1; + scb = alloc_scbs(SCpnt->host, 1); + scb->idlun = idlun; + memcpy(scb->cdb, cdb, cdblen); + scb->direc = 0x40; /* Disable direction check */ + + scb->SCpnt = SCpnt; /* so we can find stuff later */ + SCpnt->host_scribble = (unchar *) scb; + scb->host = host; + + if (SCpnt->use_sg) { + struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer; + unsigned i; + + if (SCpnt->host->sg_tablesize == SG_NONE) { + panic("wd7000_queuecommand: scatter/gather not supported.\n"); + } + dprintk("Using scatter/gather with %d elements.\n", SCpnt->use_sg); - sgb = scb->sgb; - scb->op = 1; - any2scsi (scb->dataptr, (int) sgb); - any2scsi (scb->maxlen, SCpnt->use_sg * sizeof (Sgb)); + sgb = scb->sgb; + scb->op = 1; + any2scsi(scb->dataptr, (int) sgb); + any2scsi(scb->maxlen, SCpnt->use_sg * sizeof(Sgb)); - for (i = 0; i < SCpnt->use_sg; i++) { - any2scsi (sgb[i].ptr, - isa_page_to_bus(sg[i].page) + sg[i].offset); - any2scsi (sgb[i].len, sg[i].length); + for (i = 0; i < SCpnt->use_sg; i++) { + any2scsi(sgb[i].ptr, isa_page_to_bus(sg[i].page) + sg[i].offset); + any2scsi(sgb[i].len, sg[i].length); + } + } else { + scb->op = 0; + any2scsi(scb->dataptr, isa_virt_to_bus(SCpnt->request_buffer)); + any2scsi(scb->maxlen, SCpnt->request_bufflen); } - } - else { - scb->op = 0; - any2scsi (scb->dataptr, isa_virt_to_bus(SCpnt->request_buffer)); - any2scsi (scb->maxlen, SCpnt->request_bufflen); - } - - /* FIXME: drop lock and yield here ? */ - - while (!mail_out (host, scb)) - cpu_relax(); /* keep trying */ - - return 0; + + /* FIXME: drop lock and yield here ? */ + + while (!mail_out(host, scb)) + cpu_relax(); /* keep trying */ + + return 0; } -static int wd7000_command (Scsi_Cmnd *SCpnt) +static int wd7000_command(Scsi_Cmnd * SCpnt) { - wd7000_queuecommand (SCpnt, wd7000_scsi_done); + wd7000_queuecommand(SCpnt, wd7000_scsi_done); - while (SCpnt->SCp.phase > 0) - { - cpu_relax(); - barrier(); /* phase counts scbs down to 0 */ - } + while (SCpnt->SCp.phase > 0) { + cpu_relax(); + barrier(); /* phase counts scbs down to 0 */ + } - return (SCpnt->result); + return (SCpnt->result); } -static int wd7000_diagnostics (Adapter *host, int code) +static int wd7000_diagnostics(Adapter * host, int code) { - static IcbDiag icb = {ICB_OP_DIAGNOSTICS}; - static unchar buf[256]; - unsigned long timeout; - - icb.type = code; - any2scsi (icb.len, sizeof (buf)); - any2scsi (icb.ptr, (int) &buf); - icb.phase = 1; - /* - * This routine is only called at init, so there should be OGMBs - * available. I'm assuming so here. If this is going to - * fail, I can just let the timeout catch the failure. - */ - mail_out (host, (struct scb *) &icb); - timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */ - while (icb.phase && time_before(jiffies, timeout)) - { - cpu_relax(); /* wait for completion */ - barrier(); - } - - if (icb.phase) { - printk ("wd7000_diagnostics: timed out.\n"); - return (0); - } - if (make_code (icb.vue | (icb.status << 8), 0)) { - printk ("wd7000_diagnostics: failed (0x%02x,0x%02x)\n", - icb.vue, icb.status); - return (0); - } + static IcbDiag icb = { ICB_OP_DIAGNOSTICS }; + static unchar buf[256]; + unsigned long timeout; + + icb.type = code; + any2scsi(icb.len, sizeof(buf)); + any2scsi(icb.ptr, (int) &buf); + icb.phase = 1; + /* + * This routine is only called at init, so there should be OGMBs + * available. I'm assuming so here. If this is going to + * fail, I can just let the timeout catch the failure. + */ + mail_out(host, (struct scb *) &icb); + timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */ + while (icb.phase && time_before(jiffies, timeout)) { + cpu_relax(); /* wait for completion */ + barrier(); + } + + if (icb.phase) { + printk("wd7000_diagnostics: timed out.\n"); + return (0); + } + if (make_code(icb.vue | (icb.status << 8), 0)) { + printk("wd7000_diagnostics: failed (0x%02x,0x%02x)\n", icb.vue, icb.status); + return (0); + } - return (1); + return (1); } -static int wd7000_adapter_reset(Adapter *host) +static int wd7000_adapter_reset(Adapter * host) { - InitCmd init_cmd = - { - INITIALIZATION, - 7, - host->bus_on, - host->bus_off, - 0, - { 0, 0, 0 }, - OGMB_CNT, - ICMB_CNT - }; - int diag; - /* - * Reset the adapter - only. The SCSI bus was initialized at power-up, - * and we need to do this just so we control the mailboxes, etc. - */ - outb (ASC_RES, host->iobase + ASC_CONTROL); - udelay(40); /* reset pulse: this is 40us, only need 25us */ - outb (0, host->iobase + ASC_CONTROL); - host->control = 0; /* this must always shadow ASC_CONTROL */ - - if (WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { - printk ("wd7000_init: WAIT timed out.\n"); - return -1; /* -1 = not ok */ - } - - if ((diag = inb (host->iobase + ASC_INTR_STAT)) != 1) { - printk ("wd7000_init: "); - - switch (diag) { - case 2: printk ("RAM failure.\n"); - break; - case 3: printk ("FIFO R/W failed\n"); - break; - case 4: printk ("SBIC register R/W failed\n"); - break; - case 5: printk ("Initialization D-FF failed.\n"); - break; - case 6: printk ("Host IRQ D-FF failed.\n"); - break; - case 7: printk ("ROM checksum error.\n"); - break; - default: printk ("diagnostic code 0x%02Xh received.\n", diag); + InitCmd init_cmd = { + INITIALIZATION, + 7, + host->bus_on, + host->bus_off, + 0, + {0, 0, 0}, + OGMB_CNT, + ICMB_CNT + }; + int diag; + /* + * Reset the adapter - only. The SCSI bus was initialized at power-up, + * and we need to do this just so we control the mailboxes, etc. + */ + outb(ASC_RES, host->iobase + ASC_CONTROL); + udelay(40); /* reset pulse: this is 40us, only need 25us */ + outb(0, host->iobase + ASC_CONTROL); + host->control = 0; /* this must always shadow ASC_CONTROL */ + + if (WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { + printk("wd7000_init: WAIT timed out.\n"); + return -1; /* -1 = not ok */ + } + + if ((diag = inb(host->iobase + ASC_INTR_STAT)) != 1) { + printk("wd7000_init: "); + + switch (diag) { + case 2: + printk("RAM failure.\n"); + break; + case 3: + printk("FIFO R/W failed\n"); + break; + case 4: + printk("SBIC register R/W failed\n"); + break; + case 5: + printk("Initialization D-FF failed.\n"); + break; + case 6: + printk("Host IRQ D-FF failed.\n"); + break; + case 7: + printk("ROM checksum error.\n"); + break; + default: + printk("diagnostic code 0x%02Xh received.\n", diag); + } + return -1; + } + /* Clear mailboxes */ + memset(&(host->mb), 0, sizeof(host->mb)); + + /* Execute init command */ + any2scsi((unchar *) & (init_cmd.mailboxes), (int) &(host->mb)); + if (!command_out(host, (unchar *) & init_cmd, sizeof(init_cmd))) { + printk(KERN_ERR "wd7000_adapter_reset: adapter initialization failed.\n"); + return -1; + } + + if (WAIT(host->iobase + ASC_STAT, ASC_STATMASK, ASC_INIT, 0)) { + printk("wd7000_adapter_reset: WAIT timed out.\n"); + return -1; } - return -1; - } - /* Clear mailboxes */ - memset (&(host->mb), 0, sizeof (host->mb)); - - /* Execute init command */ - any2scsi ((unchar *) & (init_cmd.mailboxes), (int) &(host->mb)); - if (!command_out (host, (unchar *) &init_cmd, sizeof (init_cmd))) { - printk (KERN_ERR "wd7000_adapter_reset: adapter initialization failed.\n"); - return -1; - } - - if (WAIT (host->iobase + ASC_STAT, ASC_STATMASK, ASC_INIT, 0)) { - printk ("wd7000_adapter_reset: WAIT timed out.\n"); - return -1; - } - return 0; + return 0; } -static int wd7000_init (Adapter *host) +static int wd7000_init(Adapter * host) { - if(wd7000_adapter_reset(host) == -1) - return 0; + if (wd7000_adapter_reset(host) == -1) + return 0; - - if (request_irq (host->irq, do_wd7000_intr_handle, SA_INTERRUPT, "wd7000", host)) { - printk ("wd7000_init: can't get IRQ %d.\n", host->irq); - return (0); - } - if (request_dma (host->dma, "wd7000")) { - printk ("wd7000_init: can't get DMA channel %d.\n", host->dma); - free_irq (host->irq, host); - return (0); - } - wd7000_enable_dma (host); - wd7000_enable_intr (host); - if (!wd7000_diagnostics (host, ICB_DIAG_FULL)) { - free_dma (host->dma); - free_irq (host->irq, NULL); - return (0); - } + if (request_irq(host->irq, do_wd7000_intr_handle, SA_INTERRUPT, "wd7000", host)) { + printk("wd7000_init: can't get IRQ %d.\n", host->irq); + return (0); + } + if (request_dma(host->dma, "wd7000")) { + printk("wd7000_init: can't get DMA channel %d.\n", host->dma); + free_irq(host->irq, host); + return (0); + } + wd7000_enable_dma(host); + wd7000_enable_intr(host); - return (1); + if (!wd7000_diagnostics(host, ICB_DIAG_FULL)) { + free_dma(host->dma); + free_irq(host->irq, NULL); + return (0); + } + + return (1); } -static void wd7000_revision (Adapter *host) +static void wd7000_revision(Adapter * host) { - static IcbRevLvl icb = - {ICB_OP_GET_REVISION}; - - icb.phase = 1; - /* - * Like diagnostics, this is only done at init time, in fact, from - * wd7000_detect, so there should be OGMBs available. If it fails, - * the only damage will be that the revision will show up as 0.0, - * which in turn means that scatter/gather will be disabled. - */ - mail_out (host, (struct scb *) &icb); - while (icb.phase) - { - cpu_relax(); /* wait for completion */ - barrier(); - } - host->rev1 = icb.primary; - host->rev2 = icb.secondary; + static IcbRevLvl icb = { ICB_OP_GET_REVISION }; + + icb.phase = 1; + /* + * Like diagnostics, this is only done at init time, in fact, from + * wd7000_detect, so there should be OGMBs available. If it fails, + * the only damage will be that the revision will show up as 0.0, + * which in turn means that scatter/gather will be disabled. + */ + mail_out(host, (struct scb *) &icb); + while (icb.phase) { + cpu_relax(); /* wait for completion */ + barrier(); + } + host->rev1 = icb.primary; + host->rev2 = icb.secondary; } #undef SPRINTF #define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } -static int wd7000_set_info (char *buffer, int length, struct Scsi_Host *host) +static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host) { - dprintk("Buffer = <%.*s>, length = %d\n", length, buffer, length); + dprintk("Buffer = <%.*s>, length = %d\n", length, buffer, length); - /* - * Currently this is a no-op - */ - dprintk("Sorry, this function is currently out of order...\n"); - return (length); + /* + * Currently this is a no-op + */ + dprintk("Sorry, this function is currently out of order...\n"); + return (length); } -static int wd7000_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout) +static int wd7000_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout) { - struct Scsi_Host *host = NULL; - Scsi_Device *scd; - Adapter *adapter; - unsigned long flags; - char *pos = buffer; - short i; + struct Scsi_Host *host = NULL; + Scsi_Device *scd; + Adapter *adapter; + unsigned long flags; + char *pos = buffer; + short i; #ifdef WD7000_DEBUG - Mailbox *ogmbs, *icmbs; - short count; + Mailbox *ogmbs, *icmbs; + short count; #endif - /* - * Find the specified host board. - */ - for (i = 0; i < UNITS; i++) - if (wd7000_host[i] && (wd7000_host[i]->host_no == hostno)) { - host = wd7000_host[i]; + /* + * Find the specified host board. + */ + for (i = 0; i < UNITS; i++) + if (wd7000_host[i] && (wd7000_host[i]->host_no == hostno)) { + host = wd7000_host[i]; - break; - } + break; + } - /* - * Host not found! - */ - if (! host) - return (-ESRCH); - - /* - * Has data been written to the file ? - */ - if (inout) - return (wd7000_set_info (buffer, length, host)); - - adapter = (Adapter *) host->hostdata; - - spin_lock_irqsave(host->host_lock, flags); - SPRINTF ("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", hostno, adapter->rev1, adapter->rev2); - SPRINTF (" IO base: 0x%x\n", adapter->iobase); - SPRINTF (" IRQ: %d\n", adapter->irq); - SPRINTF (" DMA channel: %d\n", adapter->dma); - SPRINTF (" Interrupts: %d\n", adapter->int_counter); - SPRINTF (" BUS_ON time: %d nanoseconds\n", adapter->bus_on * 125); - SPRINTF (" BUS_OFF time: %d nanoseconds\n", adapter->bus_off * 125); + /* + * Host not found! + */ + if (!host) + return (-ESRCH); + + /* + * Has data been written to the file ? + */ + if (inout) + return (wd7000_set_info(buffer, length, host)); + + adapter = (Adapter *) host->hostdata; + + spin_lock_irqsave(host->host_lock, flags); + SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", hostno, adapter->rev1, adapter->rev2); + SPRINTF(" IO base: 0x%x\n", adapter->iobase); + SPRINTF(" IRQ: %d\n", adapter->irq); + SPRINTF(" DMA channel: %d\n", adapter->dma); + SPRINTF(" Interrupts: %d\n", adapter->int_counter); + SPRINTF(" BUS_ON time: %d nanoseconds\n", adapter->bus_on * 125); + SPRINTF(" BUS_OFF time: %d nanoseconds\n", adapter->bus_off * 125); #ifdef WD7000_DEBUG - ogmbs = adapter->mb.ogmb; - icmbs = adapter->mb.icmb; - - SPRINTF ("\nControl port value: 0x%x\n", adapter->control); - SPRINTF ("Incoming mailbox:\n"); - SPRINTF (" size: %d\n", ICMB_CNT); - SPRINTF (" queued messages: "); - - for (i = count = 0; i < ICMB_CNT; i++) - if (icmbs[i].status) { - count++; - SPRINTF ("0x%x ", i); - } + ogmbs = adapter->mb.ogmb; + icmbs = adapter->mb.icmb; + + SPRINTF("\nControl port value: 0x%x\n", adapter->control); + SPRINTF("Incoming mailbox:\n"); + SPRINTF(" size: %d\n", ICMB_CNT); + SPRINTF(" queued messages: "); + + for (i = count = 0; i < ICMB_CNT; i++) + if (icmbs[i].status) { + count++; + SPRINTF("0x%x ", i); + } - SPRINTF (count ? "\n" : "none\n"); + SPRINTF(count ? "\n" : "none\n"); - SPRINTF ("Outgoing mailbox:\n"); - SPRINTF (" size: %d\n", OGMB_CNT); - SPRINTF (" next message: 0x%x\n", adapter->next_ogmb); - SPRINTF (" queued messages: "); + SPRINTF("Outgoing mailbox:\n"); + SPRINTF(" size: %d\n", OGMB_CNT); + SPRINTF(" next message: 0x%x\n", adapter->next_ogmb); + SPRINTF(" queued messages: "); - for (i = count = 0; i < OGMB_CNT; i++) - if (ogmbs[i].status) { - count++; - SPRINTF ("0x%x ", i); - } + for (i = count = 0; i < OGMB_CNT; i++) + if (ogmbs[i].status) { + count++; + SPRINTF("0x%x ", i); + } - SPRINTF (count ? "\n" : "none\n"); + SPRINTF(count ? "\n" : "none\n"); #endif - /* - * Display driver information for each device attached to the board. - */ - scd = host->host_queue; - - SPRINTF ("\nAttached devices: %s\n", scd ? "" : "none"); - - for ( ; scd; scd = scd->next) - if (scd->host->host_no == hostno) { - SPRINTF (" [Channel: %02d, Id: %02d, Lun: %02d] ", - scd->channel, scd->id, scd->lun); - SPRINTF ("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? - scsi_device_types[(short) scd->type] : "Unknown device"); - - for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++) - SPRINTF ("%c", scd->vendor[i]); - SPRINTF (" "); - - for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++) - SPRINTF ("%c", scd->model[i]); - SPRINTF ("\n"); - } + /* + * Display driver information for each device attached to the board. + */ + scd = host->host_queue; - SPRINTF ("\n"); + SPRINTF("\nAttached devices: %s\n", scd ? "" : "none"); - spin_unlock_irqrestore(host->host_lock, flags); + for (; scd; scd = scd->next) + if (scd->host->host_no == hostno) { + SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel, scd->id, scd->lun); + SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(short) scd->type] : "Unknown device"); - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; + for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++) + SPRINTF("%c", scd->vendor[i]); + SPRINTF(" "); - if ((pos - buffer) < offset) - return (0); - else if ((pos - buffer - offset) < length) - return (pos - buffer - offset); - else - return (length); + for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++) + SPRINTF("%c", scd->model[i]); + SPRINTF("\n"); + } + + SPRINTF("\n"); + + spin_unlock_irqrestore(host->host_lock, flags); + + /* + * Calculate start of next buffer, and return value. + */ + *start = buffer + offset; + + if ((pos - buffer) < offset) + return (0); + else if ((pos - buffer - offset) < length) + return (pos - buffer - offset); + else + return (length); } @@ -1514,191 +1481,181 @@ static int wd7000_proc_info (char *buffer, char **start, off_t offset, int lengt * */ -static int wd7000_detect (Scsi_Host_Template *tpnt) +static int wd7000_detect(Scsi_Host_Template * tpnt) { - short present = 0, biosaddr_ptr, sig_ptr, i, pass; - short biosptr[NUM_CONFIGS]; - unsigned iobase; - Adapter *host = NULL; - struct Scsi_Host *sh; - int unit = 0; + short present = 0, biosaddr_ptr, sig_ptr, i, pass; + short biosptr[NUM_CONFIGS]; + unsigned iobase; + Adapter *host = NULL; + struct Scsi_Host *sh; + int unit = 0; - dprintk("wd7000_detect: started\n"); + dprintk("wd7000_detect: started\n"); #ifdef MODULE if (wd7000) - wd7000_setup(wd7000); + wd7000_setup(wd7000); #endif - for (i = 0; i < UNITS; wd7000_host[i++] = NULL) ; - for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1) ; - - tpnt->proc_name = "wd7000"; - tpnt->proc_info = &wd7000_proc_info; + for (i = 0; i < UNITS; wd7000_host[i++] = NULL); + for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1); - /* - * Set up SCB free list, which is shared by all adapters - */ - init_scbs (); + tpnt->proc_name = "wd7000"; + tpnt->proc_info = &wd7000_proc_info; - for (pass = 0; pass < NUM_CONFIGS; pass++) { /* - * First, search for BIOS SIGNATURE... + * Set up SCB free list, which is shared by all adapters */ - for (biosaddr_ptr = 0; biosaddr_ptr < NUM_ADDRS; biosaddr_ptr++) - for (sig_ptr = 0; sig_ptr < NUM_SIGNATURES; sig_ptr++) { - for (i = 0; i < pass; i++) - if (biosptr[i] == biosaddr_ptr) - break; - - if (i == pass) { - void *biosaddr = ioremap (wd7000_biosaddr[biosaddr_ptr] + - signatures[sig_ptr].ofs, - signatures[sig_ptr].len); - short bios_match=0; - - if(biosaddr) - bios_match = memcmp ((char *) biosaddr, signatures[sig_ptr].sig, - signatures[sig_ptr].len); - - iounmap (biosaddr); - - if (! bios_match) - goto bios_matched; - } - } - - bios_matched: - /* - * BIOS SIGNATURE has been found. - */ -#ifdef WD7000_DEBUG - dprintk("wd7000_detect: pass %d\n", pass + 1); + init_scbs(); - if (biosaddr_ptr == NUM_ADDRS) - dprintk("WD-7000 SST BIOS not detected...\n"); - else - dprintk("WD-7000 SST BIOS detected at 0x%lx: checking...\n", - wd7000_biosaddr[biosaddr_ptr]); -#endif - - if (configs[pass].irq < 0) - continue; - - if (unit == UNITS) - continue; - - iobase = configs[pass].iobase; + for (pass = 0; pass < NUM_CONFIGS; pass++) { + /* + * First, search for BIOS SIGNATURE... + */ + for (biosaddr_ptr = 0; biosaddr_ptr < NUM_ADDRS; biosaddr_ptr++) + for (sig_ptr = 0; sig_ptr < NUM_SIGNATURES; sig_ptr++) { + for (i = 0; i < pass; i++) + if (biosptr[i] == biosaddr_ptr) + break; - dprintk("wd7000_detect: check IO 0x%x region...\n", iobase); + if (i == pass) { + void *biosaddr = ioremap(wd7000_biosaddr[biosaddr_ptr] + signatures[sig_ptr].ofs, + signatures[sig_ptr].len); + short bios_match = 0; - if (request_region (iobase, 4, "wd7000")) { + if (biosaddr) + bios_match = memcmp((char *) biosaddr, signatures[sig_ptr].sig, signatures[sig_ptr].len); - dprintk("wd7000_detect: ASC reset (IO 0x%x) ...", iobase); - /* - * ASC reset... - */ - outb (ASC_RES, iobase + ASC_CONTROL); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/100); - outb (0, iobase + ASC_CONTROL); + iounmap(biosaddr); - if (WAIT (iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { - dprintk("failed!\n"); - goto err_release; - } else - dprintk("ok!\n"); + if (!bios_match) + goto bios_matched; + } + } - if (inb (iobase + ASC_INTR_STAT) == 1) { + bios_matched: /* - * We register here, to get a pointer to the extra space, - * which we'll use as the Adapter structure (host) for - * this adapter. It is located just after the registered - * Scsi_Host structure (sh), and is located by the empty - * array hostdata. + * BIOS SIGNATURE has been found. */ - sh = scsi_register (tpnt, sizeof (Adapter)); - if(sh==NULL) - goto err_release; - - host = (Adapter *) sh->hostdata; - - dprintk("wd7000_detect: adapter allocated at 0x%x\n", - (int)host); - memset (host, 0, sizeof (Adapter)); +#ifdef WD7000_DEBUG + dprintk("wd7000_detect: pass %d\n", pass + 1); - host->irq = configs[pass].irq; - host->dma = configs[pass].dma; - host->iobase = iobase; - host->int_counter = 0; - host->bus_on = configs[pass].bus_on; - host->bus_off = configs[pass].bus_off; - host->sh = wd7000_host[unit] = sh; - unit++; + if (biosaddr_ptr == NUM_ADDRS) + dprintk("WD-7000 SST BIOS not detected...\n"); + else + dprintk("WD-7000 SST BIOS detected at 0x%lx: checking...\n", wd7000_biosaddr[biosaddr_ptr]); +#endif - dprintk("wd7000_detect: Trying init WD-7000 card at IO " - "0x%x, IRQ %d, DMA %d...\n", - host->iobase, host->irq, host->dma); + if (configs[pass].irq < 0) + continue; - if (!wd7000_init (host)) /* Initialization failed */ - goto err_unregister; + if (unit == UNITS) + continue; - /* - * OK from here - we'll use this adapter/configuration. - */ - wd7000_revision (host); /* important for scatter/gather */ + iobase = configs[pass].iobase; - /* - * For boards before rev 6.0, scatter/gather isn't supported. - */ - if (host->rev1 < 6) - sh->sg_tablesize = SG_NONE; + dprintk("wd7000_detect: check IO 0x%x region...\n", iobase); - present++; /* count it */ + if (request_region(iobase, 4, "wd7000")) { - if (biosaddr_ptr != NUM_ADDRS) - biosptr[pass] = biosaddr_ptr; + dprintk("wd7000_detect: ASC reset (IO 0x%x) ...", iobase); + /* + * ASC reset... + */ + outb(ASC_RES, iobase + ASC_CONTROL); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 100); + outb(0, iobase + ASC_CONTROL); - printk (KERN_INFO "Western Digital WD-7000 (rev %d.%d) ", - host->rev1, host->rev2); - printk ("using IO 0x%x, IRQ %d, DMA %d.\n", - host->iobase, host->irq, host->dma); - printk (" BUS_ON time: %dns, BUS_OFF time: %dns\n", - host->bus_on * 125, host->bus_off * 125); - } - } else - dprintk("wd7000_detect: IO 0x%x region already allocated!\n", - iobase); + if (WAIT(iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) { + dprintk("failed!\n"); + goto err_release; + } else + dprintk("ok!\n"); + + if (inb(iobase + ASC_INTR_STAT) == 1) { + /* + * We register here, to get a pointer to the extra space, + * which we'll use as the Adapter structure (host) for + * this adapter. It is located just after the registered + * Scsi_Host structure (sh), and is located by the empty + * array hostdata. + */ + sh = scsi_register(tpnt, sizeof(Adapter)); + if (sh == NULL) + goto err_release; + + host = (Adapter *) sh->hostdata; + + dprintk("wd7000_detect: adapter allocated at 0x%x\n", (int) host); + memset(host, 0, sizeof(Adapter)); + + host->irq = configs[pass].irq; + host->dma = configs[pass].dma; + host->iobase = iobase; + host->int_counter = 0; + host->bus_on = configs[pass].bus_on; + host->bus_off = configs[pass].bus_off; + host->sh = wd7000_host[unit] = sh; + unit++; + + dprintk("wd7000_detect: Trying init WD-7000 card at IO " "0x%x, IRQ %d, DMA %d...\n", host->iobase, host->irq, host->dma); + + if (!wd7000_init(host)) /* Initialization failed */ + goto err_unregister; + + /* + * OK from here - we'll use this adapter/configuration. + */ + wd7000_revision(host); /* important for scatter/gather */ + + /* + * For boards before rev 6.0, scatter/gather isn't supported. + */ + if (host->rev1 < 6) + sh->sg_tablesize = SG_NONE; + + present++; /* count it */ + + if (biosaddr_ptr != NUM_ADDRS) + biosptr[pass] = biosaddr_ptr; + + printk(KERN_INFO "Western Digital WD-7000 (rev %d.%d) ", host->rev1, host->rev2); + printk("using IO 0x%x, IRQ %d, DMA %d.\n", host->iobase, host->irq, host->dma); + printk(" BUS_ON time: %dns, BUS_OFF time: %dns\n", host->bus_on * 125, host->bus_off * 125); + } + } else + dprintk("wd7000_detect: IO 0x%x region already allocated!\n", iobase); - continue; + continue; - err_unregister: - scsi_unregister (sh); - err_release: - release_region(iobase, 4); + err_unregister: + scsi_unregister(sh); + err_release: + release_region(iobase, 4); - } + } - if (!present) - printk ("Failed initialization of WD-7000 SCSI card!\n"); + if (!present) + printk("Failed initialization of WD-7000 SCSI card!\n"); - return (present); + return (present); } /* * I have absolutely NO idea how to do an abort with the WD7000... */ -static int wd7000_abort (Scsi_Cmnd *SCpnt) +static int wd7000_abort(Scsi_Cmnd * SCpnt) { - Adapter *host = (Adapter *) SCpnt->host->hostdata; + Adapter *host = (Adapter *) SCpnt->host->hostdata; - if (inb (host->iobase + ASC_STAT) & INT_IM) { - printk ("wd7000_abort: lost interrupt\n"); - wd7000_intr_handle (host->irq, NULL, NULL); + if (inb(host->iobase + ASC_STAT) & INT_IM) { + printk("wd7000_abort: lost interrupt\n"); + wd7000_intr_handle(host->irq, NULL, NULL); + return FAILED; + } return FAILED; - } - return FAILED; } @@ -1706,28 +1663,28 @@ static int wd7000_abort (Scsi_Cmnd *SCpnt) * I also have no idea how to do a reset... */ -static int wd7000_bus_reset (Scsi_Cmnd *SCpnt) +static int wd7000_bus_reset(Scsi_Cmnd * SCpnt) { - return FAILED; + return FAILED; } -static int wd7000_device_reset (Scsi_Cmnd *SCpnt) +static int wd7000_device_reset(Scsi_Cmnd * SCpnt) { - return FAILED; + return FAILED; } /* * Last resort. Reinitialize the board. */ - -static int wd7000_host_reset (Scsi_Cmnd *SCpnt) + +static int wd7000_host_reset(Scsi_Cmnd * SCpnt) { - Adapter *host = (Adapter *) SCpnt->host->hostdata; - - if(wd7000_adapter_reset(host)<0) - return FAILED; - wd7000_enable_intr (host); - return SUCCESS; + Adapter *host = (Adapter *) SCpnt->host->hostdata; + + if (wd7000_adapter_reset(host) < 0) + return FAILED; + wd7000_enable_intr(host); + return SUCCESS; } @@ -1735,52 +1692,46 @@ static int wd7000_host_reset (Scsi_Cmnd *SCpnt) * This was borrowed directly from aha1542.c. (Zaga) */ -static int wd7000_biosparam (Disk *disk, struct block_device *bdev, int *ip) +static int wd7000_biosparam(Disk * disk, struct block_device *bdev, int *ip) { - dprintk("wd7000_biosparam: dev=%s, size=%d, ", bdevname(bdev), - disk->capacity); - - /* - * try default translation - */ - ip[0] = 64; - ip[1] = 32; - ip[2] = disk->capacity >> 11; - - /* - * for disks >1GB do some guessing - */ - if (ip[2] >= 1024) { - int info[3]; + dprintk("wd7000_biosparam: dev=%s, size=%d, ", bdevname(bdev), disk->capacity); /* - * try to figure out the geometry from the partition table + * try default translation */ - if ((scsicam_bios_param (disk, bdev, info) < 0) || - !(((info[0] == 64) && (info[1] == 32)) || - ((info[0] == 255) && (info[1] == 63)))) { - printk ("wd7000_biosparam: unable to verify geometry for disk with >1GB.\n" - " using extended translation.\n"); - - ip[0] = 255; - ip[1] = 63; - ip[2] = (unsigned long)disk->capacity / (255 * 63); - } - else { - ip[0] = info[0]; - ip[1] = info[1]; - ip[2] = info[2]; - - if (info[0] == 255) - printk(KERN_INFO "%s: current partition table is " - "using extended translation.\n", __FUNCTION__); + ip[0] = 64; + ip[1] = 32; + ip[2] = disk->capacity >> 11; + + /* + * for disks >1GB do some guessing + */ + if (ip[2] >= 1024) { + int info[3]; + + /* + * try to figure out the geometry from the partition table + */ + if ((scsicam_bios_param(disk, bdev, info) < 0) || !(((info[0] == 64) && (info[1] == 32)) || ((info[0] == 255) && (info[1] == 63)))) { + printk("wd7000_biosparam: unable to verify geometry for disk with >1GB.\n" " using extended translation.\n"); + + ip[0] = 255; + ip[1] = 63; + ip[2] = (unsigned long) disk->capacity / (255 * 63); + } else { + ip[0] = info[0]; + ip[1] = info[1]; + ip[2] = info[2]; + + if (info[0] == 255) + printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __FUNCTION__); + } } - } - dprintk("bios geometry: head=%d, sec=%d, cyl=%d\n", ip[0], ip[1], ip[2]); - dprintk("WARNING: check, if the bios geometry is correct.\n"); + dprintk("bios geometry: head=%d, sec=%d, cyl=%d\n", ip[0], ip[1], ip[2]); + dprintk("WARNING: check, if the bios geometry is correct.\n"); - return (0); + return (0); } MODULE_AUTHOR("Thomas Wuensche, John Boyd, Miroslav Zagorac"); diff --git a/drivers/scsi/wd7000.h b/drivers/scsi/wd7000.h index 2a0467d84c77..6ea639ac10b0 100644 --- a/drivers/scsi/wd7000.h +++ b/drivers/scsi/wd7000.h @@ -13,16 +13,16 @@ #include <linux/types.h> -static int wd7000_set_info (char *buffer, int length, struct Scsi_Host *host); -static int wd7000_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout); -static int wd7000_detect (Scsi_Host_Template *); -static int wd7000_command (Scsi_Cmnd *); -static int wd7000_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -static int wd7000_abort (Scsi_Cmnd *); -static int wd7000_bus_reset (Scsi_Cmnd *); -static int wd7000_host_reset (Scsi_Cmnd *); -static int wd7000_device_reset (Scsi_Cmnd *); -static int wd7000_biosparam (Disk *, struct block_device *, int *); +static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host); +static int wd7000_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); +static int wd7000_detect(Scsi_Host_Template *); +static int wd7000_command(Scsi_Cmnd *); +static int wd7000_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); +static int wd7000_abort(Scsi_Cmnd *); +static int wd7000_bus_reset(Scsi_Cmnd *); +static int wd7000_host_reset(Scsi_Cmnd *); +static int wd7000_device_reset(Scsi_Cmnd *); +static int wd7000_biosparam(Disk *, struct block_device *, int *); #ifndef NULL #define NULL 0L diff --git a/include/asm-alpha/pal.h b/include/asm-alpha/pal.h index 510d13326de4..9b4ba0d6f00b 100644 --- a/include/asm-alpha/pal.h +++ b/include/asm-alpha/pal.h @@ -45,7 +45,7 @@ #define PAL_wrperfmon 57 #define PAL_rdusp 58 #define PAL_whami 60 -#define PAL_rtsys 61 +#define PAL_retsys 61 #define PAL_rti 63 #endif /* __ALPHA_PAL_H */ diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index 363f1477ac16..e35f02b4713b 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -331,19 +331,19 @@ #define __NR_removexattr 391 #define __NR_lremovexattr 392 #define __NR_fremovexattr 393 -#define __NR_futex 394 -#define __NR_sched_setaffinity 395 -#define __NR_sched_getaffinity 396 -#define __NR_tuxcall 397 -#define __NR_io_setup 398 -#define __NR_io_destroy 399 -#define __NR_io_getevents 400 -#define __NR_io_submit 401 -#define __NR_io_cancel 402 -#define __NR_alloc_hugepages 403 -#define __NR_free_hugepages 404 -#define __NR_exit_group 405 - +#define __NR_futex 394 +#define __NR_sched_setaffinity 395 +#define __NR_sched_getaffinity 396 +#define __NR_tuxcall 397 +#define __NR_io_setup 398 +#define __NR_io_destroy 399 +#define __NR_io_getevents 400 +#define __NR_io_submit 401 +#define __NR_io_cancel 402 +#define __NR_alloc_hugepages 403 +#define __NR_free_hugepages 404 +#define __NR_exit_group 405 +#define NR_SYSCALLS 406 #if defined(__GNUC__) @@ -598,7 +598,7 @@ static inline pid_t waitpid(int pid, int * wait_stat, int flags) return sys_wait4(pid, wait_stat, flags, NULL); } -#endif +#endif /* __KERNEL_SYSCALLS__ */ /* * "Conditional" syscalls diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h index dcca9fc715a8..8e6f81b7a524 100644 --- a/include/asm-generic/siginfo.h +++ b/include/asm-generic/siginfo.h @@ -91,7 +91,7 @@ typedef struct siginfo { #define __SI_FAULT (3 << 16) #define __SI_CHLD (4 << 16) #define __SI_RT (5 << 16) -#define __SI_CODE(T,N) ((T) << 16 | ((N) & 0xffff)) +#define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) #else #define __SI_KILL 0 #define __SI_TIMER 0 diff --git a/include/linux/ide.h b/include/linux/ide.h index 0655a585300f..44cb38c00b96 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -794,6 +794,7 @@ typedef struct ide_drive_s { int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ struct list_head list; + struct device gendev; struct gendisk *disk; } ide_drive_t; @@ -1199,6 +1200,7 @@ typedef struct ide_driver_s { int (*attach)(ide_drive_t *); void (*ata_prebuilder)(ide_drive_t *); void (*atapi_prebuilder)(ide_drive_t *); + struct device_driver gen_driver; struct list_head drives; struct list_head drivers; } ide_driver_t; diff --git a/kernel/timer.c b/kernel/timer.c index bdd8df9e1691..16840a689ba4 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -798,10 +798,18 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds) * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this * should be moved into arch/i386 instead? */ - + +/** + * sys_getpid - return the thread group id of the current process + * + * Note, despite the name, this returns the tgid not the pid. The tgid and + * the pid are identical unless CLONE_THREAD was specified on clone() in + * which case the tgid is the same in all threads of the same group. + * + * This is SMP safe as current->tgid does not change. + */ asmlinkage long sys_getpid(void) { - /* This is SMP safe - current->pid doesn't change */ return current->tgid; } diff --git a/lib/brlock.c b/lib/brlock.c index f00914441329..7e9121378da1 100644 --- a/lib/brlock.c +++ b/lib/brlock.c @@ -24,8 +24,9 @@ void __br_write_lock (enum brlock_indices idx) { int i; + preempt_disable(); for (i = 0; i < NR_CPUS; i++) - write_lock(&__brlock_array[i][idx]); + _raw_write_lock(&__brlock_array[i][idx]); } void __br_write_unlock (enum brlock_indices idx) @@ -33,7 +34,8 @@ void __br_write_unlock (enum brlock_indices idx) int i; for (i = 0; i < NR_CPUS; i++) - write_unlock(&__brlock_array[i][idx]); + _raw_write_unlock(&__brlock_array[i][idx]); + preempt_enable(); } #else /* ! __BRLOCK_USE_ATOMICS */ @@ -48,11 +50,12 @@ void __br_write_lock (enum brlock_indices idx) { int i; + preempt_disable(); again: - spin_lock(&__br_write_locks[idx].lock); + _raw_spin_lock(&__br_write_locks[idx].lock); for (i = 0; i < NR_CPUS; i++) if (__brlock_array[i][idx] != 0) { - spin_unlock(&__br_write_locks[idx].lock); + _raw_spin_unlock(&__br_write_locks[idx].lock); barrier(); cpu_relax(); goto again; |
