diff -urN linux-2.4.31/Documentation/Configure.help linux-2.4.32/Documentation/Configure.help
--- linux-2.4.31/Documentation/Configure.help 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/Documentation/Configure.help 2005-11-16 11:12:54.562075817 -0800
@@ -9978,9 +9978,7 @@
CONFIG_PPPOE
Support for PPP over Ethernet.
- This driver requires the current pppd from the "ppp" CVS repository
- on cvs.samba.org. The required support will be present in the next
- ppp release (2.4.2).
+ This driver requires a ppp release >= 2.4.2.
Wireless LAN (non-hamradio)
CONFIG_NET_RADIO
@@ -28990,6 +28988,9 @@
the TEA algorithm to address a potential key weakness
in the TEA algorithm.
+ Xtendend Encryption Tiny Algorithm is a mis-implementation
+ of the XTEA algorithm for compatibility purposes.
+
CONFIG_CRYPTO_ARC4
ARC4 cipher algorithm.
diff -urN linux-2.4.31/Documentation/cciss.txt linux-2.4.32/Documentation/cciss.txt
--- linux-2.4.31/Documentation/cciss.txt 2004-08-07 16:26:04.000000000 -0700
+++ linux-2.4.32/Documentation/cciss.txt 2005-11-16 11:12:54.563075862 -0800
@@ -15,7 +15,11 @@
* SA 6400 U320 Expansion Module
* SA 6i
* SA 6422
- * SA V100
+ * SA P600
+ * SA P400
+ * SA P400i
+ * SA E200
+ * SA E200i
If nodes are not already created in the /dev/cciss directory
diff -urN linux-2.4.31/Documentation/crypto/api-intro.txt linux-2.4.32/Documentation/crypto/api-intro.txt
--- linux-2.4.31/Documentation/crypto/api-intro.txt 2004-11-17 03:54:20.000000000 -0800
+++ linux-2.4.32/Documentation/crypto/api-intro.txt 2005-11-16 11:12:54.563075862 -0800
@@ -221,6 +221,7 @@
TEA/XTEA algorithm contributors:
Aaron Grothe
+ Michael Ringe
Khazad algorithm contributors:
Aaron Grothe
diff -urN linux-2.4.31/Documentation/networking/vortex.txt linux-2.4.32/Documentation/networking/vortex.txt
--- linux-2.4.31/Documentation/networking/vortex.txt 2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.32/Documentation/networking/vortex.txt 2005-11-16 11:12:54.563075862 -0800
@@ -12,7 +12,7 @@
Please report problems to one or more of:
Andrew Morton <andrewm@uow.edu.au>
- Netdev mailing list <netdev@oss.sgi.com>
+ Netdev mailing list <netdev@vger.kernel.org>
Linux kernel mailing list <linux-kernel@vger.kernel.org>
Please note the 'Reporting and Diagnosing Problems' section at the end
diff -urN linux-2.4.31/MAINTAINERS linux-2.4.32/MAINTAINERS
--- linux-2.4.31/MAINTAINERS 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/MAINTAINERS 2005-11-16 11:12:54.564075907 -0800
@@ -116,7 +116,7 @@
8169 10/100/1000 GIGABIT ETHERNET DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
-L: netdev@oss.sgi.com
+L: netdev@vger.kernel.org
S: Maintained
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
@@ -820,7 +820,7 @@
I2C SUBSYSTEM
P: Jean Delvare
M: khali@linux-fr.org
-L: sensors@stimpy.netroedge.com
+L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.nu/
S: Maintained
@@ -993,9 +993,11 @@
IPVS
P: Wensong Zhang
M: wensong@linux-vs.org
+P: Simon Horman
+M: horms@verge.net.au
P: Julian Anastasov
M: ja@ssi.bg
-L: lvs-users@linuxvirtualserver.org
+L: netdev@vger.kernel.org
S: Maintained
IPX NETWORK LAYER
@@ -1186,7 +1188,7 @@
P: Manish Lachwani
M: Manish_Lachwani@pmc-sierra.com
L: linux-mips@linux-mips.org
-L: netdev@oss.sgi.com
+L: netdev@vger.kernel.org
S: Supported
MARVELL YUKON / SYSKONNECT DRIVER
@@ -1315,7 +1317,7 @@
NETWORKING [GENERAL]
P: Networking Team
-M: netdev@oss.sgi.com
+M: netdev@vger.kernel.org
L: linux-net@vger.kernel.org
S: Maintained
@@ -1332,7 +1334,7 @@
M: yoshfuji@linux-ipv6.org
P: Patrick McHardy
M: kaber@coreworks.de
-L: netdev@oss.sgi.com
+L: netdev@vger.kernel.org
S: Maintained
NFS CLIENT
@@ -1529,7 +1531,7 @@
PRISM54 WIRELESS DRIVER
P: Prism54 Development Team
M: prism54-private@prism54.org
-L: netdev@oss.sgi.com
+L: netdev@vger.kernel.org
W: http://prism54.org
S: Maintained
diff -urN linux-2.4.31/Makefile linux-2.4.32/Makefile
--- linux-2.4.31/Makefile 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/Makefile 2005-11-16 11:12:54.685081300 -0800
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 4
-SUBLEVEL = 31
+SUBLEVEL = 32
EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -urN linux-2.4.31/arch/alpha/kernel/Makefile linux-2.4.32/arch/alpha/kernel/Makefile
--- linux-2.4.31/arch/alpha/kernel/Makefile 2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.32/arch/alpha/kernel/Makefile 2005-11-16 11:12:54.565075951 -0800
@@ -76,7 +76,7 @@
obj-y += sys_alcor.o
endif
ifneq ($(CONFIG_ALPHA_CABRIOLET)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_EB66P)$(CONFIG_ALPHA_LX164)$(CONFIG_ALPHA_PC164),)
-obj-y += sys_cabriolet.o
+obj-y += sys_cabriolet.o ns87312.o
endif
obj-$(CONFIG_ALPHA_DP264) += sys_dp264.o
diff -urN linux-2.4.31/arch/i386/kernel/apm.c linux-2.4.32/arch/i386/kernel/apm.c
--- linux-2.4.31/arch/i386/kernel/apm.c 2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.32/arch/i386/kernel/apm.c 2005-11-16 11:12:54.566075996 -0800
@@ -327,7 +327,7 @@
* Save a segment register away
*/
#define savesegment(seg, where) \
- __asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where))
+ __asm__ __volatile__("mov %%" #seg ",%0" : "=m" (where))
/*
* Maximum number of events stored
@@ -553,7 +553,7 @@
#ifdef APM_ZERO_SEGS
# define APM_DECL_SEGS \
- unsigned int saved_fs; unsigned int saved_gs;
+ unsigned short saved_fs; unsigned short saved_gs;
# define APM_DO_SAVE_SEGS \
savesegment(fs, saved_fs); savesegment(gs, saved_gs)
# define APM_DO_ZERO_SEGS \
diff -urN linux-2.4.31/arch/i386/kernel/pci-irq.c linux-2.4.32/arch/i386/kernel/pci-irq.c
--- linux-2.4.31/arch/i386/kernel/pci-irq.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/arch/i386/kernel/pci-irq.c 2005-11-16 11:12:54.567076040 -0800
@@ -664,6 +664,30 @@
static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
/* FIXME: We should move some of the quirk fixup stuff here */
+
+ /*
+ * work arounds for some buggy BIOSes
+ */
+ if (device == PCI_DEVICE_ID_VIA_82C586_0) {
+ switch(router->device)
+ {
+ case PCI_DEVICE_ID_VIA_82C686:
+ /*
+ * Asus k7m bios wrongly reports 82C686A
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_82C686;
+ break;
+ case PCI_DEVICE_ID_VIA_8235:
+ /**
+ * Asus a7v-x bios wrongly reports 8235
+ * as 586-compatible
+ */
+ device = PCI_DEVICE_ID_VIA_8235;
+ break;
+ }
+ }
+
switch(device)
{
case PCI_DEVICE_ID_VIA_82C586_0:
@@ -674,6 +698,7 @@
case PCI_DEVICE_ID_VIA_82C596:
case PCI_DEVICE_ID_VIA_82C686:
case PCI_DEVICE_ID_VIA_8231:
+ case PCI_DEVICE_ID_VIA_8235:
/* FIXME: add new ones for 8233/5 */
r->name = "VIA";
r->get = pirq_via_get;
diff -urN linux-2.4.31/arch/i386/kernel/process.c linux-2.4.32/arch/i386/kernel/process.c
--- linux-2.4.31/arch/i386/kernel/process.c 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.32/arch/i386/kernel/process.c 2005-11-16 11:12:54.567076040 -0800
@@ -544,7 +544,7 @@
* Save a segment.
*/
#define savesegment(seg,value) \
- asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
+ asm volatile("mov %%" #seg ",%0":"=m" (value))
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
unsigned long unused,
@@ -661,8 +661,8 @@
* Save away %fs and %gs. No need to save %es and %ds, as
* those are always kernel segments while inside the kernel.
*/
- asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs));
- asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs));
+ asm volatile("mov %%fs,%0":"=m" (prev->fs));
+ asm volatile("mov %%gs,%0":"=m" (prev->gs));
/*
* Restore %fs and %gs.
diff -urN linux-2.4.31/arch/i386/kernel/traps.c linux-2.4.32/arch/i386/kernel/traps.c
--- linux-2.4.31/arch/i386/kernel/traps.c 2002-11-28 15:53:09.000000000 -0800
+++ linux-2.4.32/arch/i386/kernel/traps.c 2005-11-16 11:12:54.568076085 -0800
@@ -631,15 +631,14 @@
*/
cwd = get_fpu_cwd(task);
swd = get_fpu_swd(task);
- switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
+ switch (swd & ~cwd & 0x3f) {
case 0x000:
default:
break;
case 0x001: /* Invalid Op */
- case 0x041: /* Stack Fault */
- case 0x241: /* Stack Fault | Direction */
+ /* swd & 0x240 == 0x040: Stack Fault */
+ /* swd & 0x240 == 0x240: Stack Fault | Direction */
info.si_code = FPE_FLTINV;
- /* Should we clear the SF or let user space do it ???? */
break;
case 0x002: /* Denormalize */
case 0x010: /* Underflow */
diff -urN linux-2.4.31/arch/ia64/ia32/sys_ia32.c linux-2.4.32/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.31/arch/ia64/ia32/sys_ia32.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/ia64/ia32/sys_ia32.c 2005-11-16 11:12:54.570076174 -0800
@@ -94,7 +94,7 @@
static DECLARE_MUTEX(ia32_mmap_sem);
static int
-nargs (unsigned int arg, char **ap)
+nargs (unsigned int arg, char **ap, int max)
{
unsigned int addr;
int n, err;
@@ -107,6 +107,8 @@
err = get_user(addr, (unsigned int *)A(arg));
if (err)
return err;
+ if (n > max)
+ return -E2BIG;
if (ap)
*ap++ = (char *) A(addr);
arg += sizeof(unsigned int);
@@ -128,10 +130,11 @@
int na, ne, len;
long r;
- na = nargs(argv, NULL);
+ /* Allocates upto 2x MAX_ARG_PAGES */
+ na = nargs(argv, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1);
if (na < 0)
return na;
- ne = nargs(envp, NULL);
+ ne = nargs(envp, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1 );
if (ne < 0)
return ne;
len = (na + ne + 2) * sizeof(*av);
@@ -143,10 +146,10 @@
av[na] = NULL;
ae[ne] = NULL;
- r = nargs(argv, av);
+ r = nargs(argv, av, na);
if (r < 0)
goto out;
- r = nargs(envp, ae);
+ r = nargs(envp, ae, ne);
if (r < 0)
goto out;
diff -urN linux-2.4.31/arch/ia64/mm/fault.c linux-2.4.32/arch/ia64/mm/fault.c
--- linux-2.4.31/arch/ia64/mm/fault.c 2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.32/arch/ia64/mm/fault.c 2005-11-16 11:12:54.571076219 -0800
@@ -206,9 +206,6 @@
return;
}
- if (done_with_exception(regs))
- return;
-
/*
* Since we have no vma's for region 5, we might get here even if the address is
* valid, due to the VHPT walker inserting a non present translation that becomes
@@ -219,6 +216,9 @@
if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
return;
+ if (done_with_exception(regs))
+ return;
+
/*
* Oops. The kernel tried to access some bad page. We'll have to terminate things
* with extreme prejudice.
diff -urN linux-2.4.31/arch/mips/.gdbinit linux-2.4.32/arch/mips/.gdbinit
--- linux-2.4.31/arch/mips/.gdbinit 1997-12-10 10:31:09.000000000 -0800
+++ linux-2.4.32/arch/mips/.gdbinit 1969-12-31 16:00:00.000000000 -0800
@@ -1,7 +0,0 @@
-echo Setting up the environment for debugging vmlinux...\n
-echo set remotedebug 0 \n
-set remotedebug 0
-echo cd arch/mips/kernel \n
-cd arch/mips/kernel
-echo target remote /dev/ttyS0 \n
-target remote /dev/ttyS0
diff -urN linux-2.4.31/arch/ppc/boot/lib/zlib.c linux-2.4.32/arch/ppc/boot/lib/zlib.c
--- linux-2.4.31/arch/ppc/boot/lib/zlib.c 2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.32/arch/ppc/boot/lib/zlib.c 2005-11-16 11:12:54.573076308 -0800
@@ -1278,7 +1278,7 @@
{
*t = (inflate_huft *)Z_NULL;
*m = 0;
- return Z_OK;
+ return Z_DATA_ERROR;
}
@@ -1322,6 +1322,7 @@
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
+ n = x[g]; /* set n to length of v */
/* Generate the Huffman codes and for each, make the table entries */
diff -urN linux-2.4.31/arch/ppc/kernel/time.c linux-2.4.32/arch/ppc/kernel/time.c
--- linux-2.4.31/arch/ppc/kernel/time.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/arch/ppc/kernel/time.c 2005-11-16 11:12:54.573076308 -0800
@@ -84,7 +84,7 @@
extern unsigned long wall_jiffies;
-static long time_offset;
+static long timezone_offset;
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
@@ -187,7 +187,7 @@
xtime.tv_sec - last_rtc_update >= 659 &&
abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ &&
jiffies - wall_jiffies == 1) {
- if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+ if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0)
last_rtc_update = xtime.tv_sec+1;
else
/* Try again one minute later */
@@ -297,7 +297,7 @@
unsigned old_stamp, stamp, elapsed;
if (ppc_md.time_init != NULL)
- time_offset = ppc_md.time_init();
+ timezone_offset = ppc_md.time_init();
if (__USE_RTC()) {
/* 601 processor: dec counts down by 128 every 128ns */
@@ -344,9 +344,9 @@
/* If platform provided a timezone (pmac), we correct the time
* using do_sys_settimeofday() which in turn calls warp_clock()
*/
- if (time_offset) {
+ if (timezone_offset) {
struct timezone tz;
- tz.tz_minuteswest = -time_offset / 60;
+ tz.tz_minuteswest = -timezone_offset / 60;
tz.tz_dsttime = 0;
do_sys_settimeofday(NULL, &tz);
}
diff -urN linux-2.4.31/arch/ppc64/boot/zlib.c linux-2.4.32/arch/ppc64/boot/zlib.c
--- linux-2.4.31/arch/ppc64/boot/zlib.c 2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.32/arch/ppc64/boot/zlib.c 2005-11-16 11:12:54.575076397 -0800
@@ -1338,6 +1338,7 @@
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
+ n = x[g]; /* set n to length of v */
/* Generate the Huffman codes and for each, make the table entries */
diff -urN linux-2.4.31/arch/ppc64/kernel/ioctl32.c linux-2.4.32/arch/ppc64/kernel/ioctl32.c
--- linux-2.4.31/arch/ppc64/kernel/ioctl32.c 2005-01-19 06:09:36.000000000 -0800
+++ linux-2.4.32/arch/ppc64/kernel/ioctl32.c 2005-11-16 11:12:54.577076486 -0800
@@ -876,13 +876,15 @@
r = (void *) &r4;
}
- if (ret)
- return -EFAULT;
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
set_fs (KERNEL_DS);
ret = sys_ioctl (fd, cmd, (long) r);
set_fs (old_fs);
-
+out:
if (mysock)
sockfd_put(mysock);
diff -urN linux-2.4.31/arch/sparc64/kernel/ioctl32.c linux-2.4.32/arch/sparc64/kernel/ioctl32.c
--- linux-2.4.31/arch/sparc64/kernel/ioctl32.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/sparc64/kernel/ioctl32.c 2005-11-16 11:12:54.581076664 -0800
@@ -809,13 +809,15 @@
r = (void *) &r4;
}
- if (ret)
- return -EFAULT;
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
set_fs (KERNEL_DS);
ret = sys_ioctl (fd, cmd, (long) r);
set_fs (old_fs);
-
+out:
if (mysock)
sockfd_put(mysock);
diff -urN linux-2.4.31/arch/sparc64/kernel/sparc64_ksyms.c linux-2.4.32/arch/sparc64/kernel/sparc64_ksyms.c
--- linux-2.4.31/arch/sparc64/kernel/sparc64_ksyms.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/sparc64/kernel/sparc64_ksyms.c 2005-11-16 11:12:54.581076664 -0800
@@ -63,7 +63,6 @@
extern void die_if_kernel(char *str, struct pt_regs *regs);
void _sigpause_common (unsigned int set, struct pt_regs *);
extern void *__bzero(void *, size_t);
-extern void *__bzero_noasi(void *, size_t);
extern void *__memscan_zero(void *, size_t);
extern void *__memscan_generic(void *, int, size_t);
extern int __memcmp(const void *, const void *, __kernel_size_t);
diff -urN linux-2.4.31/arch/sparc64/kernel/sys_sparc32.c linux-2.4.32/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.4.31/arch/sparc64/kernel/sys_sparc32.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/sparc64/kernel/sys_sparc32.c 2005-11-16 11:12:54.583076754 -0800
@@ -50,6 +50,7 @@
#include <linux/in.h>
#include <linux/icmpv6.h>
#include <linux/sysctl.h>
+#include <linux/vmalloc.h>
#include <linux/dnotify.h>
#include <linux/netfilter_ipv4/ip_tables.h>
@@ -2919,12 +2920,12 @@
if (optlen != kreplsize)
return -ENOPROTOOPT;
- krepl = (struct ipt_replace *)kmalloc(kreplsize, GFP_KERNEL);
+ krepl = (struct ipt_replace *)vmalloc(kreplsize);
if (krepl == NULL)
return -ENOMEM;
if (copy_from_user(krepl, optval, kreplsize)) {
- kfree(krepl);
+ vfree(krepl);
return -EFAULT;
}
@@ -2932,10 +2933,9 @@
((struct ipt_replace32 *)krepl)->counters);
kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
- krepl->counters = (struct ipt_counters *)kmalloc(
- kcountersize, GFP_KERNEL);
+ krepl->counters = (struct ipt_counters *)vmalloc(kcountersize);
if (krepl->counters == NULL) {
- kfree(krepl);
+ vfree(krepl);
return -ENOMEM;
}
@@ -2949,8 +2949,8 @@
copy_to_user(counters32, krepl->counters, kcountersize))
ret = -EFAULT;
- kfree(krepl->counters);
- kfree(krepl);
+ vfree(krepl->counters);
+ vfree(krepl);
return ret;
}
@@ -4205,7 +4205,7 @@
old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_utimes(kfilename, &ktvs[0]);
+ ret = sys_utimes(kfilename, (tvs ? &ktvs[0] : NULL));
set_fs(old_fs);
putname(kfilename);
diff -urN linux-2.4.31/arch/sparc64/solaris/socket.c linux-2.4.32/arch/sparc64/solaris/socket.c
--- linux-2.4.31/arch/sparc64/solaris/socket.c 2001-02-18 19:49:54.000000000 -0800
+++ linux-2.4.32/arch/sparc64/solaris/socket.c 2005-11-16 11:12:54.584076798 -0800
@@ -410,8 +410,10 @@
unsigned long *kcmsg;
__kernel_size_t32 cmlen;
- if(kern_msg.msg_controllen > sizeof(ctl) &&
- kern_msg.msg_controllen <= 256) {
+ if (kern_msg.msg_controllen <= sizeof(__kernel_size_t32))
+ return -EINVAL;
+
+ if(kern_msg.msg_controllen > sizeof(ctl)) {
err = -ENOBUFS;
ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL);
if(!ctl_buf)
diff -urN linux-2.4.31/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.32/arch/x86_64/ia32/ia32_ioctl.c
--- linux-2.4.31/arch/x86_64/ia32/ia32_ioctl.c 2005-01-19 06:09:39.000000000 -0800
+++ linux-2.4.32/arch/x86_64/ia32/ia32_ioctl.c 2005-11-16 11:12:54.587076932 -0800
@@ -816,6 +816,11 @@
extern struct socket *sockfd_lookup(int fd, int *err);
+extern __inline__ void sockfd_put(struct socket *sock)
+{
+ fput(sock->file);
+}
+
static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
int ret;
@@ -857,12 +862,17 @@
r = (void *) &r4;
}
- if (ret)
- return -EFAULT;
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
set_fs (KERNEL_DS);
ret = sys_ioctl (fd, cmd, (long) r);
set_fs (old_fs);
+out:
+ if (mysock)
+ sockfd_put(mysock);
return ret;
}
@@ -2766,17 +2776,24 @@
static int tiocgdev(unsigned fd, unsigned cmd, unsigned int *ptr)
{
- struct file *file = fget(fd);
+ struct file *file;
struct tty_struct *real_tty;
+ int ret;
+ file = fget(fd);
if (!file)
return -EBADF;
+ ret = -EINVAL;
if (file->f_op->ioctl != tty_ioctl)
- return -EINVAL;
+ goto out;
real_tty = (struct tty_struct *)file->private_data;
if (!real_tty)
- return -EINVAL;
- return put_user(kdev_t_to_nr(real_tty->device), ptr);
+ goto out;
+ ret = put_user(kdev_t_to_nr(real_tty->device), ptr);
+out:
+ fput(file);
+
+ return ret;
}
diff -urN linux-2.4.31/arch/x86_64/ia32/sys_ia32.c linux-2.4.32/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.31/arch/x86_64/ia32/sys_ia32.c 2005-01-19 06:09:39.000000000 -0800
+++ linux-2.4.32/arch/x86_64/ia32/sys_ia32.c 2005-11-16 11:12:54.588076976 -0800
@@ -2200,7 +2200,7 @@
return ret;
}
-static int nargs(u32 src, char **dst)
+static int nargs(u32 src, char **dst, int max)
{
int cnt;
u32 val;
@@ -2210,13 +2210,13 @@
int ret = get_user(val, (__u32 *)(u64)src);
if (ret)
return ret;
+ if (cnt > max)
+ return -E2BIG;
if (dst)
dst[cnt] = (char *)(u64)val;
cnt++;
src += 4;
- if (cnt >= (MAX_ARG_PAGES * PAGE_SIZE) / sizeof(char *))
- return -E2BIG;
- } while(val);
+ } while(val);
if (dst)
dst[cnt-1] = 0;
return cnt;
@@ -2230,13 +2230,14 @@
int ret;
unsigned sz = 0;
+ /* Can actually allocate 2*MAX_ARG_PAGES */
if (argv) {
- na = nargs(argv, NULL);
+ na = nargs(argv, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1);
if (na < 0)
return -EFAULT;
}
if (envp) {
- ne = nargs(envp, NULL);
+ ne = nargs(envp, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1);
if (ne < 0)
return -EFAULT;
}
@@ -2252,13 +2253,13 @@
}
if (argv) {
- ret = nargs(argv, buf);
+ ret = nargs(argv, buf, na);
if (ret < 0)
goto free;
}
if (envp) {
- ret = nargs(envp, buf + na);
+ ret = nargs(envp, buf + na, ne);
if (ret < 0)
goto free;
}
diff -urN linux-2.4.31/arch/x86_64/kernel/io_apic.c linux-2.4.32/arch/x86_64/kernel/io_apic.c
--- linux-2.4.31/arch/x86_64/kernel/io_apic.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/io_apic.c 2005-11-16 11:12:54.590077066 -0800
@@ -222,7 +222,6 @@
__setup("apic", ioapic_setup);
-#ifndef CONFIG_SMP
#include <asm/pci-direct.h>
#include <linux/pci_ids.h>
#include <linux/pci.h>
@@ -279,7 +278,6 @@
}
}
}
-#endif
static int __init ioapic_pirq_setup(char *str)
{
diff -urN linux-2.4.31/arch/x86_64/kernel/pci-gart.c linux-2.4.32/arch/x86_64/kernel/pci-gart.c
--- linux-2.4.31/arch/x86_64/kernel/pci-gart.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/pci-gart.c 2005-11-16 11:12:54.590077066 -0800
@@ -47,6 +47,10 @@
extern int fallback_aper_order;
extern int fallback_aper_force;
+#ifdef CONFIG_SWIOTLB
+extern char *io_tlb_start, *io_tlb_end;
+#endif
+
/* Allocation bitmap for the remapping area */
static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED;
static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */
@@ -234,10 +238,10 @@
void *vaddr, dma_addr_t bus)
{
unsigned long iommu_page;
- extern char *io_tlb_start, *io_tlb_end;
-
+
size = round_up(size, PAGE_SIZE);
#ifdef CONFIG_SWIOTLB
+ /* Overlap should not happen */
if (swiotlb && vaddr >= (void *)io_tlb_start &&
vaddr < (void *)io_tlb_end) {
swiotlb_unmap_single (hwdev, bus, size, PCI_DMA_TODEVICE);
diff -urN linux-2.4.31/arch/x86_64/kernel/process.c linux-2.4.32/arch/x86_64/kernel/process.c
--- linux-2.4.31/arch/x86_64/kernel/process.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/process.c 2005-11-16 11:12:54.591077110 -0800
@@ -526,10 +526,10 @@
p->thread.fs = me->thread.fs;
p->thread.gs = me->thread.gs;
- asm("movl %%gs,%0" : "=m" (p->thread.gsindex));
- asm("movl %%fs,%0" : "=m" (p->thread.fsindex));
- asm("movl %%es,%0" : "=m" (p->thread.es));
- asm("movl %%ds,%0" : "=m" (p->thread.ds));
+ asm("mov %%gs,%0" : "=m" (p->thread.gsindex));
+ asm("mov %%fs,%0" : "=m" (p->thread.fsindex));
+ asm("mov %%es,%0" : "=m" (p->thread.es));
+ asm("mov %%ds,%0" : "=m" (p->thread.ds));
unlazy_fpu(current);
p->thread.i387 = current->thread.i387;
@@ -574,11 +574,11 @@
/*
* Switch DS and ES.
*/
- asm volatile("movl %%es,%0" : "=m" (prev->es));
+ asm volatile("mov %%es,%0" : "=m" (prev->es));
if (unlikely(next->es | prev->es))
loadsegment(es, next->es);
- asm volatile ("movl %%ds,%0" : "=m" (prev->ds));
+ asm volatile ("mov %%ds,%0" : "=m" (prev->ds));
if (unlikely(next->ds | prev->ds))
loadsegment(ds, next->ds);
@@ -587,7 +587,7 @@
*/
{
unsigned fsindex;
- asm volatile("movl %%fs,%0" : "=g" (fsindex));
+ asm volatile("movl %%fs,%0" : "=r" (fsindex));
/* segment register != 0 always requires a reload.
also reload when it has changed.
when prev process used 64bit base always reload
@@ -608,7 +608,7 @@
}
{
unsigned gsindex;
- asm volatile("movl %%gs,%0" : "=g" (gsindex));
+ asm volatile("movl %%gs,%0" : "=r" (gsindex));
if (unlikely((gsindex | next->gsindex) || prev->gs)) {
load_gs_index(next->gsindex);
if (gsindex)
diff -urN linux-2.4.31/arch/x86_64/kernel/ptrace.c linux-2.4.32/arch/x86_64/kernel/ptrace.c
--- linux-2.4.31/arch/x86_64/kernel/ptrace.c 2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/ptrace.c 2005-11-16 11:12:54.591077110 -0800
@@ -114,13 +114,13 @@
child->thread.es = value & 0xffff;
return 0;
case offsetof(struct user_regs_struct,fs_base):
- if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
- return -EIO;
+ if (value >= TASK_SIZE)
+ return -EIO;
child->thread.fs = value;
return 0;
case offsetof(struct user_regs_struct,gs_base):
- if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
- return -EIO;
+ if (value >= TASK_SIZE)
+ return -EIO;
child->thread.gs = value;
return 0;
case offsetof(struct user_regs_struct, eflags):
@@ -139,6 +139,11 @@
return -EIO;
value &= 0xffff;
break;
+ case offsetof(struct user_regs_struct, rip):
+ /* Check if the new RIP address is canonical */
+ if (value >= TASK_SIZE)
+ return -EIO;
+ break;
}
put_stack_long(child, regno - sizeof(struct pt_regs), value);
return 0;
diff -urN linux-2.4.31/arch/x86_64/kernel/setup.c linux-2.4.32/arch/x86_64/kernel/setup.c
--- linux-2.4.31/arch/x86_64/kernel/setup.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/setup.c 2005-11-16 11:12:54.592077155 -0800
@@ -304,7 +304,7 @@
#endif
paging_init();
-#if !defined(CONFIG_SMP) && defined(CONFIG_X86_IO_APIC)
+#if defined(CONFIG_X86_IO_APIC)
extern void check_ioapic(void);
check_ioapic();
#endif
diff -urN linux-2.4.31/arch/x86_64/kernel/traps.c linux-2.4.32/arch/x86_64/kernel/traps.c
--- linux-2.4.31/arch/x86_64/kernel/traps.c 2004-04-14 06:05:28.000000000 -0700
+++ linux-2.4.32/arch/x86_64/kernel/traps.c 2005-11-16 11:12:54.592077155 -0800
@@ -857,7 +857,7 @@
set_intr_gate(9,&coprocessor_segment_overrun);
set_intr_gate(10,&invalid_TSS);
set_intr_gate(11,&segment_not_present);
- set_intr_gate_ist(12,&stack_segment,STACKFAULT_STACK);
+ set_intr_gate(12,&stack_segment);
set_intr_gate(13,&general_protection);
set_intr_gate(14,&page_fault);
set_intr_gate(15,&spurious_interrupt_bug);
diff -urN linux-2.4.31/crypto/tcrypt.c linux-2.4.32/crypto/tcrypt.c
--- linux-2.4.31/crypto/tcrypt.c 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.32/crypto/tcrypt.c 2005-11-16 11:12:54.593077199 -0800
@@ -64,7 +64,7 @@
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"arc4", "michael_mic", "deflate", "tea", "xtea", "khazad",
- "wp512", "wp384", "wp256", "tnepres", "anubis", NULL
+ "wp512", "wp384", "wp256", "tnepres", "anubis", "xeta", NULL
};
static void
@@ -590,6 +590,10 @@
test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
+ //XETA
+ test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS);
+ test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS);
+
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
@@ -725,6 +729,11 @@
test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
break;
+ case 30:
+ test_cipher ("xeta", MODE_ECB, ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS);
+ test_cipher ("xeta", MODE_ECB, DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS);
+ break;
+
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
diff -urN linux-2.4.31/crypto/tcrypt.h linux-2.4.32/crypto/tcrypt.h
--- linux-2.4.31/crypto/tcrypt.h 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.32/crypto/tcrypt.h 2005-11-16 11:12:54.594077244 -0800
@@ -2085,7 +2085,7 @@
.klen = 16,
.input = { [0 ... 8] = 0x00 },
.ilen = 8,
- .result = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .result = { 0xd8, 0xd4, 0xe9, 0xde, 0xd9, 0x1e, 0x13, 0xf7 },
.rlen = 8,
}, {
.key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
@@ -2093,13 +2093,13 @@
.klen = 16,
.input = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
.ilen = 8,
- .result = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .result = { 0x94, 0xeb, 0xc8, 0x96, 0x84, 0x6a, 0x49, 0xa8 },
.rlen = 8,
}, {
.key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
.klen = 16,
- .input = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ .input = { 0x3e, 0xce, 0xae, 0x22, 0x60, 0x56, 0xa8, 0x9d,
0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
.ilen = 16,
.result = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
@@ -2114,10 +2114,10 @@
0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
.ilen = 32,
- .result = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
- 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
- 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
- 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .result = { 0x99, 0x81, 0x9f, 0x5d, 0x6f, 0x4b, 0x31, 0x3a,
+ 0x86, 0xff, 0x6f, 0xd0, 0xe3, 0x87, 0x70, 0x07,
+ 0x4d, 0xb8, 0xcf, 0xf3, 0x99, 0x50, 0xb3, 0xd4,
+ 0x73, 0xa2, 0xfa, 0xc9, 0x16, 0x59, 0x5d, 0x81 },
.rlen = 32,
}
};
@@ -2127,7 +2127,7 @@
{
.key = { [0 ... 15] = 0x00 },
.klen = 16,
- .input = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .input = { 0xd8, 0xd4, 0xe9, 0xde, 0xd9, 0x1e, 0x13, 0xf7 },
.ilen = 8,
.result = { [0 ... 8] = 0x00 },
.rlen = 8,
@@ -2135,7 +2135,7 @@
.key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
.klen = 16,
- .input = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .input = { 0x94, 0xeb, 0xc8, 0x96, 0x84, 0x6a, 0x49, 0xa8 },
.ilen = 8,
.result = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
.rlen = 8,
@@ -2143,8 +2143,8 @@
.key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
.klen = 16,
- .input = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
- 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .input = { 0x3e, 0xce, 0xae, 0x22, 0x60, 0x56, 0xa8, 0x9d,
+ 0x77, 0x4d, 0xd4, 0xb4, 0x87, 0x24, 0xe3, 0x9a },
.ilen = 16,
.result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
@@ -2153,10 +2153,10 @@
.key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
.klen = 16,
- .input = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
- 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
- 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
- 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .input = { 0x99, 0x81, 0x9f, 0x5d, 0x6f, 0x4b, 0x31, 0x3a,
+ 0x86, 0xff, 0x6f, 0xd0, 0xe3, 0x87, 0x70, 0x07,
+ 0x4d, 0xb8, 0xcf, 0xf3, 0x99, 0x50, 0xb3, 0xd4,
+ 0x73, 0xa2, 0xfa, 0xc9, 0x16, 0x59, 0x5d, 0x81 },
.ilen = 32,
.result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
@@ -2469,6 +2469,100 @@
},
};
+/*
+ * XETA test vectors
+ */
+#define XETA_ENC_TEST_VECTORS 4
+#define XETA_DEC_TEST_VECTORS 4
+
+struct cipher_testvec xeta_enc_tv_template[] =
+{
+ {
+ .key = { [0 ... 15] = 0x00 },
+ .klen = 16,
+ .input = { [0 ... 8] = 0x00 },
+ .ilen = 8,
+ .result = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .rlen = 8,
+ }, {
+ .key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
+ 0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
+ .klen = 16,
+ .input = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
+ .ilen = 8,
+ .result = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .rlen = 8,
+ }, {
+ .key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
+ 0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
+ .klen = 16,
+ .input = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
+ .ilen = 16,
+ .result = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
+ 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .rlen = 16,
+ }, {
+ .key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
+ 0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
+ .klen = 16,
+ .input = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
+ .ilen = 32,
+ .result = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+ 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+ 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
+ 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .rlen = 32,
+ }
+};
+
+struct cipher_testvec xeta_dec_tv_template[] =
+{
+ {
+ .key = { [0 ... 15] = 0x00 },
+ .klen = 16,
+ .input = { 0xaa, 0x22, 0x96, 0xe5, 0x6c, 0x61, 0xf3, 0x45 },
+ .ilen = 8,
+ .result = { [0 ... 8] = 0x00 },
+ .rlen = 8,
+ }, {
+ .key = { 0x2b, 0x02, 0x05, 0x68, 0x06, 0x14, 0x49, 0x76,
+ 0x77, 0x5d, 0x0e, 0x26, 0x6c, 0x28, 0x78, 0x43 },
+ .klen = 16,
+ .input = { 0x82, 0x3e, 0xeb, 0x35, 0xdc, 0xdd, 0xd9, 0xc3 },
+ .ilen = 8,
+ .result = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x2e },
+ .rlen = 8,
+ }, {
+ .key = { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
+ 0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
+ .klen = 16,
+ .input = { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
+ 0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
+ .ilen = 16,
+ .result = { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
+ 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
+ .rlen = 16,
+ }, {
+ .key = { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
+ 0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
+ .klen = 16,
+ .input = { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+ 0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+ 0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
+ 0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
+ .ilen = 32,
+ .result = { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+ 0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+ 0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
+ 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
+ .rlen = 32,
+ }
+};
+
/*
* Compression stuff.
*/
diff -urN linux-2.4.31/crypto/tea.c linux-2.4.32/crypto/tea.c
--- linux-2.4.31/crypto/tea.c 2004-11-17 03:54:21.000000000 -0800
+++ linux-2.4.32/crypto/tea.c 2005-11-16 11:12:54.595077288 -0800
@@ -1,11 +1,15 @@
/*
* Cryptographic API.
*
- * TEA and Xtended TEA Algorithms
+ * TEA, XTEA, and XETA crypto alogrithms
*
* The TEA and Xtended TEA algorithms were developed by David Wheeler
* and Roger Needham at the Computer Laboratory of Cambridge University.
*
+ * Due to the order of evaluation in XTEA many people have incorrectly
+ * implemented it. XETA (XTEA in the wrong order), exists for
+ * compatibility with these implementations.
+ *
* Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
*
* This program is free software; you can redistribute it and/or modify
@@ -153,9 +157,9 @@
z = u32_in (src + 4);
while (sum != limit) {
- y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
+ y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]);
sum += XTEA_DELTA;
- z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
+ z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]);
}
u32_out (dst, y);
@@ -175,6 +179,51 @@
sum = XTEA_DELTA * XTEA_ROUNDS;
while (sum) {
+ z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]);
+ sum -= XTEA_DELTA;
+ y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
+ }
+
+ u32_out (dst, y);
+ u32_out (dst + 4, z);
+
+}
+
+static void xeta_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
+{
+
+ u32 y, z, sum = 0;
+ u32 limit = XTEA_DELTA * XTEA_ROUNDS;
+
+ struct xtea_ctx *ctx = ctx_arg;
+
+ y = u32_in (src);
+ z = u32_in (src + 4);
+
+ while (sum != limit) {
+ y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
+ sum += XTEA_DELTA;
+ z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
+
+ }
+
+ u32_out (dst, y);
+ u32_out (dst + 4, z);
+
+}
+
+static void xeta_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
+{
+
+ u32 y, z, sum;
+ struct tea_ctx *ctx = ctx_arg;
+
+ y = u32_in (src);
+ z = u32_in (src + 4);
+
+ sum = XTEA_DELTA * XTEA_ROUNDS;
+
+ while (sum) {
z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3];
sum -= XTEA_DELTA;
y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
@@ -215,6 +264,22 @@
.cia_decrypt = xtea_decrypt } }
};
+
+static struct crypto_alg xeta_alg = {
+ .cra_name = "xeta",
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = XTEA_BLOCK_SIZE,
+ .cra_ctxsize = sizeof (struct xtea_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(xtea_alg.cra_list),
+ .cra_u = { .cipher = {
+ .cia_min_keysize = XTEA_KEY_SIZE,
+ .cia_max_keysize = XTEA_KEY_SIZE,
+ .cia_setkey = xtea_setkey,
+ .cia_encrypt = xeta_encrypt,
+ .cia_decrypt = xeta_decrypt } }
+};
+
static int __init init(void)
{
int ret = 0;
@@ -229,6 +294,13 @@
goto out;
}
+ ret = crypto_register_alg(&xeta_alg);
+ if (ret < 0) {
+ crypto_unregister_alg(&tea_alg);
+ crypto_unregister_alg(&xtea_alg);
+ goto out;
+ }
+
out:
return ret;
}
@@ -237,10 +309,11 @@
{
crypto_unregister_alg(&tea_alg);
crypto_unregister_alg(&xtea_alg);
+ crypto_unregister_alg(&xeta_alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("TEA & XTEA Cryptographic Algorithms");
+MODULE_DESCRIPTION("TEA, XTEA & XETA Cryptographic Algorithms");
diff -urN linux-2.4.31/drivers/block/cciss.c linux-2.4.32/drivers/block/cciss.c
--- linux-2.4.31/drivers/block/cciss.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/drivers/block/cciss.c 2005-11-16 11:12:54.597077378 -0800
@@ -1,6 +1,6 @@
/*
* Disk Array driver for HP SA 5xxx and 6xxx Controllers
- * Copyright 2000, 2002 Hewlett-Packard Development Company, L.P.
+ * Copyright 2000, 2005 Hewlett-Packard Development Company, L.P.
*
* 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
@@ -45,13 +45,13 @@
#include <linux/genhd.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.4.52)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,52)
+#define DRIVER_NAME "HP CISS Driver (v 2.4.60)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,60)
/* Embedded module documentation macros - see modules.h */
MODULE_AUTHOR("Hewlett-Packard Company");
MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.52");
-MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400 6i SA6422 V100");
+MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400 6i SA6422 P600 P400 P400i E200i E200");
MODULE_LICENSE("GPL");
#include "cciss_cmd.h"
@@ -80,8 +80,24 @@
0x0E11, 0x4091, 0, 0, 0},
{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
0x0E11, 0x409E, 0, 0, 0},
- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISS,
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA,
+ 0x103C, 0x3225, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+ 0x103C, 0x3234, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+ 0x103C, 0x3235, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
0x103C, 0x3211, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103C, 0x3212, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103C, 0x3213, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103C, 0x3214, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+ 0x103C, 0x3215, 0, 0, 0},
+ { PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
};
MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -103,7 +119,14 @@
{ 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
{ 0x40910E11, "Smart Array 6i", &SA5_access},
{ 0x409E0E11, "Smart Array 6422", &SA5_access},
- { 0x3211103C, "Smart Array V100", &SA5_access},
+ { 0x3234103c, "Smart Array P400", &SA5_access},
+ { 0x3235103c, "Smart Array P400i", &SA5_access},
+ { 0x3211103c, "Smart Array E200i", &SA5_access},
+ { 0x3212103c, "Smart Array E200", &SA5_access},
+ { 0x3213103c, "Smart Array E200i", &SA5_access},
+ { 0x3214103c, "Smart Array E200i", &SA5_access},
+ { 0x3215103c, "Smart Array E200i", &SA5_access},
+ { 0xFFFF103C, "Unknown Smart Array", &SA5_access},
};
/* How long to wait (in millesconds) for board to go into simple mode */
@@ -2805,12 +2828,6 @@
break;
}
}
- if (i == NR_PRODUCTS) {
- printk(KERN_WARNING "cciss: Sorry, I don't know how"
- " to access the Smart Array controller %08lx\n",
- (unsigned long)board_id);
- return -1;
- }
if ( (readb(&c->cfgtable->Signature[0]) != 'C') ||
(readb(&c->cfgtable->Signature[1]) != 'I') ||
(readb(&c->cfgtable->Signature[2]) != 'S') ||
@@ -2818,6 +2835,25 @@
printk("Does not appear to be a valid CISS config table\n");
return -1;
}
+ /* We didn't find the controller in our list. We know the
+ * signature is valid. If it's an HP device let's try to
+ * bind to the device and fire it up. Otherwise we bail.
+ */
+ if (i == NR_PRODUCTS) {
+ if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
+ c->product_name = products[NR_PRODUCTS-1].product_name;
+ c->access = *(products[NR_PRODUCTS-1].access);
+ printk(KERN_WARNING "cciss: This is an unknown "
+ "Smart Array controller.\n"
+ "cciss: Please update to the latest driver "
+ "available from www.hp.com.\n");
+ } else {
+ printk(KERN_WARNING "cciss: Sorry, I don't know how"
+ " to access the Smart Array controller %08lx\n"
+ , (unsigned long)board_id);
+ return -1;
+ }
+ }
#ifdef CONFIG_X86
{
diff -urN linux-2.4.31/drivers/bluetooth/bfusb.c linux-2.4.32/drivers/bluetooth/bfusb.c
--- linux-2.4.31/drivers/bluetooth/bfusb.c 2004-08-07 16:26:04.000000000 -0700
+++ linux-2.4.32/drivers/bluetooth/bfusb.c 2005-11-16 11:12:54.598077422 -0800
@@ -470,12 +470,11 @@
return 0;
write_lock_irqsave(&bfusb->lock, flags);
+ write_unlock_irqrestore(&bfusb->lock, flags);
bfusb_unlink_urbs(bfusb);
bfusb_flush(hdev);
- write_unlock_irqrestore(&bfusb->lock, flags);
-
MOD_DEC_USE_COUNT;
return 0;
diff -urN linux-2.4.31/drivers/bluetooth/hci_usb.c linux-2.4.32/drivers/bluetooth/hci_usb.c
--- linux-2.4.31/drivers/bluetooth/hci_usb.c 2004-08-07 16:26:04.000000000 -0700
+++ linux-2.4.32/drivers/bluetooth/hci_usb.c 2005-11-16 11:12:54.598077422 -0800
@@ -398,13 +398,13 @@
BT_DBG("%s", hdev->name);
+ /* Synchronize with completion handlers */
write_lock_irqsave(&husb->completion_lock, flags);
-
+ write_unlock_irqrestore(&husb->completion_lock, flags);
+
hci_usb_unlink_urbs(husb);
hci_usb_flush(hdev);
- write_unlock_irqrestore(&husb->completion_lock, flags);
-
MOD_DEC_USE_COUNT;
return 0;
}
diff -urN linux-2.4.31/drivers/char/cyclades.c linux-2.4.32/drivers/char/cyclades.c
--- linux-2.4.31/drivers/char/cyclades.c 2005-01-19 06:09:44.000000000 -0800
+++ linux-2.4.32/drivers/char/cyclades.c 2005-11-16 11:12:54.602077600 -0800
@@ -2960,10 +2960,15 @@
cy_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info;
unsigned long flags;
int c, ret = 0;
+ if (!tty)
+ return 0;
+
+ info = (struct cyclades_port *)tty->driver_data;
+
#ifdef CY_DEBUG_IO
printk("cyc:cy_write ttyC%d\n", info->line); /* */
#endif
@@ -2972,7 +2977,7 @@
return 0;
}
- if (!tty || !info->xmit_buf || !tmp_buf){
+ if (!info->xmit_buf || !tmp_buf){
return 0;
}
@@ -3047,9 +3052,14 @@
static void
cy_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info;
unsigned long flags;
+ if (!tty)
+ return;
+
+ info = (struct cyclades_port *)tty->driver_data;
+
#ifdef CY_DEBUG_IO
printk("cyc:cy_put_char ttyC%d\n", info->line);
#endif
@@ -3057,7 +3067,7 @@
if (serial_paranoia_check(info, tty->device, "cy_put_char"))
return;
- if (!tty || !info->xmit_buf)
+ if (!info->xmit_buf)
return;
CY_LOCK(info, flags);
diff -urN linux-2.4.31/drivers/char/esp.c linux-2.4.32/drivers/char/esp.c
--- linux-2.4.31/drivers/char/esp.c 2005-01-19 06:09:45.000000000 -0800
+++ linux-2.4.32/drivers/char/esp.c 2005-11-16 11:12:54.604077690 -0800
@@ -1251,13 +1251,18 @@
static void rs_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info;
unsigned long flags;
+ if (!tty)
+ return;
+
+ info = (struct esp_struct *)tty->driver_data;
+
if (serial_paranoia_check(info, tty->device, "rs_put_char"))
return;
- if (!tty || !info->xmit_buf)
+ if (!info->xmit_buf)
return;
save_flags(flags); cli();
@@ -1296,13 +1301,19 @@
const unsigned char *buf, int count)
{
int c, t, ret = 0;
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info;
unsigned long flags;
+
+ if (!tty)
+ return 0;
+
+ info = (struct esp_struct *)tty->driver_data;
+
if (serial_paranoia_check(info, tty->device, "rs_write"))
return 0;
- if (!tty || !info->xmit_buf || !tmp_buf)
+ if (!info->xmit_buf || !tmp_buf)
return 0;
if (from_user)
diff -urN linux-2.4.31/drivers/char/isicom.c linux-2.4.32/drivers/char/isicom.c
--- linux-2.4.31/drivers/char/isicom.c 2005-01-19 06:09:46.000000000 -0800
+++ linux-2.4.32/drivers/char/isicom.c 2005-11-16 11:12:54.605077734 -0800
@@ -1223,9 +1223,15 @@
static int isicom_write(struct tty_struct * tty, int from_user,
const unsigned char * buf, int count)
{
- struct isi_port * port = (struct isi_port *) tty->driver_data;
+ struct isi_port * port;
unsigned long flags;
int cnt, total = 0;
+
+ if (!tty)
+ return 0;
+
+ port = (struct isi_port *) tty->driver_data;
+
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISICOM: isicom_write for port%d: %d bytes.\n",
port->channel+1, count);
@@ -1233,7 +1239,7 @@
if (isicom_paranoia_check(port, tty->device, "isicom_write"))
return 0;
- if (!tty || !port->xmit_buf || !tmp_buf)
+ if (!port->xmit_buf || !tmp_buf)
return 0;
if (from_user)
down(&tmp_buf_sem); /* acquire xclusive access to tmp_buf */
@@ -1281,13 +1287,18 @@
/* put_char et all */
static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
{
- struct isi_port * port = (struct isi_port *) tty->driver_data;
+ struct isi_port * port;
unsigned long flags;
+
+ if (!tty)
+ return;
+
+ port = (struct isi_port *) tty->driver_data;
if (isicom_paranoia_check(port, tty->device, "isicom_put_char"))
return;
- if (!tty || !port->xmit_buf)
+ if (!port->xmit_buf)
return;
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISICOM: put_char, port %d, char %c.\n", port->channel+1, ch);
diff -urN linux-2.4.31/drivers/char/mxser.c linux-2.4.32/drivers/char/mxser.c
--- linux-2.4.31/drivers/char/mxser.c 2005-01-19 06:09:47.000000000 -0800
+++ linux-2.4.32/drivers/char/mxser.c 2005-11-16 11:12:54.607077823 -0800
@@ -911,10 +911,15 @@
const unsigned char *buf, int count)
{
int c, total = 0;
- struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
+ struct mxser_struct *info;
unsigned long flags;
- if (!tty || !info->xmit_buf || !mxvar_tmp_buf)
+ if (!tty)
+ return (0);
+
+ info = (struct mxser_struct *) tty->driver_data;
+
+ if (!info->xmit_buf || !mxvar_tmp_buf)
return (0);
save_flags(flags);
@@ -979,10 +984,15 @@
static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
+ struct mxser_struct *info;
unsigned long flags;
- if (!tty || !info->xmit_buf)
+ if (!tty)
+ return;
+
+ info = (struct mxser_struct *) tty->driver_data;
+
+ if (!info->xmit_buf)
return;
save_flags(flags);
diff -urN linux-2.4.31/drivers/char/riscom8.c linux-2.4.32/drivers/char/riscom8.c
--- linux-2.4.31/drivers/char/riscom8.c 2005-01-19 06:09:49.000000000 -0800
+++ linux-2.4.32/drivers/char/riscom8.c 2005-11-16 11:12:54.608077868 -0800
@@ -1220,17 +1220,22 @@
static int rc_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- struct riscom_port *port = (struct riscom_port *)tty->driver_data;
+ struct riscom_port *port;
struct riscom_board *bp;
int c, total = 0;
unsigned long flags;
+
+ if (!tty)
+ return 0;
+
+ port = (struct riscom_port *)tty->driver_data;
if (rc_paranoia_check(port, tty->device, "rc_write"))
return 0;
bp = port_Board(port);
- if (!tty || !port->xmit_buf || !tmp_buf)
+ if (!port->xmit_buf || !tmp_buf)
return 0;
save_flags(flags);
@@ -1298,13 +1303,18 @@
static void rc_put_char(struct tty_struct * tty, unsigned char ch)
{
- struct riscom_port *port = (struct riscom_port *)tty->driver_data;
+ struct riscom_port *port;
unsigned long flags;
+ if (!tty)
+ return;
+
+ port = (struct riscom_port *)tty->driver_data;
+
if (rc_paranoia_check(port, tty->device, "rc_put_char"))
return;
- if (!tty || !port->xmit_buf)
+ if (!port->xmit_buf)
return;
save_flags(flags); cli();
diff -urN linux-2.4.31/drivers/char/serial.c linux-2.4.32/drivers/char/serial.c
--- linux-2.4.31/drivers/char/serial.c 2005-01-19 06:09:50.000000000 -0800
+++ linux-2.4.32/drivers/char/serial.c 2005-11-16 11:12:54.612078046 -0800
@@ -1827,13 +1827,18 @@
static void rs_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
+ struct async_struct *info;
unsigned long flags;
+ if (!tty)
+ return;
+
+ info = (struct async_struct *)tty->driver_data;
+
if (serial_paranoia_check(info, tty->device, "rs_put_char"))
return;
- if (!tty || !info->xmit.buf)
+ if (!info->xmit.buf)
return;
save_flags(flags); cli();
@@ -1873,13 +1878,18 @@
const unsigned char *buf, int count)
{
int c, ret = 0;
- struct async_struct *info = (struct async_struct *)tty->driver_data;
+ struct async_struct *info;
unsigned long flags;
+ if (!tty)
+ return 0;
+
+ info = (struct async_struct *)tty->driver_data;
+
if (serial_paranoia_check(info, tty->device, "rs_write"))
return 0;
- if (!tty || !info->xmit.buf || !tmp_buf)
+ if (!info->xmit.buf || !tmp_buf)
return 0;
save_flags(flags);
diff -urN linux-2.4.31/drivers/char/specialix.c linux-2.4.32/drivers/char/specialix.c
--- linux-2.4.31/drivers/char/specialix.c 2005-01-19 06:09:51.000000000 -0800
+++ linux-2.4.32/drivers/char/specialix.c 2005-11-16 11:12:54.613078091 -0800
@@ -1600,17 +1600,22 @@
static int sx_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+ struct specialix_port *port;
struct specialix_board *bp;
int c, total = 0;
unsigned long flags;
+
+ if (!tty)
+ return 0;
+
+ port = (struct specialix_port *)tty->driver_data;
if (sx_paranoia_check(port, tty->device, "sx_write"))
return 0;
bp = port_Board(port);
- if (!tty || !port->xmit_buf || !tmp_buf)
+ if (!port->xmit_buf || !tmp_buf)
return 0;
save_flags(flags);
@@ -1676,13 +1681,18 @@
static void sx_put_char(struct tty_struct * tty, unsigned char ch)
{
- struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+ struct specialix_port *port;
unsigned long flags;
+ if (!tty)
+ return;
+
+ port = (struct specialix_port *)tty->driver_data;
+
if (sx_paranoia_check(port, tty->device, "sx_put_char"))
return;
- if (!tty || !port->xmit_buf)
+ if (!port->xmit_buf)
return;
save_flags(flags); cli();
diff -urN linux-2.4.31/drivers/char/vt.c linux-2.4.32/drivers/char/vt.c
--- linux-2.4.31/drivers/char/vt.c 2005-01-19 06:09:53.000000000 -0800
+++ linux-2.4.32/drivers/char/vt.c 2005-11-16 11:12:54.614078135 -0800
@@ -166,6 +166,9 @@
if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS)
return -EINVAL;
+ if (!capable(CAP_SYS_TTY_CONFIG))
+ perm = 0;
+
switch (cmd) {
case KDGKBENT:
key_map = key_maps[s];
@@ -276,6 +279,9 @@
char *first_free, *fj, *fnw;
int i, j, k;
+ if (!capable(CAP_SYS_TTY_CONFIG))
+ perm = 0;
+
/* we mostly copy too much here (512bytes), but who cares ;) */
if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry)))
return -EFAULT;
diff -urN linux-2.4.31/drivers/md/md.c linux-2.4.32/drivers/md/md.c
--- linux-2.4.31/drivers/md/md.c 2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.32/drivers/md/md.c 2005-11-16 11:12:54.616078224 -0800
@@ -1271,148 +1271,164 @@
memcpy (sb, freshest->sb, sizeof(*sb));
/*
- * at this point we have picked the 'best' superblock
- * from all available superblocks.
- * now we validate this superblock and kick out possibly
- * failed disks.
+ * For multipathing, lots of things are different from "true"
+ * RAIDs.
+ * All rdev's could be read, so they are no longer faulty.
+ * As there is just one sb, trying to find changed devices via the
+ * this_disk pointer is useless too.
+ *
+ * lmb@suse.de, 2002-09-12
*/
- ITERATE_RDEV(mddev,rdev,tmp) {
- /*
- * Kick all non-fresh devices
- */
- __u64 ev1, ev2;
- ev1 = md_event(rdev->sb);
- ev2 = md_event(sb);
- ++ev1;
- if (ev1 < ev2) {
- printk(KERN_WARNING "md: kicking non-fresh %s from array!\n",
- partition_name(rdev->dev));
- kick_rdev_from_array(rdev);
- continue;
- }
- }
- /*
- * Fix up changed device names ... but only if this disk has a
- * recent update time. Use faulty checksum ones too.
- */
- if (mddev->sb->level != -4)
- ITERATE_RDEV(mddev,rdev,tmp) {
- __u64 ev1, ev2, ev3;
- if (rdev->faulty || rdev->alias_device) {
- MD_BUG();
- goto abort;
- }
- ev1 = md_event(rdev->sb);
- ev2 = md_event(sb);
- ev3 = ev2;
- --ev3;
- if ((rdev->dev != rdev->old_dev) &&
- ((ev1 == ev2) || (ev1 == ev3))) {
+ if (sb->level == -4) {
+ int desc_nr = 0;
+
+ /* ... and initialize from the current rdevs instead */
+ ITERATE_RDEV(mddev,rdev,tmp) {
mdp_disk_t *desc;
- printk(KERN_WARNING "md: device name has changed from %s to %s since last import!\n",
- partition_name(rdev->old_dev), partition_name(rdev->dev));
- if (rdev->desc_nr == -1) {
- MD_BUG();
- goto abort;
- }
+ rdev->desc_nr=desc_nr;
+
desc = &sb->disks[rdev->desc_nr];
- if (rdev->old_dev != MKDEV(desc->major, desc->minor)) {
- MD_BUG();
- goto abort;
- }
- desc->major = MAJOR(rdev->dev);
- desc->minor = MINOR(rdev->dev);
- desc = &rdev->sb->this_disk;
+
+ desc->number = desc_nr;
desc->major = MAJOR(rdev->dev);
desc->minor = MINOR(rdev->dev);
- }
- }
+ desc->raid_disk = desc_nr;
- /*
- * Remove unavailable and faulty devices ...
- *
- * note that if an array becomes completely unrunnable due to
- * missing devices, we do not write the superblock back, so the
- * administrator has a chance to fix things up. The removal thus
- * only happens if it's nonfatal to the contents of the array.
- */
- for (i = 0; i < MD_SB_DISKS; i++) {
- int found;
- mdp_disk_t *desc;
- kdev_t dev;
+ /* We could read from it, so it isn't faulty
+ * any longer */
+ if (disk_faulty(desc))
+ mark_disk_spare(desc);
- desc = sb->disks + i;
- dev = MKDEV(desc->major, desc->minor);
+ memcpy(&rdev->sb->this_disk,desc,sizeof(*desc));
+
+ desc_nr++;
+ }
+ /* Kick out all old info about disks we used to have,
+ * if any */
+ for (i = desc_nr; i < MD_SB_DISKS; i++)
+ memset(&(sb->disks[i]),0,sizeof(mdp_disk_t));
+ } else {
/*
- * We kick faulty devices/descriptors immediately.
- *
- * Note: multipath devices are a special case. Since we
- * were able to read the superblock on the path, we don't
- * care if it was previously marked as faulty, it's up now
- * so enable it.
+ * at this point we have picked the 'best' superblock
+ * from all available superblocks.
+ * now we validate this superblock and kick out possibly
+ * failed disks.
*/
- if (disk_faulty(desc) && mddev->sb->level != -4) {
- found = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr != desc->number)
- continue;
- printk(KERN_WARNING "md%d: kicking faulty %s!\n",
- mdidx(mddev),partition_name(rdev->dev));
- kick_rdev_from_array(rdev);
- found = 1;
- break;
- }
- if (!found) {
- if (dev == MKDEV(0,0))
- continue;
- printk(KERN_WARNING "md%d: removing former faulty %s!\n",
- mdidx(mddev), partition_name(dev));
- }
- remove_descriptor(desc, sb);
- continue;
- } else if (disk_faulty(desc)) {
+ ITERATE_RDEV(mddev,rdev,tmp) {
/*
- * multipath entry marked as faulty, unfaulty it
+ * Kick all non-fresh devices
*/
- rdev = find_rdev(mddev, dev);
- if(rdev)
- mark_disk_spare(desc);
- else
- remove_descriptor(desc, sb);
+ __u64 ev1, ev2;
+ ev1 = md_event(rdev->sb);
+ ev2 = md_event(sb);
+ ++ev1;
+ if (ev1 < ev2) {
+ printk(KERN_WARNING "md: kicking non-fresh %s from array!\n",
+ partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ continue;
+ }
}
- if (dev == MKDEV(0,0))
- continue;
/*
- * Is this device present in the rdev ring?
+ * Fix up changed device names ... but only if this disk has a
+ * recent update time. Use faulty checksum ones too.
*/
- found = 0;
ITERATE_RDEV(mddev,rdev,tmp) {
+ __u64 ev1, ev2, ev3;
+ if (rdev->faulty || rdev->alias_device) {
+ MD_BUG();
+ goto abort;
+ }
+ ev1 = md_event(rdev->sb);
+ ev2 = md_event(sb);
+ ev3 = ev2;
+ --ev3;
+ if ((rdev->dev != rdev->old_dev) &&
+ ((ev1 == ev2) || (ev1 == ev3))) {
+ mdp_disk_t *desc;
+
+ printk(KERN_WARNING "md: device name has changed from %s to %s since last import!\n",
+ partition_name(rdev->old_dev), partition_name(rdev->dev));
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
+ goto abort;
+ }
+ desc = &sb->disks[rdev->desc_nr];
+ if (rdev->old_dev != MKDEV(desc->major, desc->minor)) {
+ MD_BUG();
+ goto abort;
+ }
+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);
+ desc = &rdev->sb->this_disk;
+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);
+ }
+ }
+
+ /*
+ * Remove unavailable and faulty devices ...
+ *
+ * note that if an array becomes completely unrunnable due to
+ * missing devices, we do not write the superblock back, so the
+ * administrator has a chance to fix things up. The removal thus
+ * only happens if it's nonfatal to the contents of the array.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ int found;
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
/*
- * Multi-path IO special-case: since we have no
- * this_disk descriptor at auto-detect time,
- * we cannot check rdev->number.
- * We can check the device though.
+ * We kick faulty devices/descriptors immediately.
*/
- if ((sb->level == -4) && (rdev->dev ==
- MKDEV(desc->major,desc->minor))) {
- found = 1;
- break;
+ if (disk_faulty(desc)) {
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr != desc->number)
+ continue;
+ printk(KERN_WARNING "md%d: kicking faulty %s!\n",
+ mdidx(mddev),partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ found = 1;
+ break;
+ }
+ if (!found) {
+ if (dev == MKDEV(0,0))
+ continue;
+ printk(KERN_WARNING "md%d: removing former faulty %s!\n",
+ mdidx(mddev), partition_name(dev));
+ }
+ remove_descriptor(desc, sb);
+ continue;
}
- if (rdev->desc_nr == desc->number) {
- found = 1;
- break;
+
+ if (dev == MKDEV(0,0))
+ continue;
+ /*
+ * Is this device present in the rdev ring?
+ */
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == desc->number) {
+ found = 1;
+ break;
+ }
}
- }
- if (found)
- continue;
+ if (found)
+ continue;
- printk(KERN_WARNING "md%d: former device %s is unavailable, removing from array!\n",
- mdidx(mddev), partition_name(dev));
- remove_descriptor(desc, sb);
+ printk(KERN_WARNING "md%d: former device %s is unavailable, removing from array!\n",
+ mdidx(mddev), partition_name(dev));
+ remove_descriptor(desc, sb);
+ }
}
/*
diff -urN linux-2.4.31/drivers/scsi/ahci.c linux-2.4.32/drivers/scsi/ahci.c
--- linux-2.4.31/drivers/scsi/ahci.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/drivers/scsi/ahci.c 2005-11-16 11:12:54.617078269 -0800
@@ -38,7 +38,8 @@
#include <asm/io.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "1.00"
+#define DRV_VERSION "1.01"
+
enum {
AHCI_PCI_BAR = 5,
@@ -48,6 +49,7 @@
AHCI_CMD_SLOT_SZ = 32 * 32,
AHCI_RX_FIS_SZ = 256,
AHCI_CMD_TBL_HDR = 0x80,
+ AHCI_CMD_TBL_CDB = 0x40,
AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
AHCI_RX_FIS_SZ,
@@ -132,6 +134,9 @@
PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
+
+ /* hpriv->flags bits */
+ AHCI_FLAG_MSI = (1 << 0),
};
struct ahci_cmd_hdr {
@@ -181,13 +186,14 @@
static u8 ahci_check_status(struct ata_port *ap);
static u8 ahci_check_err(struct ata_port *ap);
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+static void ahci_remove_one (struct pci_dev *pdev);
static Scsi_Host_Template ahci_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
.detect = ata_scsi_detect,
.release = ata_scsi_release,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
@@ -256,6 +262,12 @@
board_ahci }, /* ICH7R */
{ PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_ahci }, /* ULi M5288 */
+ { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_ahci }, /* ESB2 */
+ { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_ahci }, /* ESB2 */
+ { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_ahci }, /* ESB2 */
{ } /* terminate list */
};
@@ -264,7 +276,7 @@
.name = DRV_NAME,
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
- .remove = ata_pci_remove_one,
+ .remove = ahci_remove_one,
};
@@ -282,6 +294,8 @@
{
struct ahci_host_priv *hpriv = host_set->private_data;
kfree(hpriv);
+
+ ata_host_stop(host_set);
}
static int ahci_port_start(struct ata_port *ap)
@@ -289,26 +303,19 @@
struct device *dev = ap->host_set->dev;
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp;
- int rc;
void *mem, *mmio = ap->host_set->mmio_base;
void *port_mmio = ahci_port_base(mmio, ap->port_no);
dma_addr_t mem_dma;
- rc = ata_port_start(ap);
- if (rc)
- return rc;
-
pp = kmalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
+ if (!pp)
+ return -ENOMEM;
memset(pp, 0, sizeof(*pp));
mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
if (!mem) {
- rc = -ENOMEM;
- goto err_out_kfree;
+ kfree(pp);
+ return -ENOMEM;
}
memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
@@ -358,12 +365,6 @@
readl(port_mmio + PORT_CMD); /* flush */
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
@@ -389,7 +390,6 @@
dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
pp->cmd_slot, pp->cmd_slot_dma);
kfree(pp);
- ata_port_stop(ap);
}
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
@@ -496,7 +496,8 @@
static void ahci_qc_prep(struct ata_queued_cmd *qc)
{
- struct ahci_port_priv *pp = qc->ap->private_data;
+ struct ata_port *ap = qc->ap;
+ struct ahci_port_priv *pp = ap->private_data;
u32 opts;
const u32 cmd_fis_len = 5; /* five dwords */
@@ -508,18 +509,8 @@
opts = (qc->n_elem << 16) | cmd_fis_len;
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
-
- switch (qc->tf.protocol) {
- case ATA_PROT_ATAPI:
- case ATA_PROT_ATAPI_NODATA:
- case ATA_PROT_ATAPI_DMA:
+ if (is_atapi_taskfile(&qc->tf))
opts |= AHCI_CMD_ATAPI;
- break;
-
- default:
- /* do nothing */
- break;
- }
pp->cmd_slot[0].opts = cpu_to_le32(opts);
pp->cmd_slot[0].status = 0;
@@ -531,6 +522,10 @@
* a SATA Register - Host to Device command FIS.
*/
ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
+ if (opts & AHCI_CMD_ATAPI) {
+ memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
+ memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
+ }
if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return;
@@ -853,15 +848,19 @@
}
/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
+static void pci_intx(struct pci_dev *pdev, int enable)
{
- u16 pci_command;
+ u16 pci_command, new;
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_INTX_DISABLE) {
- pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+
+ if (enable)
+ new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+ else
+ new = pci_command | PCI_COMMAND_INTX_DISABLE;
+
+ if (new != pci_command)
pci_write_config_word(pdev, PCI_COMMAND, pci_command);
- }
}
static void ahci_print_info(struct ata_probe_ent *probe_ent)
@@ -943,7 +942,7 @@
unsigned long base;
void *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
+ int have_msi, pci_dev_busy = 0;
int rc;
VPRINTK("ENTER\n");
@@ -961,12 +960,17 @@
goto err_out;
}
- pci_enable_intx(pdev);
+ if (pci_enable_msi(pdev) == 0)
+ have_msi = 1;
+ else {
+ pci_intx(pdev, 1);
+ have_msi = 0;
+ }
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
- goto err_out_regions;
+ goto err_out_msi;
}
memset(probe_ent, 0, sizeof(*probe_ent));
@@ -999,6 +1003,9 @@
probe_ent->mmio_base = mmio_base;
probe_ent->private_data = hpriv;
+ if (have_msi)
+ hpriv->flags |= AHCI_FLAG_MSI;
+
/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
@@ -1016,7 +1023,11 @@
iounmap(mmio_base);
err_out_free_ent:
kfree(probe_ent);
-err_out_regions:
+err_out_msi:
+ if (have_msi)
+ pci_disable_msi(pdev);
+ else
+ pci_intx(pdev, 0);
pci_release_regions(pdev);
err_out:
if (!pci_dev_busy)
@@ -1024,6 +1035,38 @@
return rc;
}
+static void ahci_remove_one (struct pci_dev *pdev)
+{
+ struct device *dev = pci_dev_to_dev(pdev);
+ struct ata_host_set *host_set = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host_set->private_data;
+ struct ata_port *ap;
+ Scsi_Host_Template *sht;
+ int have_msi, rc;
+
+ /* FIXME: this unregisters all ports attached to the
+ * Scsi_Host_Template given. We _might_ have multiple
+ * templates (though we don't ATM), so this is ok... for now.
+ */
+ ap = host_set->ports[0];
+ sht = ap->host->hostt;
+ rc = scsi_unregister_module(MODULE_SCSI_HA, sht);
+ /* FIXME: handle 'rc' failure? */
+
+ have_msi = hpriv->flags & AHCI_FLAG_MSI;
+ free_irq(host_set->irq, host_set);
+
+ host_set->ops->host_stop(host_set);
+ kfree(host_set);
+
+ if (have_msi)
+ pci_disable_msi(pdev);
+ else
+ pci_intx(pdev, 0);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ dev_set_drvdata(dev, NULL);
+}
static int __init ahci_init(void)
{
diff -urN linux-2.4.31/drivers/scsi/ata_piix.c linux-2.4.32/drivers/scsi/ata_piix.c
--- linux-2.4.31/drivers/scsi/ata_piix.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/drivers/scsi/ata_piix.c 2005-11-16 11:12:54.618078314 -0800
@@ -61,6 +61,7 @@
ich6_sata = 3,
ich6_sata_rm = 4,
ich7_sata = 5,
+ esb2_sata = 6,
};
static int piix_init_one (struct pci_dev *pdev,
@@ -93,6 +94,7 @@
{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
+ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
{ } /* terminate list */
};
@@ -151,6 +153,7 @@
.port_start = ata_port_start,
.port_stop = ata_port_stop,
+ .host_stop = ata_host_stop,
};
static struct ata_port_operations piix_sata_ops = {
@@ -178,6 +181,7 @@
.port_start = ata_port_start,
.port_stop = ata_port_stop,
+ .host_stop = ata_host_stop,
};
static struct ata_port_info piix_port_info[] = {
@@ -256,6 +260,18 @@
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &piix_sata_ops,
},
+
+ /* esb2_sata */
+ {
+ .sht = &piix_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
+ PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
+ ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &piix_sata_ops,
+ },
};
static struct pci_bits piix_enable_bits[] = {
@@ -650,15 +666,6 @@
return ata_pci_init_one(pdev, port_info, n_ports);
}
-/**
- * piix_init -
- *
- * LOCKING:
- *
- * RETURNS:
- *
- */
-
static int __init piix_init(void)
{
int rc;
@@ -685,13 +692,6 @@
return rc;
}
-/**
- * piix_exit -
- *
- * LOCKING:
- *
- */
-
static void __exit piix_exit(void)
{
scsi_unregister_module(MODULE_SCSI_HA, &piix_sht);
diff -urN linux-2.4.31/drivers/scsi/libata-core.c linux-2.4.32/drivers/scsi/libata-core.c
--- linux-2.4.31/drivers/scsi/libata-core.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/drivers/scsi/libata-core.c 2005-11-16 11:12:54.622078492 -0800
@@ -185,6 +185,28 @@
ata_wait_idle(ap);
}
+
+/**
+ * ata_tf_load - send taskfile registers to host controller
+ * @ap: Port to which output is sent
+ * @tf: ATA taskfile register set
+ *
+ * Outputs ATA taskfile to standard ATA host controller using MMIO
+ * or PIO as indicated by the ATA_FLAG_MMIO flag.
+ * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ * hob_lbal, hob_lbam, and hob_lbah.
+ *
+ * This function waits for idle (!BUSY and !DRQ) after writing
+ * registers. If the control register has a new value, this
+ * function also waits for idle after writing control and before
+ * writing the remaining registers.
+ *
+ * May be used as the tf_load() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
@@ -194,11 +216,11 @@
}
/**
- * ata_exec_command - issue ATA command to host controller
+ * ata_exec_command_pio - issue ATA command to host controller
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
*
- * Issues PIO/MMIO write to ATA command register, with proper
+ * Issues PIO write to ATA command register, with proper
* synchronization with interrupt handler / other threads.
*
* LOCKING:
@@ -234,6 +256,18 @@
ata_pause(ap);
}
+
+/**
+ * ata_exec_command - issue ATA command to host controller
+ * @ap: port to which command is being issued
+ * @tf: ATA taskfile register set
+ *
+ * Issues PIO/MMIO write to ATA command register, with proper
+ * synchronization with interrupt handler / other threads.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
@@ -304,7 +338,7 @@
}
/**
- * ata_tf_read - input device's ATA taskfile shadow registers
+ * ata_tf_read_pio - input device's ATA taskfile shadow registers
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
@@ -367,6 +401,23 @@
}
}
+
+/**
+ * ata_tf_read - input device's ATA taskfile shadow registers
+ * @ap: Port from which input is read
+ * @tf: ATA taskfile register set for storing input
+ *
+ * Reads ATA taskfile registers for currently-selected device
+ * into @tf.
+ *
+ * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
+ * is set, also reads the hob registers.
+ *
+ * May be used as the tf_read() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
if (ap->flags & ATA_FLAG_MMIO)
@@ -380,7 +431,7 @@
* @ap: port where the device is
*
* Reads ATA taskfile status register for currently-selected device
- * and return it's value. This also clears pending interrupts
+ * and return its value. This also clears pending interrupts
* from this device
*
* LOCKING:
@@ -396,7 +447,7 @@
* @ap: port where the device is
*
* Reads ATA taskfile status register for currently-selected device
- * via MMIO and return it's value. This also clears pending interrupts
+ * via MMIO and return its value. This also clears pending interrupts
* from this device
*
* LOCKING:
@@ -407,6 +458,20 @@
return readb((void __iomem *) ap->ioaddr.status_addr);
}
+
+/**
+ * ata_check_status - Read device status reg & clear interrupt
+ * @ap: port where the device is
+ *
+ * Reads ATA taskfile status register for currently-selected device
+ * and return its value. This also clears pending interrupts
+ * from this device
+ *
+ * May be used as the check_status() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
u8 ata_check_status(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO)
@@ -414,6 +479,20 @@
return ata_check_status_pio(ap);
}
+
+/**
+ * ata_altstatus - Read device alternate status reg
+ * @ap: port where the device is
+ *
+ * Reads ATA taskfile alternate status register for
+ * currently-selected device and return its value.
+ *
+ * Note: may NOT be used as the check_altstatus() entry in
+ * ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
u8 ata_altstatus(struct ata_port *ap)
{
if (ap->ops->check_altstatus)
@@ -424,6 +503,20 @@
return inb(ap->ioaddr.altstatus_addr);
}
+
+/**
+ * ata_chk_err - Read device error reg
+ * @ap: port where the device is
+ *
+ * Reads ATA taskfile error register for
+ * currently-selected device and return its value.
+ *
+ * Note: may NOT be used as the check_err() entry in
+ * ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
u8 ata_chk_err(struct ata_port *ap)
{
if (ap->ops->check_err)
@@ -872,10 +965,24 @@
}
}
+
+/**
+ * ata_noop_dev_select - Select device 0/1 on ATA bus
+ * @ap: ATA channel to manipulate
+ * @device: ATA device (numbered from zero) to select
+ *
+ * This function performs no actual function.
+ *
+ * May be used as the dev_select() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * caller.
+ */
void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
{
}
+
/**
* ata_std_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
@@ -883,7 +990,9 @@
*
* Use the method defined in the ATA specification to
* make either device 0, or device 1, active on the
- * ATA channel.
+ * ATA channel. Works with both PIO and MMIO.
+ *
+ * May be used as the dev_select() entry in ata_port_operations.
*
* LOCKING:
* caller.
@@ -1185,11 +1294,47 @@
DPRINTK("EXIT, err\n");
}
+
+static inline u8 ata_dev_knobble(struct ata_port *ap)
+{
+ return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
+}
+
+/**
+ * ata_dev_config - Run device specific handlers and check for
+ * SATA->PATA bridges
+ * @ap: Bus
+ * @i: Device
+ *
+ * LOCKING:
+ */
+
+void ata_dev_config(struct ata_port *ap, unsigned int i)
+{
+ /* limit bridge transfers to udma5, 200 sectors */
+ if (ata_dev_knobble(ap)) {
+ printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
+ ap->id, ap->device->devno);
+ ap->udma_mask &= ATA_UDMA5;
+ ap->host->max_sectors = ATA_MAX_SECTORS;
+ ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
+ ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
+ }
+
+ if (ap->ops->dev_config)
+ ap->ops->dev_config(ap, &ap->device[i]);
+}
+
/**
* ata_bus_probe - Reset and probe ATA bus
* @ap: Bus to probe
*
+ * Master ATA bus probing function. Initiates a hardware-dependent
+ * bus reset, then attempts to identify any devices found on
+ * the bus.
+ *
* LOCKING:
+ * PCI/etc. bus probe sem.
*
* RETURNS:
* Zero on success, non-zero on error.
@@ -1207,8 +1352,7 @@
ata_dev_identify(ap, i);
if (ata_dev_present(&ap->device[i])) {
found = 1;
- if (ap->ops->dev_config)
- ap->ops->dev_config(ap, &ap->device[i]);
+ ata_dev_config(ap,i);
}
}
@@ -1228,10 +1372,14 @@
}
/**
- * ata_port_probe -
- * @ap:
+ * ata_port_probe - Mark port as enabled
+ * @ap: Port for which we indicate enablement
*
- * LOCKING:
+ * Modify @ap data structure such that the system
+ * thinks that the entire port is enabled.
+ *
+ * LOCKING: host_set lock, or some other form of
+ * serialization.
*/
void ata_port_probe(struct ata_port *ap)
@@ -1240,10 +1388,15 @@
}
/**
- * __sata_phy_reset -
- * @ap:
+ * __sata_phy_reset - Wake/reset a low-level SATA PHY
+ * @ap: SATA port associated with target SATA PHY.
+ *
+ * This function issues commands to standard SATA Sxxx
+ * PHY registers, to wake up the phy (and device), and
+ * clear any reset condition.
*
* LOCKING:
+ * PCI/etc. bus probe sem.
*
*/
void __sata_phy_reset(struct ata_port *ap)
@@ -1252,11 +1405,13 @@
unsigned long timeout = jiffies + (HZ * 5);
if (ap->flags & ATA_FLAG_SATA_RESET) {
- scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
- scr_read(ap, SCR_STATUS); /* dummy read; flush */
- udelay(400); /* FIXME: a guess */
+ /* issue phy wake/reset */
+ scr_write_flush(ap, SCR_CONTROL, 0x301);
+ /* Couldn't find anything in SATA I/II specs, but
+ * AHCI-1.1 10.4.2 says at least 1 ms. */
+ mdelay(1);
}
- scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */
+ scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
/* wait for phy to become ready, if necessary */
do {
@@ -1288,10 +1443,14 @@
}
/**
- * __sata_phy_reset -
- * @ap:
+ * sata_phy_reset - Reset SATA bus.
+ * @ap: SATA port associated with target SATA PHY.
+ *
+ * This function resets the SATA bus, and then probes
+ * the bus for devices.
*
* LOCKING:
+ * PCI/etc. bus probe sem.
*
*/
void sata_phy_reset(struct ata_port *ap)
@@ -1303,10 +1462,16 @@
}
/**
- * ata_port_disable -
- * @ap:
+ * ata_port_disable - Disable port.
+ * @ap: Port to be disabled.
*
- * LOCKING:
+ * Modify @ap data structure such that the system
+ * thinks that the entire port is disabled, and should
+ * never attempt to probe or communicate with devices
+ * on this port.
+ *
+ * LOCKING: host_set lock, or some other form of
+ * serialization.
*/
void ata_port_disable(struct ata_port *ap)
@@ -1415,7 +1580,10 @@
* ata_set_mode - Program timings and issue SET FEATURES - XFER
* @ap: port on which timings will be programmed
*
+ * Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
+ *
* LOCKING:
+ * PCI/etc. bus probe sem.
*
*/
static void ata_set_mode(struct ata_port *ap)
@@ -1466,7 +1634,10 @@
* @tmout_pat: impatience timeout
* @tmout: overall timeout
*
- * LOCKING:
+ * Sleep until ATA Status register bit BSY clears,
+ * or a timeout occurs.
+ *
+ * LOCKING: None.
*
*/
@@ -1552,10 +1723,14 @@
}
/**
- * ata_bus_edd -
- * @ap:
+ * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
+ * @ap: Port to reset and probe
+ *
+ * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
+ * probe the bus. Not often used these days.
*
* LOCKING:
+ * PCI/etc. bus probe sem.
*
*/
@@ -1632,8 +1807,8 @@
* the device is ATA or ATAPI.
*
* LOCKING:
- * Inherited from caller. Some functions called by this function
- * obtain the host_set lock.
+ * PCI/etc. bus probe sem.
+ * Obtains host_set lock.
*
* SIDE EFFECTS:
* Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
@@ -1746,6 +1921,7 @@
"HITACHI CDR-8335",
"HITACHI CDR-8435",
"Toshiba CD-ROM XM-6202B",
+ "TOSHIBA CD-ROM XM-1702BC",
"CD-532E-A",
"E-IDE CD-ROM CR-840",
"CD-ROM Drive/F5A",
@@ -1753,7 +1929,6 @@
"SAMSUNG CD-ROM SC-148C",
"SAMSUNG CD-ROM SC",
"SanDisk SDP3B-64",
- "SAMSUNG CD-ROM SN-124",
"ATAPI CD-ROM DRIVE 40X MAXIMUM",
"_NEC DV5800A",
};
@@ -1875,7 +2050,11 @@
* @xfer_mode_out: (output) SET FEATURES - XFER MODE code
* @xfer_shift_out: (output) bit shift that selects this mode
*
+ * Based on host and device capabilities, determine the
+ * maximum transfer mode that is amenable to all.
+ *
* LOCKING:
+ * PCI/etc. bus probe sem.
*
* RETURNS:
* Zero on success, negative on error.
@@ -1908,7 +2087,11 @@
* @ap: Port associated with device @dev
* @dev: Device to which command will be sent
*
+ * Issue SET FEATURES - XFER MODE command to device @dev
+ * on port @ap.
+ *
* LOCKING:
+ * PCI/etc. bus probe sem.
*/
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
@@ -1946,10 +2129,13 @@
}
/**
- * ata_sg_clean -
- * @qc:
+ * ata_sg_clean - Unmap DMA memory associated with command
+ * @qc: Command containing DMA memory to be released
+ *
+ * Unmap all mapped DMA memory associated with this command.
*
* LOCKING:
+ * spin_lock_irqsave(host_set lock)
*/
static void ata_sg_clean(struct ata_queued_cmd *qc)
@@ -1980,7 +2166,11 @@
* ata_fill_sg - Fill PCI IDE PRD table
* @qc: Metadata associated with taskfile to be transferred
*
+ * Fill PCI IDE PRD (scatter-gather) table with segments
+ * associated with the current disk command.
+ *
* LOCKING:
+ * spin_lock_irqsave(host_set lock)
*
*/
static void ata_fill_sg(struct ata_queued_cmd *qc)
@@ -2027,7 +2217,13 @@
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
* @qc: Metadata associated with taskfile to check
*
+ * Allow low-level driver to filter ATA PACKET commands, returning
+ * a status indicating whether or not it is OK to use DMA for the
+ * supplied PACKET command.
+ *
* LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ *
* RETURNS: 0 when ATAPI DMA can be used
* nonzero otherwise
*/
@@ -2045,6 +2241,8 @@
* ata_qc_prep - Prepare taskfile for submission
* @qc: Metadata associated with taskfile to be prepared
*
+ * Prepare ATA taskfile for submission.
+ *
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
@@ -2056,6 +2254,32 @@
ata_fill_sg(qc);
}
+/**
+ * ata_sg_init_one - Associate command with memory buffer
+ * @qc: Command to be associated
+ * @buf: Memory buffer
+ * @buflen: Length of memory buffer, in bytes.
+ *
+ * Initialize the data-related elements of queued_cmd @qc
+ * to point to a single memory buffer, @buf of byte length @buflen.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
+
+
+/**
+ * ata_sg_init_one - Prepare a one-entry scatter-gather list.
+ * @qc: Queued command
+ * @buf: transfer buffer
+ * @buflen: length of buf
+ *
+ * Builds a single-entry scatter-gather list to initiate a
+ * transfer utilizing the specified buffer.
+ *
+ * LOCKING:
+ */
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
{
struct scatterlist *sg;
@@ -2070,9 +2294,35 @@
sg = qc->sg;
sg->page = virt_to_page(buf);
sg->offset = (unsigned long) buf & ~PAGE_MASK;
- sg_dma_len(sg) = buflen;
+ sg->length = buflen;
}
+/**
+ * ata_sg_init - Associate command with scatter-gather table.
+ * @qc: Command to be associated
+ * @sg: Scatter-gather table.
+ * @n_elem: Number of elements in s/g table.
+ *
+ * Initialize the data-related elements of queued_cmd @qc
+ * to point to a scatter-gather table @sg, containing @n_elem
+ * elements.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
+
+/**
+ * ata_sg_init - Assign a scatter gather list to a queued command
+ * @qc: Queued command
+ * @sg: Scatter-gather list
+ * @n_elem: length of sg list
+ *
+ * Attaches a scatter-gather list to a queued command.
+ *
+ * LOCKING:
+ */
+
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem)
{
@@ -2082,14 +2332,16 @@
}
/**
- * ata_sg_setup_one -
- * @qc:
+ * ata_sg_setup_one - DMA-map the memory buffer associated with a command.
+ * @qc: Command with memory buffer to be mapped.
+ *
+ * DMA-map the memory buffer associated with queued_cmd @qc.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
- *
+ * Zero on success, negative on error.
*/
static int ata_sg_setup_one(struct ata_queued_cmd *qc)
@@ -2100,11 +2352,12 @@
dma_addr_t dma_address;
dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
- sg_dma_len(sg), dir);
+ sg->length, dir);
if (dma_mapping_error(dma_address))
return -1;
sg_dma_address(sg) = dma_address;
+ sg_dma_len(sg) = sg->length;
DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
@@ -2113,13 +2366,16 @@
}
/**
- * ata_sg_setup -
- * @qc:
+ * ata_sg_setup - DMA-map the scatter-gather table associated with a command.
+ * @qc: Command with scatter-gather table to be mapped.
+ *
+ * DMA-map the scatter-gather table associated with queued_cmd @qc.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
+ * Zero on success, negative on error.
*
*/
@@ -2149,6 +2405,7 @@
* @ap:
*
* LOCKING:
+ * None. (executing in kernel thread context)
*
* RETURNS:
*
@@ -2196,6 +2453,7 @@
* @ap:
*
* LOCKING:
+ * None. (executing in kernel thread context)
*/
static void ata_pio_complete (struct ata_port *ap)
@@ -2238,6 +2496,18 @@
ata_qc_complete(qc, drv_stat);
}
+
+/**
+ * swap_buf_le16 -
+ * @buf: Buffer to swap
+ * @buf_words: Number of 16-bit words in buffer.
+ *
+ * Swap halves of 16-bit words if needed to convert from
+ * little-endian byte order to native cpu byte order, or
+ * vice-versa.
+ *
+ * LOCKING:
+ */
void swap_buf_le16(u16 *buf, unsigned int buf_words)
{
#ifdef __BIG_ENDIAN
@@ -2309,7 +2579,7 @@
qc->cursect++;
qc->cursg_ofs++;
- if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
+ if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -2338,7 +2608,6 @@
next_sg:
sg = &qc->sg[qc->cursg];
-next_page:
page = sg->page;
offset = sg->offset + qc->cursg_ofs;
@@ -2346,7 +2615,8 @@
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
- count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
+ /* don't overrun current sg */
+ count = min(sg->length - qc->cursg_ofs, bytes);
/* don't cross page boundaries */
count = min(count, (unsigned int)PAGE_SIZE - offset);
@@ -2357,7 +2627,7 @@
qc->curbytes += count;
qc->cursg_ofs += count;
- if (qc->cursg_ofs == sg_dma_len(sg)) {
+ if (qc->cursg_ofs == sg->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -2370,8 +2640,6 @@
kunmap(page);
if (bytes) {
- if (qc->cursg_ofs < sg_dma_len(sg))
- goto next_page;
goto next_sg;
}
}
@@ -2413,6 +2681,7 @@
* @ap:
*
* LOCKING:
+ * None. (executing in kernel thread context)
*/
static void ata_pio_block(struct ata_port *ap)
@@ -2539,7 +2808,7 @@
ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
qc->dma_dir = DMA_FROM_DEVICE;
- memset(&qc->cdb, 0, sizeof(ap->cdb_len));
+ memset(&qc->cdb, 0, ap->cdb_len);
qc->cdb[0] = REQUEST_SENSE;
qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
@@ -2582,6 +2851,7 @@
* transaction completed successfully.
*
* LOCKING:
+ * Inherited from SCSI layer (none, can sleep)
*/
static void ata_qc_timeout(struct ata_queued_cmd *qc)
@@ -2691,6 +2961,7 @@
* @dev: Device from whom we request an available command structure
*
* LOCKING:
+ * None.
*/
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
@@ -2716,6 +2987,7 @@
* @dev: Device from whom we request an available command structure
*
* LOCKING:
+ * None.
*/
struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
@@ -2780,6 +3052,7 @@
* in case something prevents using it.
*
* LOCKING:
+ * spin_lock_irqsave(host_set lock)
*
*/
void ata_qc_free(struct ata_queued_cmd *qc)
@@ -2793,9 +3066,13 @@
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
- * @drv_stat: ATA status register contents
+ * @drv_stat: ATA Status register contents
+ *
+ * Indicate to the mid and upper layers that an ATA
+ * command has completed, with either an ok or not-ok status.
*
* LOCKING:
+ * spin_lock_irqsave(host_set lock)
*
*/
@@ -2811,6 +3088,7 @@
/* call completion callback */
rc = qc->complete_fn(qc, drv_stat);
+ qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* if callback indicates not to complete command (non-zero),
* return immediately
@@ -2839,7 +3117,7 @@
return 1;
/* fall through */
-
+
default:
return 0;
}
@@ -2890,6 +3168,7 @@
return -1;
}
+
/**
* ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
* @qc: command to issue to device
@@ -2899,6 +3178,8 @@
* classes called "protocols", and issuing each type of protocol
* is slightly different.
*
+ * May be used as the qc_issue() entry in ata_port_operations.
+ *
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
@@ -2956,7 +3237,7 @@
}
/**
- * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
@@ -3063,6 +3344,18 @@
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
+
+/**
+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * Writes the ATA_DMA_START flag to the DMA command register.
+ *
+ * May be used as the bmdma_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
void ata_bmdma_start(struct ata_queued_cmd *qc)
{
if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3071,6 +3364,20 @@
ata_bmdma_start_pio(qc);
}
+
+/**
+ * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * Writes address of PRD table to device's PRD Table Address
+ * register, sets the DMA control register, and calls
+ * ops->exec_command() to start the transfer.
+ *
+ * May be used as the bmdma_setup() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
void ata_bmdma_setup(struct ata_queued_cmd *qc)
{
if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3079,6 +3386,19 @@
ata_bmdma_setup_pio(qc);
}
+
+/**
+ * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Clear interrupt and error flags in DMA status register.
+ *
+ * May be used as the irq_clear() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
void ata_bmdma_irq_clear(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
@@ -3091,6 +3411,19 @@
}
+
+/**
+ * ata_bmdma_status - Read PCI IDE BMDMA status
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Read and return BMDMA status register.
+ *
+ * May be used as the bmdma_status() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
u8 ata_bmdma_status(struct ata_port *ap)
{
u8 host_stat;
@@ -3102,6 +3435,19 @@
return host_stat;
}
+
+/**
+ * ata_bmdma_stop - Stop PCI IDE BMDMA transfer
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Clears the ATA_DMA_START flag in the dma control register
+ *
+ * May be used as the bmdma_stop() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+
void ata_bmdma_stop(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
@@ -3201,13 +3547,18 @@
/**
* ata_interrupt - Default ATA host interrupt handler
- * @irq: irq line
- * @dev_instance: pointer to our host information structure
+ * @irq: irq line (unused)
+ * @dev_instance: pointer to our ata_host_set information structure
* @regs: unused
*
+ * Default interrupt handler for PCI IDE devices. Calls
+ * ata_host_intr() for each port that is not disabled.
+ *
* LOCKING:
+ * Obtains host_set lock during operation.
*
* RETURNS:
+ * IRQ_NONE or IRQ_HANDLED.
*
*/
@@ -3229,7 +3580,8 @@
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
- if (qc && (!(qc->tf.ctl & ATA_NIEN)))
+ if (qc && (!(qc->tf.ctl & ATA_NIEN)) &&
+ (qc->flags & ATA_QCFLAG_ACTIVE))
handled |= ata_host_intr(ap, qc);
}
}
@@ -3299,6 +3651,19 @@
ata_qc_complete(qc, ATA_ERR);
}
+
+/**
+ * ata_port_start - Set port up for dma.
+ * @ap: Port to initialize
+ *
+ * Called just after data structures for each port are
+ * initialized. Allocates space for PRD table.
+ *
+ * May be used as the port_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ */
+
int ata_port_start (struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
@@ -3312,6 +3677,18 @@
return 0;
}
+
+/**
+ * ata_port_stop - Undo ata_port_start()
+ * @ap: Port to shut down
+ *
+ * Frees the PRD table.
+ *
+ * May be used as the port_stop() entry in ata_port_operations.
+ *
+ * LOCKING:
+ */
+
void ata_port_stop (struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
@@ -3319,6 +3696,13 @@
dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
}
+void ata_host_stop (struct ata_host_set *host_set)
+{
+ if (host_set->mmio_base)
+ iounmap(host_set->mmio_base);
+}
+
+
/**
* ata_host_remove - Unregister SCSI host structure with upper layers
* @ap: Port to unregister
@@ -3347,7 +3731,11 @@
* @ent: Probe information provided by low-level driver
* @port_no: Port number associated with this ata_port
*
+ * Initialize a new ata_port structure, and its associated
+ * scsi_host.
+ *
* LOCKING:
+ * Inherited from caller.
*
*/
@@ -3401,9 +3789,13 @@
* @host_set: Collections of ports to which we add
* @port_no: Port number associated with this host
*
+ * Attach low-level ATA driver to system.
+ *
* LOCKING:
+ * PCI/etc. bus probe sem.
*
* RETURNS:
+ * New ata_port on success, for NULL on error.
*
*/
@@ -3436,12 +3828,22 @@
}
/**
- * ata_device_add -
- * @ent:
+ * ata_device_add - Register hardware device with ATA and SCSI layers
+ * @ent: Probe information describing hardware device to be registered
+ *
+ * This function processes the information provided in the probe
+ * information struct @ent, allocates the necessary ATA and SCSI
+ * host information structures, initializes them, and registers
+ * everything with requisite kernel subsystems.
+ *
+ * This function requests irqs, probes the ATA bus, and probes
+ * the SCSI bus.
*
* LOCKING:
+ * PCI/etc. bus probe sem.
*
* RETURNS:
+ * Number of ports registered. Zero on error (no ports registered).
*
*/
@@ -3612,7 +4014,15 @@
/**
* ata_std_ports - initialize ioaddr with standard port offsets.
* @ioaddr: IO address structure to be initialized
+ *
+ * Utility function which initializes data_addr, error_addr,
+ * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+ * device_addr, status_addr, and command_addr to standard offsets
+ * relative to cmd_addr.
+ *
+ * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
*/
+
void ata_std_ports(struct ata_ioports *ioaddr)
{
ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
@@ -3654,6 +4064,20 @@
return probe_ent;
}
+
+
+/**
+ * ata_pci_init_native_mode - Initialize native-mode driver
+ * @pdev: pci device to be initialized
+ * @port: array[2] of pointers to port info structures.
+ *
+ * Utility function which allocates and initializes an
+ * ata_probe_ent structure for a standard dual-port
+ * PIO-based IDE controller. The returned ata_probe_ent
+ * structure can be passed to ata_device_add(). The returned
+ * ata_probe_ent structure should then be freed with kfree().
+ */
+
#ifdef CONFIG_PCI
struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
@@ -3735,10 +4159,19 @@
* @port_info: Information from low-level host driver
* @n_ports: Number of ports attached to host controller
*
+ * This is a helper function which can be called from a driver's
+ * xxx_init_one() probe function if the hardware uses traditional
+ * IDE taskfile registers.
+ *
+ * This function calls pci_enable_device(), reserves its register
+ * regions, sets the dma mask, enables bus master mode, and calls
+ * ata_device_add()
+ *
* LOCKING:
* Inherited from PCI layer (may sleep).
*
* RETURNS:
+ * Zero on success, negative on errno-based value on error.
*
*/
@@ -3882,10 +4315,6 @@
/* FIXME: handle 'rc' failure? */
free_irq(host_set->irq, host_set);
- if (host_set->ops->host_stop)
- host_set->ops->host_stop(host_set);
- if (host_set->mmio_base)
- iounmap(host_set->mmio_base);
for (i = 0; i < host_set->n_ports; i++) {
ap = host_set->ports[i];
@@ -3900,6 +4329,9 @@
}
}
+ if (host_set->ops->host_stop)
+ host_set->ops->host_stop(host_set);
+
kfree(host_set);
pci_release_regions(pdev);
@@ -3958,15 +4390,6 @@
#endif /* CONFIG_PCI */
-/**
- * ata_init -
- *
- * LOCKING:
- *
- * RETURNS:
- *
- */
-
static int __init ata_init(void)
{
printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
@@ -4007,6 +4430,7 @@
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
+EXPORT_SYMBOL_GPL(ata_host_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
@@ -4029,6 +4453,7 @@
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(ata_dev_classify);
EXPORT_SYMBOL_GPL(ata_dev_id_string);
+EXPORT_SYMBOL_GPL(ata_dev_config);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
#ifdef CONFIG_PCI
diff -urN linux-2.4.31/drivers/scsi/libata-scsi.c linux-2.4.32/drivers/scsi/libata-scsi.c
--- linux-2.4.31/drivers/scsi/libata-scsi.c 2005-05-31 17:56:56.000000000 -0700
+++ linux-2.4.32/drivers/scsi/libata-scsi.c 2005-11-16 11:12:54.623078536 -0800
@@ -906,7 +906,7 @@
}
/**
- * ata_scsiop_noop -
+ * ata_scsiop_noop - Command handler that simply returns success.
* @args: device IDENTIFY data / SCSI command of interest.
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
@@ -1135,8 +1135,12 @@
n_sectors = ata_id_u32(args->id, 60);
n_sectors--; /* ATA TotalUserSectors - 1 */
- tmp = n_sectors; /* note: truncates, if lba48 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
+ if( n_sectors >= 0xffffffffULL )
+ tmp = 0xffffffff ; /* Return max count on overflow */
+ else
+ tmp = n_sectors ;
+
/* sector count, 32-bit */
rbuf[0] = tmp >> (8 * 3);
rbuf[1] = tmp >> (8 * 2);
@@ -1150,10 +1154,12 @@
} else {
/* sector count, 64-bit */
- rbuf[2] = n_sectors >> (8 * 7);
- rbuf[3] = n_sectors >> (8 * 6);
- rbuf[4] = n_sectors >> (8 * 5);
- rbuf[5] = n_sectors >> (8 * 4);
+ tmp = n_sectors >> (8 * 4);
+ rbuf[2] = tmp >> (8 * 3);
+ rbuf[3] = tmp >> (8 * 2);
+ rbuf[4] = tmp >> (8 * 1);
+ rbuf[5] = tmp;
+ tmp = n_sectors;
rbuf[6] = tmp >> (8 * 3);
rbuf[7] = tmp >> (8 * 2);
rbuf[8] = tmp >> (8 * 1);
diff -urN linux-2.4.31/drivers/scsi/libata.h linux-2.4.32/drivers/scsi/libata.h
--- linux-2.4.31/drivers/scsi/libata.h 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/drivers/scsi/libata.h 2005-11-16 11:12:54.623078536 -0800
@@ -26,7 +26,7 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
-#define DRV_VERSION "1.10" /* must be exactly four chars */
+#define DRV_VERSION "1.11" /* must be exactly four chars */
struct ata_scsi_args {
u16 *id;
diff -urN linux-2.4.31/drivers/scsi/megaraid2.c linux-2.4.32/drivers/scsi/megaraid2.c
--- linux-2.4.31/drivers/scsi/megaraid2.c 2005-04-03 18:42:19.000000000 -0700
+++ linux-2.4.32/drivers/scsi/megaraid2.c 2005-11-16 11:12:54.627078715 -0800
@@ -14,7 +14,7 @@
* - speed-ups (list handling fixes, issued_list, optimizations.)
* - lots of cleanups.
*
- * Version : v2.10.8.2 (July 26, 2004)
+ * Version : v2.10.10.1 (January 27, 2005)
*
* Authors: Atul Mukker <Atul.Mukker@lsil.com>
* Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
@@ -46,7 +46,7 @@
#include "megaraid2.h"
-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
#include <asm/ioctl32.h>
#endif
@@ -181,7 +181,7 @@
/*
* Scan PCI bus for our all devices.
*/
- for( i = 0; i < sizeof(dev_sw_table)/sizeof(u16); i += 2 ) {
+ for( i = 0; i < ((int) (sizeof(dev_sw_table)/sizeof(u16))); i += 2 ) {
mega_find_card(host_template, dev_sw_table[i],
dev_sw_table[i+1]);
@@ -233,7 +233,7 @@
"MegaRAID Shutdown routine not registered!!\n");
}
-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
/*
* Register the 32-bit ioctl conversion
*/
@@ -341,6 +341,7 @@
(subsysvid != INTEL_SUBSYS_VID) &&
(subsysvid != FSC_SUBSYS_VID) &&
(subsysvid != ACER_SUBSYS_VID) &&
+ (subsysvid != NEC_SUBSYS_VID) &&
(subsysvid != LSI_SUBSYS_VID) ) continue;
@@ -821,6 +822,78 @@
}
+/**
+ * issue_scb()
+ * @adapter - pointer to our soft state
+ * @scb - scsi control block
+ *
+ * Post a command to the card if the mailbox is available, otherwise return
+ * busy. We also take the scb from the pending list if the mailbox is
+ * available.
+ */
+static inline int
+issue_scb(adapter_t *adapter, scb_t *scb)
+{
+ volatile mbox64_t *mbox64 = adapter->mbox64;
+ volatile mbox_t *mbox = adapter->mbox;
+ unsigned int i = 0;
+
+ if(unlikely(mbox->busy)) {
+ do {
+ udelay(1);
+ i++;
+ } while( mbox->busy && (i < max_mbox_busy_wait) );
+
+ if(mbox->busy) return -1;
+ }
+
+ /* Copy mailbox data into host structure */
+ memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
+
+ mbox->cmdid = scb->idx; /* Set cmdid */
+ mbox->busy = 1; /* Set busy */
+
+
+ /*
+ * Increment the pending queue counter
+ */
+ atomic_inc(&adapter->pend_cmds);
+
+ switch (mbox->cmd) {
+ case MEGA_MBOXCMD_EXTPTHRU:
+ if( !adapter->has_64bit_addr ) break;
+ // else fall through
+ case MEGA_MBOXCMD_LREAD64:
+ case MEGA_MBOXCMD_LWRITE64:
+ case MEGA_MBOXCMD_PASSTHRU64:
+ mbox64->xfer_segment_lo = mbox->xferaddr;
+ mbox64->xfer_segment_hi = 0;
+ mbox->xferaddr = 0xFFFFFFFF;
+ break;
+ default:
+ mbox64->xfer_segment_lo = 0;
+ mbox64->xfer_segment_hi = 0;
+ }
+
+ /*
+ * post the command
+ */
+ scb->state |= SCB_ISSUED;
+
+ if( likely(adapter->flag & BOARD_MEMMAP) ) {
+ mbox->poll = 0;
+ mbox->ack = 0;
+ WRINDOOR(adapter, adapter->mbox_dma | 0x1);
+ }
+ else {
+ irq_enable(adapter);
+ issue_command(adapter);
+ }
+
+ return 0;
+}
+
+
/*
* mega_query_adapter()
* @adapter - pointer to our soft state
@@ -990,78 +1063,6 @@
/**
- * issue_scb()
- * @adapter - pointer to our soft state
- * @scb - scsi control block
- *
- * Post a command to the card if the mailbox is available, otherwise return
- * busy. We also take the scb from the pending list if the mailbox is
- * available.
- */
-static inline int
-issue_scb(adapter_t *adapter, scb_t *scb)
-{
- volatile mbox64_t *mbox64 = adapter->mbox64;
- volatile mbox_t *mbox = adapter->mbox;
- unsigned int i = 0;
-
- if(unlikely(mbox->busy)) {
- do {
- udelay(1);
- i++;
- } while( mbox->busy && (i < max_mbox_busy_wait) );
-
- if(mbox->busy) return -1;
- }
-
- /* Copy mailbox data into host structure */
- memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
-
- mbox->cmdid = scb->idx; /* Set cmdid */
- mbox->busy = 1; /* Set busy */
-
-
- /*
- * Increment the pending queue counter
- */
- atomic_inc(&adapter->pend_cmds);
-
- switch (mbox->cmd) {
- case MEGA_MBOXCMD_EXTPTHRU:
- if( !adapter->has_64bit_addr ) break;
- // else fall through
- case MEGA_MBOXCMD_LREAD64:
- case MEGA_MBOXCMD_LWRITE64:
- case MEGA_MBOXCMD_PASSTHRU64:
- mbox64->xfer_segment_lo = mbox->xferaddr;
- mbox64->xfer_segment_hi = 0;
- mbox->xferaddr = 0xFFFFFFFF;
- break;
- default:
- mbox64->xfer_segment_lo = 0;
- mbox64->xfer_segment_hi = 0;
- }
-
- /*
- * post the command
- */
- scb->state |= SCB_ISSUED;
-
- if( likely(adapter->flag & BOARD_MEMMAP) ) {
- mbox->poll = 0;
- mbox->ack = 0;
- WRINDOOR(adapter, adapter->mbox_dma | 0x1);
- }
- else {
- irq_enable(adapter);
- issue_command(adapter);
- }
-
- return 0;
-}
-
-
-/**
* mega_runpendq()
* @adapter - pointer to our soft state
*
@@ -1074,7 +1075,6 @@
__mega_runpendq(adapter);
}
-
static void
__mega_runpendq(adapter_t *adapter)
{
@@ -1176,80 +1176,6 @@
return ldrv_num;
}
-/*
- * Wait until the controller's mailbox is available
- */
-static inline int
-mega_busywait_mbox (adapter_t *adapter)
-{
- if (adapter->mbox->busy)
- return __mega_busywait_mbox(adapter);
- return 0;
-}
-
-
-/**
- * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
- * @adapter - controller's soft state
- *
- * Interrupt ackrowledgement sequence for IO mapped HBAs
- */
-static inline void
-megaraid_iombox_ack_sequence(adapter_t *adapter)
-{
- u8 status;
- u8 nstatus;
- u8 completed[MAX_FIRMWARE_STATUS];
- u8 byte;
- int i;
-
-
- /*
- * loop till F/W has more commands for us to complete.
- */
- do {
- /* Check if a valid interrupt is pending */
- byte = irq_state(adapter);
- if( (byte & VALID_INTR_BYTE) == 0 ) {
- return;
- }
- set_irq_state(adapter, byte);
-
- while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
- cpu_relax();
- }
- adapter->mbox->numstatus = 0xFF;
-
- for (i = 0; i < nstatus; i++) {
- while ((completed[i] = adapter->mbox->completed[i])
- == 0xFF) {
- cpu_relax();
- }
-
- adapter->mbox->completed[i] = 0xFF;
- }
-
- // we must read the valid status now
- if ((status = adapter->mbox->status) == 0xFF) {
- printk(KERN_WARNING
- "megaraid critical: status 0xFF from firmware.\n");
- }
- adapter->mbox->status = 0xFF;
-
- /*
- * decrement the pending queue counter
- */
- atomic_sub(nstatus, &adapter->pend_cmds);
-
- /* Acknowledge interrupt */
- irq_ack(adapter);
-
- mega_cmd_done(adapter, completed, nstatus, status);
-
- } while(1);
-}
-
-
/*
* megaraid_queue()
@@ -1755,8 +1681,8 @@
pthru = scb->pthru;
memset(pthru, 0, sizeof (mega_passthru));
- /* 0=6sec/1=60sec/2=10min/3=3hrs */
- pthru->timeout = 2;
+ /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */
+ pthru->timeout = 4;
pthru->ars = 1;
pthru->reqsenselen = 14;
@@ -1819,8 +1745,8 @@
epthru = scb->epthru;
memset(epthru, 0, sizeof(mega_ext_passthru));
- /* 0=6sec/1=60sec/2=10min/3=3hrs */
- epthru->timeout = 2;
+ /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */
+ epthru->timeout = 4;
epthru->ars = 1;
epthru->reqsenselen = 14;
@@ -1862,6 +1788,32 @@
}
+/*
+ * Wait until the controller's mailbox is available
+ */
+static inline int
+mega_busywait_mbox (adapter_t *adapter)
+{
+ if (adapter->mbox->busy)
+ return __mega_busywait_mbox(adapter);
+ return 0;
+}
+
+static int
+__mega_busywait_mbox (adapter_t *adapter)
+{
+ volatile mbox_t *mbox = adapter->mbox;
+ long counter;
+
+ for (counter = 0; counter < 10000; counter++) {
+ if (!mbox->busy)
+ return 0;
+ udelay(100); yield();
+ }
+ return -1; /* give up after 1 second */
+}
+
+
/**
* issue_scb_block()
* @adapter - pointer to our soft state
@@ -1962,137 +1914,7 @@
return -1;
}
-
-/**
- * megaraid_isr_iomapped()
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
- *
- * Interrupt service routine for io-mapped controllers.
- * Find out if our device is interrupting. If yes, acknowledge the interrupt
- * and service the completed commands.
- */
-static void
-megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
-{
- adapter_t *adapter = devp;
- unsigned long flags;
-
-
- spin_lock_irqsave(adapter->host_lock, flags);
-
- megaraid_iombox_ack_sequence(adapter);
-
- /* Loop through any pending requests */
- if( atomic_read(&adapter->quiescent ) == 0) {
- mega_runpendq(adapter);
- }
-
- spin_unlock_irqrestore(adapter->host_lock, flags);
-
- return;
-}
-
-
-/**
- * megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped HBAs
- * @adapter - controller's soft state
- *
- * Interrupt ackrowledgement sequence for memory mapped HBAs
- */
-static inline void
-megaraid_memmbox_ack_sequence(adapter_t *adapter)
-{
- u8 status;
- u32 dword = 0;
- u8 nstatus;
- u8 completed[MAX_FIRMWARE_STATUS];
- int i;
-
-
- /*
- * loop till F/W has more commands for us to complete.
- */
- do {
- /* Check if a valid interrupt is pending */
- dword = RDOUTDOOR(adapter);
- if( dword != 0x10001234 ) {
- /*
- * No more pending commands
- */
- return;
- }
- WROUTDOOR(adapter, 0x10001234);
-
- while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
- cpu_relax();
- }
- adapter->mbox->numstatus = 0xFF;
-
- for (i = 0; i < nstatus; i++ ) {
- while ((completed[i] = adapter->mbox->completed[i])
- == 0xFF) {
- cpu_relax();
- }
-
- adapter->mbox->completed[i] = 0xFF;
- }
-
- // we must read the valid status now
- if ((status = adapter->mbox->status) == 0xFF) {
- printk(KERN_WARNING
- "megaraid critical: status 0xFF from firmware.\n");
- }
- adapter->mbox->status = 0xFF;
-
- /*
- * decrement the pending queue counter
- */
- atomic_sub(nstatus, &adapter->pend_cmds);
-
- /* Acknowledge interrupt */
- WRINDOOR(adapter, 0x2);
-
- while( RDINDOOR(adapter) & 0x02 ) cpu_relax();
-
- mega_cmd_done(adapter, completed, nstatus, status);
-
- } while(1);
-}
-
-
-/**
- * megaraid_isr_memmapped()
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
- *
- * Interrupt service routine for memory-mapped controllers.
- * Find out if our device is interrupting. If yes, acknowledge the interrupt
- * and service the completed commands.
- */
-static void
-megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
-{
- adapter_t *adapter = devp;
- unsigned long flags;
-
-
- spin_lock_irqsave(adapter->host_lock, flags);
-
- megaraid_memmbox_ack_sequence(adapter);
-
- /* Loop through any pending requests */
- if(atomic_read(&adapter->quiescent) == 0) {
- mega_runpendq(adapter);
- }
-
- spin_unlock_irqrestore(adapter->host_lock, flags);
-
- return;
-}
-
+
/**
* mega_cmd_done()
* @adapter - pointer to our soft state
@@ -2102,7 +1924,7 @@
*
* Complete the comamnds and call the scsi mid-layer callback hooks.
*/
-static void
+static inline void
mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
{
mega_ext_passthru *epthru = NULL;
@@ -2351,6 +2173,197 @@
}
+/**
+ * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
+ * @adapter - controller's soft state
+ *
+ * Interrupt ackrowledgement sequence for IO mapped HBAs
+ */
+static inline void
+megaraid_iombox_ack_sequence(adapter_t *adapter)
+{
+ u8 status;
+ int nstatus;
+ u8 completed[MAX_FIRMWARE_STATUS];
+ u8 byte;
+ int i;
+
+
+ /*
+ * loop till F/W has more commands for us to complete.
+ */
+ do {
+ /* Check if a valid interrupt is pending */
+ byte = irq_state(adapter);
+ if( (byte & VALID_INTR_BYTE) == 0 ) {
+ return;
+ }
+ set_irq_state(adapter, byte);
+
+ while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
+ cpu_relax();
+ }
+ adapter->mbox->numstatus = 0xFF;
+
+ for (i = 0; i < nstatus; i++) {
+ while ((completed[i] = adapter->mbox->completed[i])
+ == 0xFF) {
+ cpu_relax();
+ }
+
+ adapter->mbox->completed[i] = 0xFF;
+ }
+
+ // we must read the valid status now
+ if ((status = adapter->mbox->status) == 0xFF) {
+ printk(KERN_WARNING
+ "megaraid critical: status 0xFF from firmware.\n");
+ }
+ adapter->mbox->status = 0xFF;
+
+ /*
+ * decrement the pending queue counter
+ */
+ atomic_sub(nstatus, &adapter->pend_cmds);
+
+ /* Acknowledge interrupt */
+ irq_ack(adapter);
+
+ mega_cmd_done(adapter, completed, nstatus, status);
+
+ } while(1);
+}
+
+
+/**
+ * megaraid_isr_iomapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for io-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
+{
+ adapter_t *adapter = devp;
+ unsigned long flags;
+
+ spin_lock_irqsave(adapter->host_lock, flags);
+
+ megaraid_iombox_ack_sequence(adapter);
+
+ /* Loop through any pending requests */
+ if( atomic_read(&adapter->quiescent ) == 0) {
+ mega_runpendq(adapter);
+ }
+
+ spin_unlock_irqrestore(adapter->host_lock, flags);
+
+ return;
+}
+
+
+/**
+ * megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped HBAs
+ * @adapter - controller's soft state
+ *
+ * Interrupt ackrowledgement sequence for memory mapped HBAs
+ */
+static inline void
+megaraid_memmbox_ack_sequence(adapter_t *adapter)
+{
+ u8 status;
+ u32 dword = 0;
+ int nstatus;
+ u8 completed[MAX_FIRMWARE_STATUS];
+ int i;
+
+
+ /*
+ * loop till F/W has more commands for us to complete.
+ */
+ do {
+ /* Check if a valid interrupt is pending */
+ dword = RDOUTDOOR(adapter);
+ if( dword != 0x10001234 ) {
+ /*
+ * No more pending commands
+ */
+ return;
+ }
+ WROUTDOOR(adapter, 0x10001234);
+
+ while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
+ cpu_relax();
+ }
+ adapter->mbox->numstatus = 0xFF;
+
+ for (i = 0; i < nstatus; i++ ) {
+ while ((completed[i] = adapter->mbox->completed[i])
+ == 0xFF) {
+ cpu_relax();
+ }
+
+ adapter->mbox->completed[i] = 0xFF;
+ }
+
+ // we must read the valid status now
+ if ((status = adapter->mbox->status) == 0xFF) {
+ printk(KERN_WARNING
+ "megaraid critical: status 0xFF from firmware.\n");
+ }
+ adapter->mbox->status = 0xFF;
+
+ /*
+ * decrement the pending queue counter
+ */
+ atomic_sub(nstatus, &adapter->pend_cmds);
+
+ /* Acknowledge interrupt */
+ WRINDOOR(adapter, 0x2);
+
+ while( RDINDOOR(adapter) & 0x02 ) cpu_relax();
+
+ mega_cmd_done(adapter, completed, nstatus, status);
+
+ } while(1);
+}
+
+
+/**
+ * megaraid_isr_memmapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for memory-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
+{
+ adapter_t *adapter = devp;
+ unsigned long flags;
+
+ spin_lock_irqsave(adapter->host_lock, flags);
+
+ megaraid_memmbox_ack_sequence(adapter);
+
+ /* Loop through any pending requests */
+ if(atomic_read(&adapter->quiescent) == 0) {
+ mega_runpendq(adapter);
+ }
+
+ spin_unlock_irqrestore(adapter->host_lock, flags);
+
+ return;
+}
+
+
/*
* Free a SCB structure
* Note: We assume the scsi commands associated with this scb is not free yet.
@@ -2404,19 +2417,6 @@
list_add(&scb->list, &adapter->free_list);
}
-static int
-__mega_busywait_mbox (adapter_t *adapter)
-{
- volatile mbox_t *mbox = adapter->mbox;
- long counter;
-
- for (counter = 0; counter < 10000; counter++) {
- if (!mbox->busy)
- return 0;
- udelay(100); yield();
- }
- return -1; /* give up after 1 second */
-}
/*
* Copies data to SGLIST
@@ -2434,7 +2434,7 @@
cmd = scb->cmd;
- /* return 0 elements if no data transfer */
+ // return 0 elements if no data transfer
if (!cmd->request_buffer || !cmd->request_bufflen)
return 0;
@@ -2561,6 +2561,7 @@
enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
}
+
static inline void
mega_free_sgl(adapter_t *adapter)
{
@@ -2726,7 +2727,7 @@
*/
scsi_unregister(host);
-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
unregister_ioctl32_conversion(MEGAIOCCMD);
#endif
@@ -2835,7 +2836,6 @@
return SUCCESS;
}
-
static int
megaraid_reset(Scsi_Cmnd *cmd)
{
@@ -2903,12 +2903,10 @@
/*
* Perform the ack sequence, since interrupts are unavailable
*/
- if( adapter->flag & BOARD_MEMMAP ) {
+ if (adapter->flag & BOARD_MEMMAP)
megaraid_memmbox_ack_sequence(adapter);
- }
- else {
+ else
megaraid_iombox_ack_sequence(adapter);
- }
spin_unlock(adapter->host_lock);
@@ -2941,7 +2939,6 @@
return rval;
}
-
#ifdef CONFIG_PROC_FS
/* Following code handles /proc fs */
@@ -3200,6 +3197,7 @@
return len;
}
+
/**
* mega_allocate_inquiry()
* @dma_handle - handle returned for dma address
@@ -3582,7 +3580,7 @@
* Check for overflow. We print less than 240
* characters for inquiry
*/
- if( (len + 240) >= PAGE_SIZE ) break;
+ if( (len + 240) >= ((int) PAGE_SIZE) ) break;
len += sprintf(page+len, "%s.\n", str);
@@ -3886,7 +3884,7 @@
* Check for overflow. We print less than 240 characters for
* information about each logical drive.
*/
- if( (len + 240) >= PAGE_SIZE ) break;
+ if( (len + 240) >= ((int) PAGE_SIZE) ) break;
len += sprintf(page+len, "Logical drive:%2d:, ", i);
@@ -4172,7 +4170,7 @@
}
-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
static int
megadev_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
struct file *filep)
@@ -4221,7 +4219,7 @@
megacmd_t mc;
megastat_t *ustats;
int num_ldrv;
- u32 uxferaddr = 0;
+ caddr_t uxferaddr=NULL;
struct pci_dev *pdev;
ustats = NULL; /* avoid compilation warnings */
@@ -4251,13 +4249,13 @@
switch( uioc.opcode ) {
case GET_DRIVER_VER:
- if( put_user(driver_ver, (u32 *)uioc.uioc_uaddr) )
+ if( put_user(driver_ver, (u32 *)uioc.u_dataaddr) )
return (-EFAULT);
break;
case GET_N_ADAP:
- if( put_user(hba_count, (u32 *)uioc.uioc_uaddr) )
+ if( put_user(hba_count, (u32 *)uioc.u_dataaddr) )
return (-EFAULT);
/*
@@ -4275,7 +4273,7 @@
if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
return (-ENODEV);
- if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno,
+ if( copy_to_user(uioc.u_dataaddr, mcontroller+adapno,
sizeof(struct mcontroller)) )
return (-EFAULT);
break;
@@ -4291,7 +4289,7 @@
adapter = hba_soft_state[adapno];
- ustats = (megastat_t *)uioc.uioc_uaddr;
+ ustats = (megastat_t *)uioc.u_dataaddr;
if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) )
return (-EFAULT);
@@ -4333,7 +4331,7 @@
/*
* Which adapter
*/
- if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+ if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
return (-ENODEV);
adapter = hba_soft_state[adapno];
@@ -4342,37 +4340,37 @@
* Deletion of logical drive is a special case. The adapter
* should be quiescent before this command is issued.
*/
- if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV &&
- uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) {
+ if( RMBOX(uioc)[0] == FC_DEL_LOGDRV ) {
+ if ( RMBOX(uioc)[2] == OP_DEL_LOGDRV ) {
+ /*
+ * Do we support this feature
+ */
+ if( !adapter->support_random_del ) {
+ printk(KERN_WARNING "megaraid: logdrv ");
+ printk("delete on non-supporting F/W.\n");
- /*
- * Do we support this feature
- */
- if( !adapter->support_random_del ) {
- printk(KERN_WARNING "megaraid: logdrv ");
- printk("delete on non-supporting F/W.\n");
+ return (-EINVAL);
+ }
- return (-EINVAL);
- }
+ rval = mega_del_logdrv( adapter, RMBOX(uioc)[3] );
- rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3] );
+ if( rval == 0 ) {
+ memset(&mc, 0, sizeof(megacmd_t));
- if( rval == 0 ) {
- memset(&mc, 0, sizeof(megacmd_t));
+ mc.status = rval;
- mc.status = rval;
+ rval = mega_n_to_m((void *)arg, &mc);
+ }
- rval = mega_n_to_m((void *)arg, &mc);
+ return rval;
}
-
- return rval;
}
/*
* This interface only support the regular passthru commands.
* Reject extended passthru and 64-bit passthru
*/
- if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 ||
- uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) {
+ if( RMBOX(uioc)[0] == MEGA_MBOXCMD_PASSTHRU64 ||
+ RMBOX(uioc)[0] == MEGA_MBOXCMD_EXTPTHRU ) {
printk(KERN_WARNING "megaraid: rejected passthru.\n");