diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/Documentation/Changes linux-2.4.30-rc1/Documentation/Changes --- linux-2.4.29/Documentation/Changes 2005-01-19 14:09:22.000000000 +0000 +++ linux-2.4.30-rc1/Documentation/Changes 2005-03-18 18:08:19.111776592 +0000 @@ -341,7 +341,7 @@ o +o Reiserfsprogs ------------- diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/Documentation/Configure.help linux-2.4.30-rc1/Documentation/Configure.help --- linux-2.4.29/Documentation/Configure.help 2005-01-19 14:09:22.000000000 +0000 +++ linux-2.4.30-rc1/Documentation/Configure.help 2005-03-18 18:08:19.575706064 +0000 @@ -9345,6 +9345,11 @@ CONFIG_SCSI_SATA_PROMISE If unsure, say N. +CONFIG_SCSI_SATA_QSTOR + This option enables support for Pacific Digital Serial ATA QStor. + + If unsure, say N. + CONFIG_SCSI_SATA_SX4 This option enables support for Promise Serial ATA SX4. diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/Documentation/filesystems/jfs.txt linux-2.4.30-rc1/Documentation/filesystems/jfs.txt --- linux-2.4.29/Documentation/filesystems/jfs.txt 2003-11-28 18:26:19.000000000 +0000 +++ linux-2.4.30-rc1/Documentation/filesystems/jfs.txt 2005-03-18 18:07:38.810903256 +0000 @@ -1,13 +1,6 @@ IBM's Journaled File System (JFS) for Linux -JFS Homepage: http://oss.software.ibm.com/jfs/ - -Team members ------------- -Dave Kleikamp shaggy@austin.ibm.com -Dave Blaschke blaschke@us.ibm.com -Steve Best sbest@us.ibm.com -Barry Arndt barndt@us.ibm.com +JFS Homepage: http://jfs.sourceforge.net/ The following mount options are supported: @@ -15,7 +8,8 @@ iocharset=name Character set to use for ASCII. The default is compiled into the kernel as CONFIG_NLS_DEFAULT. Use iocharset=utf8 for UTF8 translations. This requires CONFIG_NLS_UTF8 to be set - in the kernel .config file. + in the kernel .config file. Specify iocharset=none for + no conversion (default linux-2.6 behavior). resize=value Resize the volume to blocks. JFS only supports growing a volume, not shrinking it. This option is only @@ -51,4 +45,4 @@ Longer term work items Please send bugs, comments, cards and letters to shaggy@austin.ibm.com. The JFS mailing list can be subscribed to by using the link labeled -"Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/. +"Mail list Subscribe" at our web page http://jfs.sourceforge.net/. diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/Documentation/i2c/writing-clients linux-2.4.30-rc1/Documentation/i2c/writing-clients --- linux-2.4.29/Documentation/i2c/writing-clients 2004-11-17 11:54:20.000000000 +0000 +++ linux-2.4.30-rc1/Documentation/i2c/writing-clients 2005-03-18 18:06:41.337640520 +0000 @@ -380,9 +380,6 @@ detection just fails for this address, r For now, you can ignore the `flags' parameter. It is there for future use. - /* Unique ID allocation */ - static int foo_id = 0; - int foo_detect_client(struct i2c_adapter *adapter, int address, unsigned short flags, int kind) { @@ -518,7 +515,6 @@ For now, you can ignore the `flags' para data->type = kind; /* SENSORS ONLY END */ - new_client->id = foo_id++; /* Automatically unique */ data->valid = 0; /* Only if you use this field */ init_MUTEX(&data->update_lock); /* Only if you use this field */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/MAINTAINERS linux-2.4.30-rc1/MAINTAINERS --- linux-2.4.29/MAINTAINERS 2005-01-19 14:09:24.000000000 +0000 +++ linux-2.4.30-rc1/MAINTAINERS 2005-03-18 18:07:42.152395272 +0000 @@ -1058,8 +1058,8 @@ S: Maintained JFS FILESYSTEM P: Dave Kleikamp M: shaggy@austin.ibm.com -L: jfs-discussion@oss.software.ibm.com -W: http://oss.software.ibm.com/developerworks/opensource/jfs/ +L: jfs-discussion@lists.sourceforge.net +W: http://jfs.sourceforge.net/ S: Supported JOYSTICK DRIVER @@ -1532,7 +1532,7 @@ S: Maintained PPP OVER ETHERNET P: Michal Ostrowski -M: mostrows@styx.uwaterloo.ca +M: mostrows@speakeasy.net S: Maintained PRISM54 WIRELESS DRIVER diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/Makefile linux-2.4.30-rc1/Makefile --- linux-2.4.29/Makefile 2005-01-19 14:10:14.000000000 +0000 +++ linux-2.4.30-rc1/Makefile 2005-03-18 18:07:49.761238552 +0000 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 29 -EXTRAVERSION = +SUBLEVEL = 30 +EXTRAVERSION = -rc1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/Makefile linux-2.4.30-rc1/arch/i386/kernel/Makefile --- linux-2.4.29/arch/i386/kernel/Makefile 2003-11-28 18:26:19.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/Makefile 2005-03-18 18:06:38.875014896 +0000 @@ -40,7 +40,7 @@ obj-$(CONFIG_ACPI_BOOT) += acpi.o obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o -obj-$(CONFIG_X86_IO_APIC) += io_apic.o +obj-$(CONFIG_X86_IO_APIC) += io_apic.o earlyquirk.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o obj-$(CONFIG_EDD) += edd.o diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/acpi.c linux-2.4.30-rc1/arch/i386/kernel/acpi.c --- linux-2.4.29/arch/i386/kernel/acpi.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/acpi.c 2005-03-18 18:08:09.298268472 +0000 @@ -55,6 +55,7 @@ int acpi_strict; acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; +int acpi_skip_timer_override __initdata; /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -320,6 +321,12 @@ acpi_parse_int_src_ovr ( return 0; } + if (acpi_skip_timer_override && + intsrc->bus_irq == 0 && intsrc->global_irq == 2) { + printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); + return 0; + } + mp_override_legacy_irq ( intsrc->bus_irq, intsrc->flags.polarity, @@ -433,6 +440,10 @@ acpi_boot_init (void) return result; } +#ifdef CONFIG_X86_IOAPIC + check_acpi_pci(); +#endif + result = acpi_blacklisted(); if (result) { printk(KERN_NOTICE PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/earlyquirk.c linux-2.4.30-rc1/arch/i386/kernel/earlyquirk.c --- linux-2.4.29/arch/i386/kernel/earlyquirk.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/earlyquirk.c 2005-03-18 18:07:33.809663560 +0000 @@ -0,0 +1,53 @@ +/* + * Do early PCI probing for bug detection when the main PCI subsystem is + * not up yet. + */ +#include +#include +#include +#include +#include + +#ifdef CONFIG_ACPI_BOOT +static int __init check_bridge(int vendor, int device) +{ + /* According to Nvidia all timer overrides are bogus. Just ignore + them all. */ + if (vendor == PCI_VENDOR_ID_NVIDIA) { + acpi_skip_timer_override = 1; + } + return 0; +} + +void __init check_acpi_pci(void) +{ + int num,slot,func; + + /* Assume the machine supports type 1. If not it will + always read ffffffff and should not have any side effect. */ + + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class; + u32 vendor; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) + continue; + + vendor = read_pci_config(num, slot, func, + PCI_VENDOR_ID); + + if (check_bridge(vendor&0xffff, vendor >> 16)) + return; + } + + } + } +} +#endif /* CONFIG_ACPI */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/i387.c linux-2.4.30-rc1/arch/i386/kernel/i387.c --- linux-2.4.29/arch/i386/kernel/i387.c 2003-08-25 11:44:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/i387.c 2005-03-18 18:08:34.311465888 +0000 @@ -128,16 +128,17 @@ static inline unsigned short twd_i387_to static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) { struct _fpxreg *st = NULL; + unsigned long tos = (fxsave->swd >> 11) & 7; unsigned long twd = (unsigned long) fxsave->twd; unsigned long tag; unsigned long ret = 0xffff0000; int i; -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); +#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16); for ( i = 0 ; i < 8 ; i++ ) { if ( twd & 0x1 ) { - st = (struct _fpxreg *) FPREG_ADDR( fxsave, i ); + st = FPREG_ADDR( fxsave, (i - tos) & 7 ); switch ( st->exponent & 0x7fff ) { case 0x7fff: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/pci-irq.c linux-2.4.30-rc1/arch/i386/kernel/pci-irq.c --- linux-2.4.29/arch/i386/kernel/pci-irq.c 2005-01-19 14:09:25.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/pci-irq.c 2005-03-18 18:08:30.289077384 +0000 @@ -1120,13 +1120,15 @@ void pcibios_penalize_isa_irq(int irq) void pcibios_enable_irq(struct pci_dev *dev) { u8 pin; - extern int interrupt_line_quirk; + extern int via_interrupt_line_quirk; struct pci_dev *temp_dev; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { char *msg; + pin--; /* interrupt pins are numbered starting from 1 */ + /* With IDE legacy devices the IRQ lookup failure is not a problem.. */ if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5)) return; @@ -1134,46 +1136,43 @@ void pcibios_enable_irq(struct pci_dev * if (io_apic_assign_pci_irqs) { int irq; - if (pin) { - pin--; /* interrupt pins are numbered starting from 1 */ - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); - /* - * Busses behind bridges are typically not listed in the MP-table. - * In this case we have to look up the IRQ based on the parent bus, - * parent slot, and pin number. The SMP code detects such bridged - * busses itself so we should get into this branch reliably. - */ - temp_dev = dev; - while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ - struct pci_dev * bridge = dev->bus->self; + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + /* + * Busses behind bridges are typically not listed in the MP-table. + * In this case we have to look up the IRQ based on the parent bus, + * parent slot, and pin number. The SMP code detects such bridged + * busses itself so we should get into this branch reliably. + */ + temp_dev = dev; + while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ + struct pci_dev * bridge = dev->bus->self; - pin = (pin + PCI_SLOT(dev->devfn)) % 4; - irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); - if (irq >= 0) - printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", - bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); - dev = bridge; - } - dev = temp_dev; - if (irq >= 0) { - printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", - dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); - dev->irq = irq; - return; - } else - msg = " Probably buggy MP table."; + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); + if (irq >= 0) + printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); + dev = bridge; } + dev = temp_dev; + if (irq >= 0) { + printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", + dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); + dev->irq = irq; + return; + } else + msg = " Probably buggy MP table."; } else if (pci_probe & PCI_BIOS_IRQ_SCAN) msg = ""; else msg = " Please try using pci=biosirq."; printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", - 'A' + pin - 1, dev->slot_name, msg); + 'A' + pin, dev->slot_name, msg); } /* VIA bridges use interrupt line for apic/pci steering across the V-Link */ - else if (interrupt_line_quirk) + else if (via_interrupt_line_quirk) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15); } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/kernel/setup.c linux-2.4.30-rc1/arch/i386/kernel/setup.c --- linux-2.4.29/arch/i386/kernel/setup.c 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/kernel/setup.c 2005-03-18 18:07:24.828028976 +0000 @@ -354,7 +354,8 @@ static char command_line[COMMAND_LINE_SI struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, { "pic1", 0x20, 0x3f, IORESOURCE_BUSY }, - { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, + { "timer0", 0x40, 0x43, IORESOURCE_BUSY }, + { "timer1", 0x50, 0x53, IORESOURCE_BUSY }, { "keyboard", 0x60, 0x6f, IORESOURCE_BUSY }, { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, { "pic2", 0xa0, 0xbf, IORESOURCE_BUSY }, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/i386/lib/usercopy.c linux-2.4.30-rc1/arch/i386/lib/usercopy.c --- linux-2.4.29/arch/i386/lib/usercopy.c 2003-06-13 14:51:29.000000000 +0000 +++ linux-2.4.30-rc1/arch/i386/lib/usercopy.c 2005-03-18 18:06:13.471876760 +0000 @@ -14,6 +14,7 @@ unsigned long __generic_copy_to_user(void *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); if (access_ok(VERIFY_WRITE, to, n)) { if(n<512) @@ -27,6 +28,7 @@ __generic_copy_to_user(void *to, const v unsigned long __generic_copy_from_user(void *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); if (access_ok(VERIFY_READ, from, n)) { if(n<512) @@ -44,6 +46,7 @@ __generic_copy_from_user(void *to, const unsigned long __generic_copy_to_user(void *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); prefetch(from); if (access_ok(VERIFY_WRITE, to, n)) __copy_user(to,from,n); @@ -53,6 +56,7 @@ __generic_copy_to_user(void *to, const v unsigned long __generic_copy_from_user(void *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); prefetchw(to); if (access_ok(VERIFY_READ, from, n)) __copy_user_zeroing(to,from,n); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/ia64/ia32/sys_ia32.c linux-2.4.30-rc1/arch/ia64/ia32/sys_ia32.c --- linux-2.4.29/arch/ia64/ia32/sys_ia32.c 2005-01-19 14:09:26.000000000 +0000 +++ linux-2.4.30-rc1/arch/ia64/ia32/sys_ia32.c 2005-03-18 18:07:43.290222296 +0000 @@ -1649,7 +1649,8 @@ scm_detach_fds32 (struct msghdr *kmsg, s * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ static void -cmsg32_recvmsg_fixup (struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +cmsg32_recvmsg_fixup (struct msghdr *kmsg, unsigned long orig_cmsg_uptr, + __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -1683,6 +1684,9 @@ cmsg32_recvmsg_fixup (struct msghdr *kms goto fail2; clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -1812,6 +1816,7 @@ sys32_recvmsg (int fd, struct msghdr32 * struct iovec *iov=iovstack; struct msghdr msg_sys; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, iov_size, total_len, len; struct scm_cookie scm; @@ -1856,6 +1861,7 @@ sys32_recvmsg (int fd, struct msghdr32 * total_len=err; cmsg_ptr = (unsigned long)msg_sys.msg_control; + cmsg_len = msg_sys.msg_controllen; msg_sys.msg_flags = 0; if (sock->file->f_flags & O_NONBLOCK) @@ -1882,7 +1888,8 @@ sys32_recvmsg (int fd, struct msghdr32 * * fix it up before we tack on more stuff. */ if ((unsigned long) msg_sys.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&msg_sys, cmsg_ptr); + cmsg32_recvmsg_fixup(&msg_sys, cmsg_ptr, + cmsg_len); /* Wheee... */ if (sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/mips64/kernel/linux32.c linux-2.4.30-rc1/arch/mips64/kernel/linux32.c --- linux-2.4.29/arch/mips64/kernel/linux32.c 2005-01-19 14:09:32.000000000 +0000 +++ linux-2.4.30-rc1/arch/mips64/kernel/linux32.c 2005-03-18 18:07:44.194084888 +0000 @@ -1088,11 +1088,9 @@ do_readv_writev32(int type, struct file i--; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); + retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); if (retval) { if (iov != iovstack) kfree(iov); @@ -2792,7 +2790,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -2823,6 +2822,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -2908,6 +2910,7 @@ asmlinkage int sys32_recvmsg(int fd, str struct sockaddr *uaddr; int *uaddr_len; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, total_len, len = 0; if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) @@ -2923,6 +2926,7 @@ asmlinkage int sys32_recvmsg(int fd, str total_len = err; cmsg_ptr = (unsigned long) kern_msg.msg_control; + cmsg_len = kern_msg.msg_controllen; kern_msg.msg_flags = 0; sock = sockfd_lookup(fd, &err); @@ -2948,7 +2952,8 @@ asmlinkage int sys32_recvmsg(int fd, str * to fix it up before we tack on more stuff. */ if((unsigned long) kern_msg.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + cmsg32_recvmsg_fixup(&kern_msg, + cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/parisc/kernel/sys_parisc32.c linux-2.4.30-rc1/arch/parisc/kernel/sys_parisc32.c --- linux-2.4.29/arch/parisc/kernel/sys_parisc32.c 2005-01-19 14:09:35.000000000 +0000 +++ linux-2.4.30-rc1/arch/parisc/kernel/sys_parisc32.c 2005-03-18 18:06:56.198381344 +0000 @@ -1671,11 +1671,9 @@ do_readv_writev32(int type, struct file i--; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); + retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); if (retval) { if (iov != iovstack) kfree(iov); @@ -2108,7 +2106,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -2139,6 +2138,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -2224,6 +2226,7 @@ asmlinkage int sys32_recvmsg(int fd, str struct sockaddr *uaddr; int *uaddr_len; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, total_len, len = 0; if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) @@ -2239,6 +2242,7 @@ asmlinkage int sys32_recvmsg(int fd, str total_len = err; cmsg_ptr = (unsigned long) kern_msg.msg_control; + cmsg_len = kern_msg.msg_controllen; kern_msg.msg_flags = 0; sock = sockfd_lookup(fd, &err); @@ -2264,7 +2268,8 @@ asmlinkage int sys32_recvmsg(int fd, str * to fix it up before we tack on more stuff. */ if((unsigned long) kern_msg.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + cmsg32_recvmsg_fixup(&kern_msg, + cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/ppc/kernel/cputable.c linux-2.4.30-rc1/arch/ppc/kernel/cputable.c --- linux-2.4.29/arch/ppc/kernel/cputable.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/arch/ppc/kernel/cputable.c 2005-03-18 18:07:33.526706576 +0000 @@ -480,8 +480,8 @@ struct cpu_spec cpu_specs[] = { 32, 32, 0, /*__setup_cpu_440 */ }, - { /* 440GX Rev. B1 (2.1) */ - 0xf0000fff, 0x50000852, "440GX Rev. B1 (2.1)", + { /* 440GX Rev. C */ + 0xf0000fff, 0x50000892, "440GX Rev. C", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 32, 32, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/ppc/kernel/head_8xx.S linux-2.4.30-rc1/arch/ppc/kernel/head_8xx.S --- linux-2.4.29/arch/ppc/kernel/head_8xx.S 2004-02-18 13:36:30.000000000 +0000 +++ linux-2.4.30-rc1/arch/ppc/kernel/head_8xx.S 2005-03-18 18:07:23.872174288 +0000 @@ -338,13 +338,13 @@ InstructionTLBMiss: 3: lwz r21, 0(r20) /* Get the level 1 entry */ rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */ - beq 2f /* If zero, don't try to find a pte */ /* We have a pte table, so load the MI_TWC with the attributes * for this "segment." */ tophys(r21,r21) ori r21,r21,1 /* Set valid bit */ + beq- 2f /* If zero, don't try to find a pte */ #ifdef CONFIG_8xx_CPU6 li r3, 0x2b80 stw r3, 12(r0) @@ -369,7 +369,7 @@ InstructionTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x00f0 +2: li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ #ifdef CONFIG_8xx_CPU6 @@ -388,15 +388,6 @@ InstructionTLBMiss: #endif rfi -2: mfspr r20, M_TW /* Restore registers */ - lwz r21, 0(r0) - mtcr r21 - lwz r21, 4(r0) -#ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) -#endif - b InstructionAccess - . = 0x1200 DataStoreTLBMiss: #ifdef CONFIG_8xx_CPU6 @@ -422,12 +413,12 @@ DataStoreTLBMiss: 3: lwz r21, 0(r20) /* Get the level 1 entry */ rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */ - beq 2f /* If zero, don't try to find a pte */ /* We have a pte table, so load fetch the pte from the table. */ tophys(r21, r21) ori r21, r21, 1 /* Set valid bit in physical L2 page */ + beq- 2f /* If zero, don't try to find a pte */ #ifdef CONFIG_8xx_CPU6 li r3, 0x3b80 stw r3, 12(r0) @@ -461,7 +452,7 @@ DataStoreTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x00f0 +2: li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ #ifdef CONFIG_8xx_CPU6 @@ -480,24 +471,6 @@ DataStoreTLBMiss: #endif rfi -2: - /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fail - * to update DAR when they cause a DTLB miss. - */ - mfspr r21, MD_EPN - mfspr r20, DAR - rlwimi r20, r21, 0, 0, 19 - mtspr DAR, r20 - - mfspr r20, M_TW /* Restore registers */ - lwz r21, 0(r0) - mtcr r21 - lwz r21, 4(r0) -#ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) -#endif - b DataAccess - /* This is an instruction TLB error on the MPC8xx. This could be due * to many reasons, such as executing guarded memory or illegal instruction * addresses. There is nothing to do but handle a big time error fault. diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/ppc64/kernel/sys_ppc32.c linux-2.4.30-rc1/arch/ppc64/kernel/sys_ppc32.c --- linux-2.4.29/arch/ppc64/kernel/sys_ppc32.c 2005-01-19 14:09:37.000000000 +0000 +++ linux-2.4.30-rc1/arch/ppc64/kernel/sys_ppc32.c 2005-03-18 18:06:38.900011096 +0000 @@ -183,11 +183,9 @@ static long do_readv_writev32(int type, i--; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); + retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); if (retval) { if (iov != iovstack) kfree(iov); @@ -3666,7 +3664,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -3697,6 +3696,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -3753,6 +3755,7 @@ asmlinkage long sys32_recvmsg(int fd, st struct sockaddr *uaddr; int *uaddr_len; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, total_len, len = 0; PPCDBG(PPCDBG_SYS32, "sys32_recvmsg - entered - fd=%x, user_msg@=%p, user_flags=%x \n", fd, user_msg, user_flags); @@ -3770,6 +3773,7 @@ asmlinkage long sys32_recvmsg(int fd, st total_len = err; cmsg_ptr = (unsigned long) kern_msg.msg_control; + cmsg_len = kern_msg.msg_controllen; kern_msg.msg_flags = 0; sock = sockfd_lookup(fd, &err); @@ -3795,7 +3799,8 @@ asmlinkage long sys32_recvmsg(int fd, st * to fix it up before we tack on more stuff. */ if((unsigned long) kern_msg.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + cmsg32_recvmsg_fixup(&kern_msg, + cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/s390x/kernel/linux32.c linux-2.4.30-rc1/arch/s390x/kernel/linux32.c --- linux-2.4.29/arch/s390x/kernel/linux32.c 2005-01-19 14:09:38.000000000 +0000 +++ linux-2.4.30-rc1/arch/s390x/kernel/linux32.c 2005-03-18 18:07:57.553054016 +0000 @@ -1108,7 +1108,6 @@ static long do_readv_writev32(int type, unsigned long tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov=iovstack, *ivp; - struct inode *inode; long retval, i; io_fn_t fn; iov_fn_t fnv; @@ -1145,11 +1144,9 @@ static long do_readv_writev32(int type, i--; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); + retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); if (retval) goto out; @@ -2600,7 +2597,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -2631,6 +2629,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -2890,7 +2891,8 @@ out: static __inline__ void scm_recv32(struct socket *sock, struct msghdr *msg, - struct scm_cookie *scm, int flags, unsigned long cmsg_ptr) + struct scm_cookie *scm, int flags, unsigned long cmsg_ptr, + __kernel_size_t cmsg_len) { if(!msg->msg_control) { @@ -2905,7 +2907,7 @@ scm_recv32(struct socket *sock, struct m * to fix it up before we tack on more stuff. */ if((unsigned long) msg->msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(msg, cmsg_ptr); + cmsg32_recvmsg_fixup(msg, cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) put_cmsg32(msg, @@ -2919,14 +2921,14 @@ scm_recv32(struct socket *sock, struct m static int sock_recvmsg32(struct socket *sock, struct msghdr *msg, int size, int flags, - unsigned long cmsg_ptr) + unsigned long cmsg_ptr, __kernel_size_t cmsg_len) { struct scm_cookie scm; memset(&scm, 0, sizeof(scm)); size = sock->ops->recvmsg(sock, msg, size, flags, &scm); if (size >= 0) - scm_recv32(sock, msg, &scm, flags, cmsg_ptr); + scm_recv32(sock, msg, &scm, flags, cmsg_ptr, cmsg_len); return size; } @@ -2943,6 +2945,7 @@ sys32_recvmsg (int fd, struct msghdr32 * struct iovec *iov=iovstack; struct msghdr msg_sys; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, iov_size, total_len, len; /* kernel mode address */ @@ -2986,11 +2989,12 @@ sys32_recvmsg (int fd, struct msghdr32 * total_len=err; cmsg_ptr = (unsigned long)msg_sys.msg_control; + cmsg_len = msg_sys.msg_controllen; msg_sys.msg_flags = 0; if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; - err = sock_recvmsg32(sock, &msg_sys, total_len, flags, cmsg_ptr); + err = sock_recvmsg32(sock, &msg_sys, total_len, flags, cmsg_ptr, cmsg_len); if (err < 0) goto out_freeiov; len = err; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/Makefile linux-2.4.30-rc1/arch/sparc/Makefile --- linux-2.4.29/arch/sparc/Makefile 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/Makefile 2005-03-18 18:06:35.001603744 +0000 @@ -45,6 +45,7 @@ LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TO $(TOPDIR)/arch/sparc/lib/lib.a # This one has to come last +_dir_arch/sparc/boot : $(patsubst %, _dir_%, $(SUBDIRS)) SUBDIRS += arch/sparc/boot CORE_FILES_NO_BTFIX := $(CORE_FILES) CORE_FILES += arch/sparc/boot/btfix.o diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/boot/Makefile linux-2.4.30-rc1/arch/sparc/boot/Makefile --- linux-2.4.29/arch/sparc/boot/Makefile 2002-08-03 00:39:43.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/boot/Makefile 2005-03-18 18:08:18.802823560 +0000 @@ -26,11 +26,14 @@ BTOBJS := $(HEAD) init/main.o init/versi BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \ $(DRIVERS) $(NETWORKS) -# I wanted to make this depend upon BTOBJS so that a parallel -# build would work, but this fails because $(HEAD) cannot work -# properly as it will cause head.o to be built with the implicit -# rules not the ones in kernel/Makefile. Someone please fix. --DaveM -vmlinux.o: dummy +GENFILES := include/linux/version.h include/linux/compile.h $(foreach dirname, $(CORE_FILES_NO_BTFIX), _dir_$(dir $(dirname))) +.PHONY : $(GENFILES) +GENFILES += $(BTOBJS) + +$(GENFILES): + $(MAKE) -C $(TOPDIR) $@ + +vmlinux.o: $(GENFILES) $(LD) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) \ --start-group \ $(patsubst %,$(TOPDIR)/%,$(BTLIBS)) \ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/kernel/muldiv.c linux-2.4.30-rc1/arch/sparc/kernel/muldiv.c --- linux-2.4.29/arch/sparc/kernel/muldiv.c 1998-01-12 23:15:43.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/kernel/muldiv.c 2005-03-18 18:07:59.211801848 +0000 @@ -4,6 +4,9 @@ * * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * + * 2004-12-25 Krzysztof Helt (krzysztof.h1@wp.pl) + * - fixed registers constrains in inline assembly declarations */ #include @@ -125,7 +128,7 @@ int do_user_muldiv(struct pt_regs *regs, "mov %%o0, %0\n\t" "mov %%o1, %1\n\t" : "=r" (rs1), "=r" (rs2) - : + : "0" (rs1), "1" (rs2) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); #ifdef DEBUG_MULDIV printk ("0x%x%08x\n", rs2, rs1); @@ -145,7 +148,7 @@ int do_user_muldiv(struct pt_regs *regs, "mov %%o0, %0\n\t" "mov %%o1, %1\n\t" : "=r" (rs1), "=r" (rs2) - : + : "0" (rs1), "1" (rs2) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); #ifdef DEBUG_MULDIV printk ("0x%x%08x\n", rs2, rs1); @@ -174,7 +177,7 @@ int do_user_muldiv(struct pt_regs *regs, "mov %%o1, %0\n\t" "mov %%o0, %1\n\t" : "=r" (rs1), "=r" (rs2) - : "r" (regs->y) + : "r" (regs->y), "0" (rs1), "1" (rs2) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "cc"); #ifdef DEBUG_MULDIV @@ -203,7 +206,7 @@ int do_user_muldiv(struct pt_regs *regs, "mov %%o1, %0\n\t" "mov %%o0, %1\n\t" : "=r" (rs1), "=r" (rs2) - : "r" (regs->y) + : "r" (regs->y), "0" (rs1), "1" (rs2) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "cc"); #ifdef DEBUG_MULDIV diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/kernel/process.c linux-2.4.30-rc1/arch/sparc/kernel/process.c --- linux-2.4.29/arch/sparc/kernel/process.c 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/kernel/process.c 2005-03-18 18:06:35.014601768 +0000 @@ -512,6 +512,11 @@ int copy_thread(int nr, unsigned long cl } } +#ifdef CONFIG_SMP + /* FPU must be disabled on SMP. */ + childregs->psr &= ~PSR_EF; +#endif + /* Set the return value for the child. */ childregs->u_regs[UREG_I0] = current->pid; childregs->u_regs[UREG_I1] = 1; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/kernel/sun4d_smp.c linux-2.4.30-rc1/arch/sparc/kernel/sun4d_smp.c --- linux-2.4.29/arch/sparc/kernel/sun4d_smp.c 2003-11-28 18:26:19.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/kernel/sun4d_smp.c 2005-03-18 18:06:30.992213264 +0000 @@ -132,8 +132,7 @@ void __init smp4d_callin(void) /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" - "sta %%g6, [%%g0] %1\n\t" - : : "r" (¤t_set[cpuid]), "i" (ASI_M_VIKING_TMP2) + : : "r" (¤t_set[cpuid]) : "memory" /* paranoid */); cpu_leds[cpuid] = 0x9; @@ -494,25 +493,18 @@ void __init smp4d_blackbox_id(unsigned * void __init smp4d_blackbox_current(unsigned *addr) { - /* We have a nice Linux current register :) */ - int rd = addr[1] & 0x3e000000; + int rd = *addr & 0x3e000000; - addr[0] = 0x10800006; /* b .+24 */ - addr[1] = 0xc0800820 | rd; /* lda [%g0] ASI_M_VIKING_TMP2, reg */ + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ + addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */ + addr[4] = 0x01000000; /* nop */ } void __init sun4d_init_smp(void) { int i; - extern unsigned int patchme_store_new_current[]; extern unsigned int t_nmi[], linux_trap_ipi15_sun4d[], linux_trap_ipi15_sun4m[]; - /* Store current into Linux current register :) */ - __asm__ __volatile__("sta %%g6, [%%g0] %0" : : "i"(ASI_M_VIKING_TMP2)); - - /* Patch switch_to */ - patchme_store_new_current[0] = (patchme_store_new_current[0] & 0x3e000000) | 0xc0a00820; - /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/mm/io-unit.c linux-2.4.30-rc1/arch/sparc/mm/io-unit.c --- linux-2.4.29/arch/sparc/mm/io-unit.c 2002-11-28 23:53:12.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/mm/io-unit.c 2005-03-18 18:07:20.233727416 +0000 @@ -188,7 +188,7 @@ static void iounit_map_dma_area(unsigned pte_t *ptep; long i; - pgdp = pgd_offset(init_task.mm, addr); + pgdp = pgd_offset(&init_mm, addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset(pmdp, addr); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc/prom/ranges.c linux-2.4.30-rc1/arch/sparc/prom/ranges.c --- linux-2.4.29/arch/sparc/prom/ranges.c 2002-02-25 19:37:56.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc/prom/ranges.c 2005-03-18 18:07:17.388160008 +0000 @@ -34,7 +34,7 @@ prom_adjust_regs(struct linux_prom_regis } } -static void +void prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1, struct linux_prom_ranges *ranges2, int nranges2) { diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/ioctl32.c linux-2.4.30-rc1/arch/sparc64/kernel/ioctl32.c --- linux-2.4.29/arch/sparc64/kernel/ioctl32.c 2005-01-19 14:09:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/ioctl32.c 2005-03-18 18:08:15.317353432 +0000 @@ -562,6 +562,8 @@ static __inline__ void *alloc_user_space if (!(current->thread.flags & SPARC_FLAG_32BIT)) usp += STACK_BIAS; + else + usp &= 0xffffffffUL; return (void *) (usp - len); } @@ -696,6 +698,7 @@ static int dev_ifsioc(unsigned int fd, u set_fs (old_fs); if (!err) { switch (cmd) { + case TUNSETIFF: case SIOCGIFFLAGS: case SIOCGIFMETRIC: case SIOCGIFMTU: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/pci_schizo.c linux-2.4.30-rc1/arch/sparc64/kernel/pci_schizo.c --- linux-2.4.29/arch/sparc64/kernel/pci_schizo.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/pci_schizo.c 2005-03-18 18:06:31.645114008 +0000 @@ -388,9 +388,9 @@ static int __init schizo_ino_to_pil(stru return ret; } -static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm, - struct pci_dev *pdev, - unsigned int ino) +static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, + struct pci_dev *pdev, + unsigned int ino) { struct ino_bucket *bucket; unsigned long imap, iclr; @@ -444,19 +444,57 @@ static unsigned long stc_error_buf[128]; static unsigned long stc_tag_buf[16]; static unsigned long stc_line_buf[16]; -/* These offsets look weird because I keep in pbm->controller_regs - * the second PROM register property minus 0x10000 which is the - * base of the Safari and UPA64S registers of SCHIZO. - */ -#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL) -#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL) +#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */ +#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */ +#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */ +#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ +#define SCHIZO_SERR_INO 0x34 /* Safari interface error */ + +struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) +{ + ino &= IMAP_INO; + if (p->pbm_A.ino_bitmap & (1UL << ino)) + return &p->pbm_A; + if (p->pbm_B.ino_bitmap & (1UL << ino)) + return &p->pbm_B; + + printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps " + "PBM_A[%016lx] PBM_B[%016lx]", + p->index, ino, + p->pbm_A.ino_bitmap, + p->pbm_B.ino_bitmap); + printk("PCI%d: Using PBM_A, report this problem immediately.\n", + p->index); + + return &p->pbm_A; +} -static void schizo_clear_other_err_intr(int irq) +static void schizo_clear_other_err_intr(struct pci_controller_info *p, int irq) { - struct ino_bucket *bucket = __bucket(irq); - unsigned long iclr = bucket->iclr; + struct pci_pbm_info *pbm; + struct ino_bucket *bucket; + unsigned long iclr; + + /* Do not clear the interrupt for the other PCI bus. + * + * This "ACK both PBM IRQs" only needs to be performed + * for chip-wide error interrupts. + */ + if ((irq & IMAP_INO) == SCHIZO_PCIERR_A_INO || + (irq & IMAP_INO) == SCHIZO_PCIERR_B_INO) + return; + + pbm = pbm_for_ino(p, irq); + if (pbm == &p->pbm_A) + pbm = &p->pbm_B; + else + pbm = &p->pbm_A; + + irq = schizo_irq_build(pbm, NULL, + (pbm->portid << 6) | (irq & IMAP_INO)); + bucket = __bucket(irq); + iclr = bucket->iclr; - iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF); upa_writel(ICLR_IDLE, iclr); } @@ -790,7 +828,7 @@ static void schizo_ue_intr(int irq, void /* Interrogate IOMMU for error status. */ schizo_check_iommu_error(p, UE_ERR); - schizo_clear_other_err_intr(irq); + schizo_clear_other_err_intr(p, irq); } #define SCHIZO_CE_AFSR 0x10040UL @@ -879,7 +917,7 @@ static void schizo_ce_intr(int irq, void printk("(none)"); printk("]\n"); - schizo_clear_other_err_intr(irq); + schizo_clear_other_err_intr(p, irq); } #define SCHIZO_PCI_AFSR 0x2010UL @@ -914,9 +952,9 @@ static void schizo_ce_intr(int irq, void #define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */ #define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */ #define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */ -#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */ -#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_MRM_PREF (1UL << 30UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDO_PREF (1UL << 29UL) /* Tomatillo */ +#define SCHIZO_PCICTRL_RDL_PREF (1UL << 28UL) /* Tomatillo */ #define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */ #define SCHIZO_PCICTRL_PTO_SHIFT 24UL #define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */ @@ -1094,7 +1132,7 @@ static void schizo_pcierr_intr(int irq, if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) pci_scan_for_parity_error(p, pbm, pbm->pci_bus); - schizo_clear_other_err_intr(irq); + schizo_clear_other_err_intr(p, irq); } #define SCHIZO_SAFARI_ERRLOG 0x10018UL @@ -1149,7 +1187,7 @@ static void schizo_safarierr_intr(int ir printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", p->index, errlog); - schizo_clear_other_err_intr(irq); + schizo_clear_other_err_intr(p, irq); return; } @@ -1157,7 +1195,7 @@ static void schizo_safarierr_intr(int ir p->index); schizo_check_iommu_error(p, SAFARI_ERR); - schizo_clear_other_err_intr(irq); + schizo_clear_other_err_intr(p, irq); } /* Nearly identical to PSYCHO equivalents... */ @@ -1171,26 +1209,6 @@ static void schizo_safarierr_intr(int ir #define SCHIZO_SAFARI_IRQCTRL 0x10010UL #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL -#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */ -#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */ -#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */ -#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ -#define SCHIZO_SERR_INO 0x34 /* Safari interface error */ - -struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) -{ - ino &= IMAP_INO; - if (p->pbm_A.ino_bitmap & (1UL << ino)) - return &p->pbm_A; - if (p->pbm_B.ino_bitmap & (1UL << ino)) - return &p->pbm_B; - prom_printf("TOMATILLO%d: No entry in ino bitmap for %d\n", - p->index, ino); - prom_halt(); - /* NOTREACHED */ - return NULL; -} - /* How the Tomatillo IRQs are routed around is pure guesswork here. * * All the Tomatillo devices I see in prtconf dumps seem to have only @@ -1964,7 +1982,7 @@ static void __init schizo_pbm_hw_init(st tmp &= ~SCHIZO_PCICTRL_PTO; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && - pbm->chip_version == 0x2) + pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; else tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; @@ -1972,8 +1990,16 @@ static void __init schizo_pbm_hw_init(st if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && + pbm->chip_version <= 0x1) + tmp |= (1UL << 61); + else + tmp &= ~(1UL << 61); + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) - tmp |= SCHIZO_PCICTRL_MRM_PREF; + tmp |= (SCHIZO_PCICTRL_MRM_PREF | + SCHIZO_PCICTRL_RDO_PREF | + SCHIZO_PCICTRL_RDL_PREF); schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/smp.c linux-2.4.30-rc1/arch/sparc64/kernel/smp.c --- linux-2.4.29/arch/sparc64/kernel/smp.c 2005-01-19 14:09:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/smp.c 2005-03-18 18:06:10.869272416 +0000 @@ -1034,7 +1034,7 @@ static unsigned long penguins_are_doing_ void smp_capture(void) { if (smp_processors_ready) { - int result = __atomic_add(1, &smp_capture_depth); + int result = atomic_add_ret(1, &smp_capture_depth); membar("#StoreStore | #LoadStore"); if (result == 1) { diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/sparc64_ksyms.c linux-2.4.30-rc1/arch/sparc64/kernel/sparc64_ksyms.c --- linux-2.4.29/arch/sparc64/kernel/sparc64_ksyms.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/sparc64_ksyms.c 2005-03-18 18:08:09.948169672 +0000 @@ -173,18 +173,21 @@ EXPORT_SYMBOL(__down_interruptible); EXPORT_SYMBOL(__up); /* Atomic counter implementation. */ -EXPORT_SYMBOL(__atomic_add); -EXPORT_SYMBOL(__atomic_sub); +EXPORT_SYMBOL(atomic_add); +EXPORT_SYMBOL(atomic_add_ret); +EXPORT_SYMBOL(atomic_sub); +EXPORT_SYMBOL(atomic_sub_ret); #ifdef CONFIG_SMP EXPORT_SYMBOL(atomic_dec_and_lock); #endif /* Atomic bit operations. */ -EXPORT_SYMBOL(___test_and_set_bit); -EXPORT_SYMBOL(___test_and_clear_bit); -EXPORT_SYMBOL(___test_and_change_bit); -EXPORT_SYMBOL(___test_and_set_le_bit); -EXPORT_SYMBOL(___test_and_clear_le_bit); +EXPORT_SYMBOL(test_and_set_bit); +EXPORT_SYMBOL(test_and_clear_bit); +EXPORT_SYMBOL(test_and_change_bit); +EXPORT_SYMBOL(set_bit); +EXPORT_SYMBOL(clear_bit); +EXPORT_SYMBOL(change_bit); EXPORT_SYMBOL(ivector_table); EXPORT_SYMBOL(enable_irq); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/sys_sparc32.c linux-2.4.30-rc1/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.29/arch/sparc64/kernel/sys_sparc32.c 2005-01-19 14:09:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/sys_sparc32.c 2005-03-18 18:07:45.287918600 +0000 @@ -505,25 +505,32 @@ out: return err; } -static int do_sys32_msgsnd (int first, int second, int third, void *uptr) +static int do_sys32_msgsnd(int first, int second, int third, void *uptr) { - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); - struct msgbuf32 *up = (struct msgbuf32 *)uptr; + struct msgbuf *p; + struct msgbuf32 *up; mm_segment_t old_fs; int err; + if (second < 0) + return -EINVAL; + + p = kmalloc(second + sizeof (struct msgbuf), GFP_USER); if (!p) return -ENOMEM; + + up = (struct msgbuf32 *)uptr; err = -EFAULT; - if (get_user (p->mtype, &up->mtype) || - __copy_from_user (p->mtext, &up->mtext, second)) + if (get_user(p->mtype, &up->mtype) || + __copy_from_user(p->mtext, up->mtext, second)) goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgsnd (first, p, second, third); - set_fs (old_fs); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_msgsnd(first, p, second, third); + set_fs(old_fs); out: - kfree (p); + kfree(p); return err; } @@ -535,6 +542,9 @@ static int do_sys32_msgrcv (int first, i mm_segment_t old_fs; int err; + if (second < 0) + return -EINVAL; + if (!version) { struct ipc_kludge *uipck = (struct ipc_kludge *)uptr; struct ipc_kludge ipck; @@ -560,7 +570,7 @@ static int do_sys32_msgrcv (int first, i goto free_then_out; up = (struct msgbuf32 *)uptr; if (put_user (p->mtype, &up->mtype) || - __copy_to_user (&up->mtext, p->mtext, err)) + __copy_to_user (up->mtext, p->mtext, err)) err = -EFAULT; free_then_out: kfree (p); @@ -647,18 +657,18 @@ out: return err; } -static int do_sys32_shmat (int first, int second, int third, int version, void *uptr) +static int do_sys32_shmat(int first, int second, u32 third, int version, void *uptr) { unsigned long raddr; - u32 *uaddr = (u32 *)A((u32)third); + u32 *uaddr = (u32 *)A(third); int err = -EINVAL; if (version == 1) goto out; - err = sys_shmat (first, uptr, second, &raddr); + err = sys_shmat(first, uptr, second, &raddr); if (err) goto out; - err = put_user (raddr, uaddr); + err = put_user(raddr, uaddr); out: return err; } @@ -770,6 +780,8 @@ static __inline__ void *alloc_user_space if (!(current->thread.flags & SPARC_FLAG_32BIT)) usp += STACK_BIAS; + else + usp &= 0xffffffffUL; return (void *) (usp - len); } @@ -795,9 +807,11 @@ static int sys32_semtimedop(int semid, s return sys_semtimedop(semid, tsems, nsems, t64); } -asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) +asmlinkage int sys32_ipc (u32 call, u32 first, u32 second, u32 third, s32 __ptr, s32 __fifth) { int version, err; + u32 ptr = (u32) __ptr; + u32 fifth = (u32) __fifth; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -806,15 +820,23 @@ asmlinkage int sys32_ipc (u32 call, int switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second, NULL); + err = sys_semtimedop((int)first, + (struct sembuf *)A(ptr), + second, NULL); goto out; case SEMTIMEDOP: - err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second, (const struct timespec32 *) AA(fifth)); + err = sys32_semtimedop((int)first, + (struct sembuf *)A(ptr), + second, + (const struct timespec32 *) + A(fifth)); case SEMGET: - err = sys_semget (first, second, third); + err = sys_semget((key_t)first, (int)second, + (int)third); goto out; case SEMCTL: - err = do_sys32_semctl (first, second, third, (void *)AA(ptr)); + err = do_sys32_semctl((int)first, (int)second, + (int)third, (void *) A(ptr)); goto out; default: err = -ENOSYS; @@ -823,17 +845,20 @@ asmlinkage int sys32_ipc (u32 call, int if (call <= MSGCTL) switch (call) { case MSGSND: - err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr)); + err = do_sys32_msgsnd((int)first, (int)second, + (int)third, (void *)A(ptr)); goto out; case MSGRCV: - err = do_sys32_msgrcv (first, second, fifth, third, - version, (void *)AA(ptr)); + err = do_sys32_msgrcv((int)first, (int)second, + (int)fifth, (int)third, + version, (void *)A(ptr)); goto out; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t)first, (int)second); goto out; case MSGCTL: - err = do_sys32_msgctl (first, second, (void *)AA(ptr)); + err = do_sys32_msgctl((int)first, (int)second, + (void *)A(ptr)); goto out; default: err = -ENOSYS; @@ -842,17 +867,18 @@ asmlinkage int sys32_ipc (u32 call, int if (call <= SHMCTL) switch (call) { case SHMAT: - err = do_sys32_shmat (first, second, third, - version, (void *)AA(ptr)); + err = do_sys32_shmat((int)first, (int)second, third, + version, (void *)A(ptr)); goto out; case SHMDT: - err = sys_shmdt ((char *)AA(ptr)); + err = sys_shmdt((char *)A(ptr)); goto out; case SHMGET: - err = sys_shmget (first, second, third); + err = sys_shmget((key_t)first, second, (int)third); goto out; case SHMCTL: - err = do_sys32_shmctl (first, second, (void *)AA(ptr)); + err = do_sys32_shmctl((int)first, (int)second, + (void *)A(ptr)); goto out; default: err = -ENOSYS; @@ -1093,7 +1119,6 @@ static long do_readv_writev32(int type, __kernel_ssize_t32 tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov=iovstack, *ivp; - struct inode *inode; long retval, i; io_fn_t fn; iov_fn_t fnv; @@ -1140,11 +1165,9 @@ static long do_readv_writev32(int type, i--; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - retval = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); + retval = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); if (retval) goto out; @@ -2160,9 +2183,6 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese timeout = (timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec)); - current->state = TASK_INTERRUPTIBLE; - timeout = schedule_timeout(timeout); - if (timeout) { /* None ready -- temporarily unblock those we're * interested while we are sleeping in so that we'll @@ -2648,7 +2668,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -2679,6 +2700,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; if (kcmsg32->cmsg_level == SOL_SOCKET && kcmsg32->cmsg_type == SO_TIMESTAMP) { struct timeval tv; @@ -2782,6 +2806,7 @@ asmlinkage int sys32_recvmsg(int fd, str struct sockaddr *uaddr; int *uaddr_len; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, total_len, len = 0; if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) @@ -2797,6 +2822,7 @@ asmlinkage int sys32_recvmsg(int fd, str total_len = err; cmsg_ptr = (unsigned long) kern_msg.msg_control; + cmsg_len = kern_msg.msg_controllen; kern_msg.msg_flags = 0; sock = sockfd_lookup(fd, &err); @@ -2822,7 +2848,8 @@ asmlinkage int sys32_recvmsg(int fd, str * to fix it up before we tack on more stuff. */ if((unsigned long) kern_msg.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + cmsg32_recvmsg_fixup(&kern_msg, + cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/kernel/time.c linux-2.4.30-rc1/arch/sparc64/kernel/time.c --- linux-2.4.29/arch/sparc64/kernel/time.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/kernel/time.c 2005-03-18 18:07:28.275504880 +0000 @@ -770,6 +770,7 @@ void __init clock_probe(void) strcmp(model, "mk48t59") && strcmp(model, "m5819") && strcmp(model, "m5819p") && + strcmp(model, "m5823") && strcmp(model, "ds1287")) { if (cbus != NULL) { prom_printf("clock_probe: Central bus lacks timer chip.\n"); @@ -829,7 +830,8 @@ void __init clock_probe(void) if (!strcmp(model, "ds1287") || !strcmp(model, "m5819") || - !strcmp(model, "m5819p")) { + !strcmp(model, "m5819p") || + !strcmp(model, "m5823")) { ds1287_regs = edev->resource[0].start; } else { mstk48t59_regs = edev->resource[0].start; @@ -850,7 +852,8 @@ try_isa_clock: } if (!strcmp(model, "ds1287") || !strcmp(model, "m5819") || - !strcmp(model, "m5819p")) { + !strcmp(model, "m5819p") || + !strcmp(model, "m5823")) { ds1287_regs = isadev->resource.start; } else { mstk48t59_regs = isadev->resource.start; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/lib/atomic.S linux-2.4.30-rc1/arch/sparc64/lib/atomic.S --- linux-2.4.29/arch/sparc64/lib/atomic.S 2001-12-21 17:41:53.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/lib/atomic.S 2005-03-18 18:08:15.318353280 +0000 @@ -4,33 +4,83 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#include #include + /* On SMP we need to use memory barriers to ensure + * correct memory operation ordering, nop these out + * for uniprocessor. + */ +#ifdef CONFIG_SMP +#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad +#define ATOMIC_POST_BARRIER membar #StoreLoad | #StoreStore +#else +#define ATOMIC_PRE_BARRIER nop +#define ATOMIC_POST_BARRIER nop +#endif + .text - .align 64 .globl atomic_impl_begin, atomic_impl_end - - .globl __atomic_add atomic_impl_begin: -__atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ - lduw [%o1], %g5 + /* Two versions of the atomic routines, one that + * does not return a value and does not perform + * memory barriers, and a second which returns + * a value and does the barriers. + */ + .globl atomic_add + .type atomic_add,#function +atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ +1: lduw [%o1], %g5 + add %g5, %o0, %g7 + cas [%o1], %g5, %g7 + cmp %g5, %g7 + bne,pn %icc, 1b + nop + retl + nop + .size atomic_add, .-atomic_add + + .globl atomic_sub + .type atomic_sub,#function +atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ +1: lduw [%o1], %g5 + sub %g5, %o0, %g7 + cas [%o1], %g5, %g7 + cmp %g5, %g7 + bne,pn %icc, 1b + nop + retl + nop + .size atomic_sub, .-atomic_sub + + .globl atomic_add_ret + .type atomic_add_ret,#function +atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ + ATOMIC_PRE_BARRIER +1: lduw [%o1], %g5 add %g5, %o0, %g7 cas [%o1], %g5, %g7 cmp %g5, %g7 - bne,pn %icc, __atomic_add - membar #StoreLoad | #StoreStore + bne,pn %icc, 1b + add %g7, %o0, %g7 + ATOMIC_POST_BARRIER retl - add %g7, %o0, %o0 + sra %g7, 0, %o0 + .size atomic_add_ret, .-atomic_add_ret - .globl __atomic_sub -__atomic_sub: /* %o0 = increment, %o1 = atomic_ptr */ - lduw [%o1], %g5 + .globl atomic_sub_ret + .type atomic_sub_ret,#function +atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ + ATOMIC_PRE_BARRIER +1: lduw [%o1], %g5 sub %g5, %o0, %g7 cas [%o1], %g5, %g7 cmp %g5, %g7 - bne,pn %icc, __atomic_sub - membar #StoreLoad | #StoreStore + bne,pn %icc, 1b + sub %g7, %o0, %g7 + ATOMIC_POST_BARRIER retl - sub %g7, %o0, %o0 + sra %g7, 0, %o0 + .size atomic_sub_ret, .-atomic_sub_ret atomic_impl_end: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/lib/bitops.S linux-2.4.30-rc1/arch/sparc64/lib/bitops.S --- linux-2.4.29/arch/sparc64/lib/bitops.S 2001-12-21 17:41:53.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/lib/bitops.S 2005-03-18 18:08:14.298508320 +0000 @@ -4,107 +4,149 @@ * Copyright (C) 2000 David S. Miller (davem@redhat.com) */ +#include #include + /* On SMP we need to use memory barriers to ensure + * correct memory operation ordering, nop these out + * for uniprocessor. + */ +#ifdef CONFIG_SMP +#define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad +#define BITOP_POST_BARRIER membar #StoreLoad | #StoreStore +#else +#define BITOP_PRE_BARRIER nop +#define BITOP_POST_BARRIER nop +#endif + .text - .align 64 + .globl __bitops_begin __bitops_begin: - .globl ___test_and_set_bit -___test_and_set_bit: /* %o0=nr, %o1=addr */ + + .globl test_and_set_bit + .type test_and_set_bit,#function +test_and_set_bit: /* %o0=nr, %o1=addr */ + BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %g5 sllx %g1, 3, %g3 and %o0, 63, %g2 sllx %g5, %g2, %g5 add %o1, %g3, %o1 - ldx [%o1], %g7 -1: andcc %g7, %g5, %o0 - bne,pn %xcc, 2f - xor %g7, %g5, %g1 +1: ldx [%o1], %g7 + or %g7, %g5, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,a,pn %xcc, 1b - ldx [%o1], %g7 -2: retl - membar #StoreLoad | #StoreStore - - .globl ___test_and_clear_bit -___test_and_clear_bit: /* %o0=nr, %o1=addr */ + bne,pn %xcc, 1b + and %g7, %g5, %g2 + BITOP_POST_BARRIER + clr %o0 + retl + movrne %g2, 1, %o0 + .size test_and_set_bit, .-test_and_set_bit + + .globl test_and_clear_bit + .type test_and_clear_bit,#function +test_and_clear_bit: /* %o0=nr, %o1=addr */ + BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %g5 sllx %g1, 3, %g3 and %o0, 63, %g2 sllx %g5, %g2, %g5 add %o1, %g3, %o1 - ldx [%o1], %g7 -1: andcc %g7, %g5, %o0 - be,pn %xcc, 2f - xor %g7, %g5, %g1 +1: ldx [%o1], %g7 + andn %g7, %g5, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,a,pn %xcc, 1b - ldx [%o1], %g7 -2: retl - membar #StoreLoad | #StoreStore - - .globl ___test_and_change_bit -___test_and_change_bit: /* %o0=nr, %o1=addr */ + bne,pn %xcc, 1b + and %g7, %g5, %g2 + BITOP_POST_BARRIER + clr %o0 + retl + movrne %g2, 1, %o0 + .size test_and_clear_bit, .-test_and_clear_bit + + .globl test_and_change_bit + .type test_and_change_bit,#function +test_and_change_bit: /* %o0=nr, %o1=addr */ + BITOP_PRE_BARRIER + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 +1: ldx [%o1], %g7 + xor %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,pn %xcc, 1b + and %g7, %g5, %g2 + BITOP_POST_BARRIER + clr %o0 + retl + movrne %g2, 1, %o0 + .size test_and_change_bit, .-test_and_change_bit + + .globl set_bit + .type set_bit,#function +set_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 +1: ldx [%o1], %g7 + or %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,pn %xcc, 1b + nop + retl + nop + .size set_bit, .-set_bit + + .globl clear_bit + .type clear_bit,#function +clear_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 +1: ldx [%o1], %g7 + andn %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,pn %xcc, 1b + nop + retl + nop + .size clear_bit, .-clear_bit + + .globl change_bit + .type change_bit,#function +change_bit: /* %o0=nr, %o1=addr */ srlx %o0, 6, %g1 mov 1, %g5 sllx %g1, 3, %g3 and %o0, 63, %g2 sllx %g5, %g2, %g5 add %o1, %g3, %o1 - ldx [%o1], %g7 -1: and %g7, %g5, %o0 +1: ldx [%o1], %g7 xor %g7, %g5, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,a,pn %xcc, 1b - ldx [%o1], %g7 -2: retl - membar #StoreLoad | #StoreStore - nop - - .globl ___test_and_set_le_bit -___test_and_set_le_bit: /* %o0=nr, %o1=addr */ - srlx %o0, 5, %g1 - mov 1, %g5 - sllx %g1, 2, %g3 - and %o0, 31, %g2 - sllx %g5, %g2, %g5 - add %o1, %g3, %o1 - lduwa [%o1] ASI_PL, %g7 -1: andcc %g7, %g5, %o0 - bne,pn %icc, 2f - xor %g7, %g5, %g1 - casa [%o1] ASI_PL, %g7, %g1 - cmp %g7, %g1 - bne,a,pn %icc, 1b - lduwa [%o1] ASI_PL, %g7 -2: retl - membar #StoreLoad | #StoreStore - - .globl ___test_and_clear_le_bit -___test_and_clear_le_bit: /* %o0=nr, %o1=addr */ - srlx %o0, 5, %g1 - mov 1, %g5 - sllx %g1, 2, %g3 - and %o0, 31, %g2 - sllx %g5, %g2, %g5 - add %o1, %g3, %o1 - lduwa [%o1] ASI_PL, %g7 -1: andcc %g7, %g5, %o0 - be,pn %icc, 2f - xor %g7, %g5, %g1 - casa [%o1] ASI_PL, %g7, %g1 - cmp %g7, %g1 - bne,a,pn %icc, 1b - lduwa [%o1] ASI_PL, %g7 -2: retl - membar #StoreLoad | #StoreStore + bne,pn %xcc, 1b + nop + retl + nop + .size change_bit, .-change_bit .globl __bitops_end __bitops_end: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/lib/debuglocks.c linux-2.4.30-rc1/arch/sparc64/lib/debuglocks.c --- linux-2.4.29/arch/sparc64/lib/debuglocks.c 2001-12-21 17:41:53.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/lib/debuglocks.c 2005-03-18 18:07:43.314218648 +0000 @@ -162,6 +162,7 @@ void _do_read_unlock (rwlock_t *rw, char runlock_again: /* Spin trying to decrement the counter using casx. */ __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" " ldx [%0], %%g5\n" " sub %%g5, 1, %%g7\n" " casx [%0], %%g5, %%g7\n" @@ -276,6 +277,7 @@ void _do_write_unlock(rwlock_t *rw) current->thread.smp_lock_count--; wlock_again: __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" " mov 1, %%g3\n" " sllx %%g3, 63, %%g3\n" " ldx [%0], %%g5\n" diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/sparc64/lib/rwlock.S linux-2.4.30-rc1/arch/sparc64/lib/rwlock.S --- linux-2.4.29/arch/sparc64/lib/rwlock.S 2000-09-09 00:55:17.000000000 +0000 +++ linux-2.4.30-rc1/arch/sparc64/lib/rwlock.S 2005-03-18 18:07:18.581978520 +0000 @@ -24,12 +24,13 @@ __read_lock: /* %o0 = lock_ptr */ 99: retl nop __read_unlock: /* %o0 = lock_ptr */ + membar #StoreLoad | #LoadLoad lduw [%o0], %g5 sub %g5, 1, %g7 cas [%o0], %g5, %g7 cmp %g5, %g7 be,pt %xcc, 99b - membar #StoreLoad | #StoreStore + nop ba,a,pt %xcc, __read_unlock __read_wait_for_writer: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/ia32/fpu32.c linux-2.4.30-rc1/arch/x86_64/ia32/fpu32.c --- linux-2.4.29/arch/x86_64/ia32/fpu32.c 2003-06-13 14:51:32.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/ia32/fpu32.c 2005-03-18 18:06:31.616118416 +0000 @@ -28,16 +28,17 @@ static inline unsigned short twd_i387_to static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave) { struct _fpxreg *st = NULL; + unsigned long tos = (fxsave->swd >> 11) & 7; unsigned long twd = (unsigned long) fxsave->twd; unsigned long tag; unsigned long ret = 0xffff0000; int i; -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); +#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16); for (i = 0 ; i < 8 ; i++) { if (twd & 0x1) { - st = (struct _fpxreg *) FPREG_ADDR( fxsave, i ); + st = FPREG_ADDR( fxsave, (i - tos) & 7 ); switch (st->exponent & 0x7fff) { case 0x7fff: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/ia32/socket32.c linux-2.4.30-rc1/arch/x86_64/ia32/socket32.c --- linux-2.4.29/arch/x86_64/ia32/socket32.c 2005-01-19 14:09:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/ia32/socket32.c 2005-03-18 18:06:38.929006688 +0000 @@ -302,7 +302,8 @@ static void scm_detach_fds32(struct msgh * IPV6_RTHDR ipv6 routing exthdr 32-bit clean * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ -static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, + unsigned long orig_cmsg_uptr, __kernel_size_t orig_cmsg_len) { unsigned char *workbuf, *wp; unsigned long bufsz, space_avail; @@ -333,6 +334,9 @@ static void cmsg32_recvmsg_fixup(struct __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; + if ((clen64 < CMSG_ALIGN(sizeof(*ucmsg))) || + (clen64 > (orig_cmsg_len + wp - workbuf))) + break; copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), clen64 - CMSG_ALIGN(sizeof(*ucmsg))); clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + @@ -418,6 +422,7 @@ asmlinkage long sys32_recvmsg(int fd, st struct sockaddr *uaddr; int *uaddr_len; unsigned long cmsg_ptr; + __kernel_size_t cmsg_len; int err, total_len, len = 0; if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) @@ -433,6 +438,7 @@ asmlinkage long sys32_recvmsg(int fd, st total_len = err; cmsg_ptr = (unsigned long) kern_msg.msg_control; + cmsg_len = kern_msg.msg_controllen; kern_msg.msg_flags = 0; sock = sockfd_lookup(fd, &err); @@ -458,7 +464,8 @@ asmlinkage long sys32_recvmsg(int fd, st * to fix it up before we tack on more stuff. */ if((unsigned long) kern_msg.msg_control != cmsg_ptr) - cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + cmsg32_recvmsg_fixup(&kern_msg, + cmsg_ptr, cmsg_len); /* Wheee... */ if(sock->passcred) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/kernel/acpi.c linux-2.4.30-rc1/arch/x86_64/kernel/acpi.c --- linux-2.4.29/arch/x86_64/kernel/acpi.c 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/kernel/acpi.c 2005-03-18 18:08:24.227998808 +0000 @@ -53,6 +53,7 @@ int acpi_strict; acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; +int acpi_skip_timer_override __initdata; /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -333,6 +334,12 @@ acpi_parse_int_src_ovr ( return 0; } + if (acpi_skip_timer_override && + intsrc->bus_irq == 0 && intsrc->global_irq == 2) { + printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); + return 0; + } + mp_override_legacy_irq ( intsrc->bus_irq, intsrc->flags.polarity, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/kernel/io_apic.c linux-2.4.30-rc1/arch/x86_64/kernel/io_apic.c --- linux-2.4.29/arch/x86_64/kernel/io_apic.c 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/kernel/io_apic.c 2005-03-18 18:08:14.282510752 +0000 @@ -259,10 +259,14 @@ void __init check_ioapic(void) case PCI_VENDOR_ID_VIA: return; case PCI_VENDOR_ID_NVIDIA: +#ifdef CONFIG_ACPI + /* All timer overrides on Nvidia + seem to be wrong. Skip them. */ + acpi_skip_timer_override = 1; printk(KERN_INFO - "PCI bridge %02x:%02x from %x found. Setting \"noapic\". Overwrite with \"apic\"\n", - num,slot,vendor); - skip_ioapic_setup = 1; + "Nvidia board detected. Ignoring ACPI timer override.\n"); +#endif + /* RED-PEN skip them on mptables too? */ return; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/kernel/pci-irq.c linux-2.4.30-rc1/arch/x86_64/kernel/pci-irq.c --- linux-2.4.29/arch/x86_64/kernel/pci-irq.c 2003-08-25 11:44:40.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/kernel/pci-irq.c 2005-03-18 18:07:53.611653200 +0000 @@ -742,7 +742,7 @@ void pcibios_penalize_isa_irq(int irq) void pcibios_enable_irq(struct pci_dev *dev) { u8 pin; - extern int interrupt_line_quirk; + extern int via_interrupt_line_quirk; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { @@ -762,6 +762,6 @@ void pcibios_enable_irq(struct pci_dev * } /* VIA bridges use interrupt line for apic/pci steering across the V-Link */ - else if (interrupt_line_quirk) + else if (via_interrupt_line_quirk) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/arch/x86_64/kernel/setup.c linux-2.4.30-rc1/arch/x86_64/kernel/setup.c --- linux-2.4.29/arch/x86_64/kernel/setup.c 2005-01-19 14:09:39.000000000 +0000 +++ linux-2.4.30-rc1/arch/x86_64/kernel/setup.c 2005-03-18 18:06:41.323642648 +0000 @@ -93,7 +93,8 @@ char saved_command_line[COMMAND_LINE_SIZ struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, { "pic1", 0x20, 0x3f, IORESOURCE_BUSY }, - { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, + { "timer0", 0x40, 0x43, IORESOURCE_BUSY }, + { "timer1", 0x50, 0x53, IORESOURCE_BUSY }, { "keyboard", 0x60, 0x6f, IORESOURCE_BUSY }, { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, { "pic2", 0xa0, 0xbf, IORESOURCE_BUSY }, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/acpi/pci_irq.c linux-2.4.30-rc1/drivers/acpi/pci_irq.c --- linux-2.4.29/drivers/acpi/pci_irq.c 2004-08-07 23:26:04.000000000 +0000 +++ linux-2.4.30-rc1/drivers/acpi/pci_irq.c 2005-03-18 18:08:28.020422272 +0000 @@ -335,6 +335,7 @@ acpi_pci_irq_enable ( { int irq = 0; u8 pin = 0; + extern int via_interrupt_line_quirk; ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); @@ -383,6 +384,9 @@ acpi_pci_irq_enable ( } } + if (via_interrupt_line_quirk) + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15); + dev->irq = irq; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", dev->slot_name, dev->irq)); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/block/nbd.c linux-2.4.30-rc1/drivers/block/nbd.c --- linux-2.4.29/drivers/block/nbd.c 2003-08-25 11:44:41.000000000 +0000 +++ linux-2.4.30-rc1/drivers/block/nbd.c 2005-03-18 18:06:44.845107304 +0000 @@ -408,10 +408,7 @@ static int nbd_ioctl(struct inode *inode int dev, error, temp; struct request sreq ; - /* Anyone capable of this syscall can do *real bad* things */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; if (!inode) return -EINVAL; dev = MINOR(inode->i_rdev); @@ -419,6 +416,20 @@ static int nbd_ioctl(struct inode *inode return -ENODEV; lo = &nbd_dev[dev]; + + /* these are innocent, but.... */ + switch (cmd) { + case BLKGETSIZE: + return put_user(nbd_bytesizes[dev] >> 9, (unsigned long *) arg); + case BLKGETSIZE64: + return put_user((u64)nbd_bytesizes[dev], (u64 *) arg); + } + + /* ... anyone capable of any of the below ioctls can do *real bad* + things */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + switch (cmd) { case NBD_DISCONNECT: printk("NBD_DISCONNECT\n"); @@ -524,10 +535,6 @@ static int nbd_ioctl(struct inode *inode dev, lo->queue_head.next, lo->queue_head.prev, requests_in, requests_out); return 0; #endif - case BLKGETSIZE: - return put_user(nbd_bytesizes[dev] >> 9, (unsigned long *) arg); - case BLKGETSIZE64: - return put_user((u64)nbd_bytesizes[dev], (u64 *) arg); } return -EINVAL; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/agp/agp.h linux-2.4.30-rc1/drivers/char/agp/agp.h --- linux-2.4.29/drivers/char/agp/agp.h 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/agp/agp.h 2005-03-18 18:07:15.076511432 +0000 @@ -217,6 +217,12 @@ struct agp_bridge_data { #ifndef PCI_DEVICE_ID_INTEL_915_G_1 #define PCI_DEVICE_ID_INTEL_915_G_1 0x2582 #endif +#ifndef PCI_DEVICE_ID_INTEL_915_GM_0 +#define PCI_DEVICE_ID_INTEL_915_GM_0 0x2590 +#endif +#ifndef PCI_DEVICE_ID_INTEL_915_GM_1 +#define PCI_DEVICE_ID_INTEL_915_GM_1 0x2592 +#endif #ifndef PCI_DEVICE_ID_INTEL_820_0 #define PCI_DEVICE_ID_INTEL_820_0 0x2500 #endif diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/agp/agpgart_be.c linux-2.4.30-rc1/drivers/char/agp/agpgart_be.c --- linux-2.4.29/drivers/char/agp/agpgart_be.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/agp/agpgart_be.c 2005-03-18 18:06:35.350550696 +0000 @@ -1170,14 +1170,14 @@ static aper_size_info_fixed intel_i830_s {128, 32768, 5}, /* The 64M mode still requires a 128k gatt */ {64, 16384, 5}, - /* For I915G */ + /* For I915G/I915GM */ {256, 65536, 6} }; static struct _intel_i830_private { struct pci_dev *i830_dev; /* device one */ volatile u8 *registers; - volatile u32 *gtt; /* I915G */ + volatile u32 *gtt; /* I915G/I915GM */ int gtt_entries; } intel_i830_private; @@ -1220,14 +1220,16 @@ static void intel_i830_init_gtt_entries( break; case I915_GMCH_GMS_STOLEN_48M: /* Check it's really I915 */ - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; break; case I915_GMCH_GMS_STOLEN_64M: /* Check it's really I915 */ - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1287,7 +1289,8 @@ static int intel_i830_create_gatt_table( num_entries = size->num_entries; agp_bridge.gatt_table_real = 0; - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) { + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) { pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR,&temp); pci_read_config_dword(intel_i830_private.i830_dev, @@ -1331,7 +1334,8 @@ static int intel_i830_fetch_size(void) values = A_SIZE_FIX(agp_bridge.aperture_sizes); - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) { + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) { u32 temp, offset = 0; pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR,&temp); @@ -1375,7 +1379,8 @@ static int intel_i830_configure(void) current_size = A_SIZE_FIX(agp_bridge.current_size); - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR,&temp); else @@ -1392,7 +1397,8 @@ static int intel_i830_configure(void) CACHE_FLUSH(); if (agp_bridge.needs_scratch_page == TRUE) { - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) { + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) { for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) OUTREG32(intel_i830_private.gtt, i, agp_bridge.scratch_page); } else { @@ -1406,7 +1412,8 @@ static int intel_i830_configure(void) static void intel_i830_cleanup(void) { - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) iounmap((void *)intel_i830_private.gtt); iounmap((void *) intel_i830_private.registers); @@ -1441,7 +1448,8 @@ static int intel_i830_insert_entries(agp CACHE_FLUSH(); - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) { + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) { for (i = 0, j = pg_start; i < mem->page_count; i++, j++) OUTREG32(intel_i830_private.gtt, j, agp_bridge.mask_memory(mem->memory[i], mem->type)); } else { @@ -1467,7 +1475,8 @@ static int intel_i830_remove_entries(agp return (-EINVAL); } - if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0) { + if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_G_0 || + agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_915_GM_0) { for (i = pg_start; i < (mem->page_count + pg_start); i++) OUTREG32(intel_i830_private.gtt, i, agp_bridge.scratch_page); } else { @@ -6270,6 +6279,13 @@ static struct { "915G", intel_845_setup }, + { PCI_DEVICE_ID_INTEL_915_GM_0, + PCI_VENDOR_ID_INTEL, + INTEL_I915_GM, + "Intel(R)", + "915GM", + intel_845_setup }, + { PCI_DEVICE_ID_INTEL_840_0, PCI_VENDOR_ID_INTEL, INTEL_I840, @@ -7021,6 +7037,33 @@ static int __init agp_init_one(struct pc agp_bridge.type = INTEL_I810; return intel_i830_setup(i810_dev); + case PCI_DEVICE_ID_INTEL_915_GM_0: + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_915_GM_1, NULL); + if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_915_GM_1, i810_dev); + } + + if (i810_dev == NULL) { + /* + * We probably have a 915GM chipset + * with an external graphics + * card. It will be initialized later + */ + printk(KERN_ERR PFX "Detected an " + "Intel(R) 915GM, but could not" + " find the" + " secondary device. Assuming a " + "non-integrated video card.\n"); + agp_bridge.type = INTEL_I915_GM; + break; + } + printk(KERN_INFO PFX "Detected an Intel(R) " + "915GM Chipset.\n"); + agp_bridge.type = INTEL_I810; + return intel_i830_setup(i810_dev); + default: break; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/lcd.c linux-2.4.30-rc1/drivers/char/lcd.c --- linux-2.4.29/drivers/char/lcd.c 2005-01-19 14:09:46.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/lcd.c 2005-03-18 18:06:51.726061240 +0000 @@ -386,6 +386,8 @@ static int lcd_ioctl(struct inode *inode int ctr=0; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + // Chip Erase Sequence WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); @@ -422,6 +424,8 @@ static int lcd_ioctl(struct inode *inode struct lcd_display display; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) return -EFAULT; rom = (unsigned char *) kmalloc((128),GFP_ATOMIC); @@ -434,8 +438,10 @@ static int lcd_ioctl(struct inode *inode save_flags(flags); for (i=0; i LP_BUFFER_SIZE) copy_size = LP_BUFFER_SIZE; - if (copy_from_user (kbuf, buf, copy_size)) - return -EFAULT; - if (down_interruptible (&lp_table[minor].port_mutex)) return -EINTR; + if (copy_from_user (kbuf, buf, copy_size)) { + retv = -EFAULT; + goto out_unlock; + } + /* Claim Parport or sleep until it becomes available */ lp_claim_parport_or_block (&lp_table[minor]); @@ -398,7 +400,7 @@ static ssize_t lp_write(struct file * fi lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; lp_release_parport (&lp_table[minor]); } - +out_unlock: up (&lp_table[minor].port_mutex); return retv; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/pty.c linux-2.4.30-rc1/drivers/char/pty.c --- linux-2.4.29/drivers/char/pty.c 2005-01-19 14:09:48.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/pty.c 2005-03-18 18:07:01.783532272 +0000 @@ -218,13 +218,15 @@ static int pty_write_room(struct tty_str static int pty_chars_in_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; + ssize_t (*chars_in_buffer)(struct tty_struct *); int count; - if (!to || !to->ldisc.chars_in_buffer) + /* We should get the line discipline lock for "tty->link" */ + if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer)) return 0; /* The ldisc must report 0 if no characters available to be read */ - count = to->ldisc.chars_in_buffer(to); + count = chars_in_buffer(to); if (tty->driver.subtype == PTY_TYPE_SLAVE) return count; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/softdog.c linux-2.4.30-rc1/drivers/char/softdog.c --- linux-2.4.29/drivers/char/softdog.c 2003-11-28 18:26:20.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/softdog.c 2005-03-18 18:07:15.087509760 +0000 @@ -124,7 +124,7 @@ static int softdog_release(struct inode * Shut off the timer. * Lock it in if it's a module and we set nowayout */ - if (expect_close || nowayout == 0) { + if (expect_close && nowayout == 0) { del_timer(&watchdog_ticktock); } else { printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly. WDT will not stop!\n"); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/char/synclinkmp.c linux-2.4.30-rc1/drivers/char/synclinkmp.c --- linux-2.4.29/drivers/char/synclinkmp.c 2005-01-19 14:09:53.000000000 +0000 +++ linux-2.4.30-rc1/drivers/char/synclinkmp.c 2005-03-18 18:07:23.368250896 +0000 @@ -1,5 +1,5 @@ /* - * $Id: synclinkmp.c,v 3.23 2004/08/24 19:49:48 paulkf Exp $ + * $Id: synclinkmp.c,v 3.27 2005/02/15 21:29:09 paulkf Exp $ * * Device driver for Microgate SyncLink Multiport * high speed multiprotocol serial adapter. @@ -504,7 +504,7 @@ MODULE_PARM(maxframe,"1-" __MODULE_STRIN MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i"); static char *driver_name = "SyncLink MultiPort driver"; -static char *driver_version = "$Revision: 3.23 $"; +static char *driver_version = "$Revision: 3.27 $"; static int __devinit synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void __devexit synclinkmp_remove_one(struct pci_dev *dev); @@ -4482,7 +4482,7 @@ void async_mode(SLMP_INFO *info) * 07..05 Reserved, must be 0 * 04..00 RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte */ - write_reg(info, TRC0, 0x00); + write_reg(info, RRC, 0x00); /* TRC0 Transmit Ready Control 0 * diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/i2c/i2c-algo-bit.c linux-2.4.30-rc1/drivers/i2c/i2c-algo-bit.c --- linux-2.4.29/drivers/i2c/i2c-algo-bit.c 2004-02-18 13:36:31.000000000 +0000 +++ linux-2.4.30-rc1/drivers/i2c/i2c-algo-bit.c 2005-03-18 18:07:33.224752480 +0000 @@ -28,14 +28,12 @@ #include #include #include -#include -#include #include #include - #include #include + /* ----- global defines ----------------------------------------------- */ #define DEB(x) if (i2c_debug>=1) x; #define DEB2(x) if (i2c_debug>=2) x; @@ -522,8 +520,8 @@ static int algo_control(struct i2c_adapt static u32 bit_func(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | - I2C_FUNC_PROTOCOL_MANGLING; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/i2c/i2c-algo-pcf.c linux-2.4.30-rc1/drivers/i2c/i2c-algo-pcf.c --- linux-2.4.29/drivers/i2c/i2c-algo-pcf.c 2004-02-18 13:36:31.000000000 +0000 +++ linux-2.4.30-rc1/drivers/i2c/i2c-algo-pcf.c 2005-03-18 18:08:04.525993968 +0000 @@ -32,15 +32,13 @@ #include #include #include -#include -#include #include #include - #include #include #include "i2c-pcf8584.h" + /* ----- global defines ----------------------------------------------- */ #define DEB(x) if (i2c_debug>=1) x #define DEB2(x) if (i2c_debug>=2) x @@ -435,8 +433,8 @@ static int algo_control(struct i2c_adapt static u32 pcf_func(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | - I2C_FUNC_PROTOCOL_MANGLING; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; } /* -----exported algorithm data: ------------------------------------- */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/ide/ide-cd.c linux-2.4.30-rc1/drivers/ide/ide-cd.c --- linux-2.4.29/drivers/ide/ide-cd.c 2003-11-28 18:26:20.000000000 +0000 +++ linux-2.4.30-rc1/drivers/ide/ide-cd.c 2005-03-18 18:07:18.608974416 +0000 @@ -2206,25 +2206,31 @@ static int cdrom_read_toc(ide_drive_t *d /* Read the multisession information. */ if (toc->hdr.first_track != CDROM_LEADOUT) { /* Read the multisession information. */ - stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, + stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp, sizeof(ms_tmp), sense); if (stat) return stat; + + toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba); } else { - ms_tmp.ent.addr.msf.minute = 0; - ms_tmp.ent.addr.msf.second = 2; - ms_tmp.ent.addr.msf.frame = 0; ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT; + toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */ } #if ! STANDARD_ATAPI - if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) + if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) { + /* Re-read multisession information using MSF format */ + stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, + sizeof(ms_tmp), sense); + if (stat) + return stat; + msf_from_bcd (&ms_tmp.ent.addr.msf); + toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute, + ms_tmp.ent.addr.msf.second, + ms_tmp.ent.addr.msf.frame); + } #endif /* not STANDARD_ATAPI */ - toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.minute, - ms_tmp.ent.addr.msf.second, - ms_tmp.ent.addr.msf.frame); - toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); /* Now try to get the total cdrom capacity. */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/isdn/hisax/ipacx.c linux-2.4.30-rc1/drivers/isdn/hisax/ipacx.c --- linux-2.4.29/drivers/isdn/hisax/ipacx.c 2002-11-28 23:53:13.000000000 +0000 +++ linux-2.4.30-rc1/drivers/isdn/hisax/ipacx.c 2005-03-18 18:06:35.034598728 +0000 @@ -152,7 +152,13 @@ dch_l2l1(struct PStack *st, int pr, void case (HW_RESET | REQUEST): case (HW_ENABLE | REQUEST): - ph_command(cs, IPACX_CMD_TIM); + if ((cs->dc.isac.ph_state == IPACX_IND_RES) || + (cs->dc.isac.ph_state == IPACX_IND_DR) || + (cs->dc.isac.ph_state == IPACX_IND_DC)) + ph_command(cs, IPACX_CMD_TIM); + else + ph_command(cs, IPACX_CMD_RES); + break; case (HW_INFO3 | REQUEST): diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/md/lvm-snap.c linux-2.4.30-rc1/drivers/md/lvm-snap.c --- linux-2.4.29/drivers/md/lvm-snap.c 2004-04-14 13:05:30.000000000 +0000 +++ linux-2.4.30-rc1/drivers/md/lvm-snap.c 2005-03-18 18:07:58.331935608 +0000 @@ -119,7 +119,6 @@ static inline lv_block_exception_t *lvm_ unsigned long mask = lv->lv_snapshot_hash_mask; int chunk_size = lv->lv_chunk_size; lv_block_exception_t *ret; - int i = 0; hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; @@ -132,15 +131,9 @@ static inline lv_block_exception_t *lvm_ exception = list_entry(next, lv_block_exception_t, hash); if (exception->rsector_org == org_start && exception->rdev_org == org_dev) { - if (i) { - /* fun, isn't it? :) */ - list_del(next); - list_add(next, hash_table); - } ret = exception; break; } - i++; } return ret; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/e1000/e1000.h linux-2.4.30-rc1/drivers/net/e1000/e1000.h --- linux-2.4.29/drivers/net/e1000/e1000.h 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/e1000/e1000.h 2005-03-18 18:07:07.944595648 +0000 @@ -140,6 +140,7 @@ struct e1000_adapter; #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ #define AUTO_ALL_MODES 0 +#define E1000_EEPROM_82544_APM 0x0004 #define E1000_EEPROM_APME 0x0400 #ifndef E1000_MASTER_SLAVE @@ -211,6 +212,7 @@ struct e1000_adapter { /* TX */ struct e1000_desc_ring tx_ring; + struct e1000_buffer previous_buffer_info; spinlock_t tx_lock; uint32_t txd_cmd; uint32_t tx_int_delay; @@ -224,6 +226,7 @@ struct e1000_adapter { uint32_t tx_fifo_size; atomic_t tx_fifo_stall; boolean_t pcix_82544; + boolean_t detect_tx_hung; /* RX */ struct e1000_desc_ring rx_ring; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/e1000/e1000_ethtool.c linux-2.4.30-rc1/drivers/net/e1000/e1000_ethtool.c --- linux-2.4.29/drivers/net/e1000/e1000_ethtool.c 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/e1000/e1000_ethtool.c 2005-03-18 18:07:51.687945648 +0000 @@ -1309,7 +1309,7 @@ e1000_run_loopback_test(struct e1000_ada struct e1000_desc_ring *txdr = &adapter->test_tx_ring; struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; - int i; + int i, ret_val; E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); @@ -1329,11 +1329,12 @@ e1000_run_loopback_test(struct e1000_ada rxdr->buffer_info[i].length, PCI_DMA_FROMDEVICE); - if (!e1000_check_lbtest_frame(rxdr->buffer_info[i++].skb, 1024)) - return 0; - } while (i < 64); + ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb, + 1024); + i++; + } while (ret_val != 0 && i < 64); - return 13; + return ret_val; } static int diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/e1000/e1000_hw.c linux-2.4.30-rc1/drivers/net/e1000/e1000_hw.c --- linux-2.4.29/drivers/net/e1000/e1000_hw.c 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/e1000/e1000_hw.c 2005-03-18 18:07:52.479825264 +0000 @@ -1573,7 +1573,8 @@ e1000_phy_force_speed_duplex(struct e100 if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay(100); } - if((i == 0) && (hw->phy_type == e1000_phy_m88)) { + if((i == 0) && + (hw->phy_type == e1000_phy_m88)) { /* We didn't get link. Reset the DSP and wait again for link. */ ret_val = e1000_phy_reset_dsp(hw); if(ret_val) { @@ -2504,7 +2505,7 @@ e1000_read_phy_reg(struct e1000_hw *hw, } } - ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); return ret_val; @@ -2610,7 +2611,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, } } - ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr, + ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, phy_data); return ret_val; @@ -2956,8 +2957,7 @@ e1000_phy_m88_get_info(struct e1000_hw * /* Check polarity status */ ret_val = e1000_check_polarity(hw, &polarity); if(ret_val) - return ret_val; - + return ret_val; phy_info->cable_polarity = polarity; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); @@ -2967,9 +2967,9 @@ e1000_phy_m88_get_info(struct e1000_hw * phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >> M88E1000_PSSR_MDIX_SHIFT; - if(phy_data & M88E1000_PSSR_1000MBS) { - /* Cable Length Estimation and Local/Remote Receiver Informatoion - * are only valid at 1000 Mbps + if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) { + /* Cable Length Estimation and Local/Remote Receiver Information + * are only valid at 1000 Mbps. */ phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT); @@ -4641,41 +4641,44 @@ e1000_get_bus_info(struct e1000_hw *hw) { uint32_t status; - if(hw->mac_type < e1000_82543) { + switch (hw->mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: hw->bus_type = e1000_bus_type_unknown; hw->bus_speed = e1000_bus_speed_unknown; hw->bus_width = e1000_bus_width_unknown; - return; - } - - status = E1000_READ_REG(hw, STATUS); - hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? - e1000_bus_type_pcix : e1000_bus_type_pci; + break; + default: + status = E1000_READ_REG(hw, STATUS); + hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? + e1000_bus_type_pcix : e1000_bus_type_pci; - if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { - hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ? - e1000_bus_speed_66 : e1000_bus_speed_120; - } else if(hw->bus_type == e1000_bus_type_pci) { - hw->bus_speed = (status & E1000_STATUS_PCI66) ? - e1000_bus_speed_66 : e1000_bus_speed_33; - } else { - switch (status & E1000_STATUS_PCIX_SPEED) { - case E1000_STATUS_PCIX_SPEED_66: - hw->bus_speed = e1000_bus_speed_66; - break; - case E1000_STATUS_PCIX_SPEED_100: - hw->bus_speed = e1000_bus_speed_100; - break; - case E1000_STATUS_PCIX_SPEED_133: - hw->bus_speed = e1000_bus_speed_133; - break; - default: - hw->bus_speed = e1000_bus_speed_reserved; - break; + if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { + hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ? + e1000_bus_speed_66 : e1000_bus_speed_120; + } else if(hw->bus_type == e1000_bus_type_pci) { + hw->bus_speed = (status & E1000_STATUS_PCI66) ? + e1000_bus_speed_66 : e1000_bus_speed_33; + } else { + switch (status & E1000_STATUS_PCIX_SPEED) { + case E1000_STATUS_PCIX_SPEED_66: + hw->bus_speed = e1000_bus_speed_66; + break; + case E1000_STATUS_PCIX_SPEED_100: + hw->bus_speed = e1000_bus_speed_100; + break; + case E1000_STATUS_PCIX_SPEED_133: + hw->bus_speed = e1000_bus_speed_133; + break; + default: + hw->bus_speed = e1000_bus_speed_reserved; + break; + } } + hw->bus_width = (status & E1000_STATUS_BUS64) ? + e1000_bus_width_64 : e1000_bus_width_32; + break; } - hw->bus_width = (status & E1000_STATUS_BUS64) ? - e1000_bus_width_64 : e1000_bus_width_32; } /****************************************************************************** * Reads a value from one of the devices registers using port I/O (as opposed @@ -4740,6 +4743,7 @@ e1000_get_cable_length(struct e1000_hw * uint16_t agc_value = 0; uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE; uint16_t i, phy_data; + uint16_t cable_length; DEBUGFUNC("e1000_get_cable_length"); @@ -4751,10 +4755,11 @@ e1000_get_cable_length(struct e1000_hw * &phy_data); if(ret_val) return ret_val; + cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT; /* Convert the enum value to ranged values */ - switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT) { + switch (cable_length) { case e1000_cable_length_50: *min_length = 0; *max_length = e1000_igp_cable_length_50; @@ -4921,8 +4926,7 @@ e1000_check_downshift(struct e1000_hw *h return ret_val; hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0; - } - else if(hw->phy_type == e1000_phy_m88) { + } else if(hw->phy_type == e1000_phy_m88) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if(ret_val) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/e1000/e1000_hw.h linux-2.4.30-rc1/drivers/net/e1000/e1000_hw.h --- linux-2.4.29/drivers/net/e1000/e1000_hw.h 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/e1000/e1000_hw.h 2005-03-18 18:06:36.658351880 +0000 @@ -36,7 +36,6 @@ #include "e1000_osdep.h" - /* Forward declarations of structures used by the shared code */ struct e1000_hw; struct e1000_hw_stats; @@ -370,6 +369,7 @@ int32_t e1000_set_d3_lplu_state(struct e #define E1000_DEV_ID_82546GB_SERDES 0x107B #define E1000_DEV_ID_82546GB_PCIE 0x108A #define E1000_DEV_ID_82547EI 0x1019 + #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 @@ -1735,6 +1735,9 @@ struct e1000_hw { #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */ + /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ #define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ @@ -1795,8 +1798,7 @@ struct e1000_hw { #define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 -#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ -#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/ + /* PHY Control Register */ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ #define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ @@ -2099,7 +2101,11 @@ struct e1000_hw { #define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080 #define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 + /* Bit definitions for valid PHY IDs. */ +/* I = Integrated + * E = External + */ #define M88E1000_E_PHY_ID 0x01410C50 #define M88E1000_I_PHY_ID 0x01410C30 #define M88E1011_I_PHY_ID 0x01410C20 diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/e1000/e1000_main.c linux-2.4.30-rc1/drivers/net/e1000/e1000_main.c --- linux-2.4.29/drivers/net/e1000/e1000_main.c 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/e1000/e1000_main.c 2005-03-18 18:07:14.649576336 +0000 @@ -34,6 +34,14 @@ * - if_mii support and associated kcompat for older kernels * - More errlogging support from Jon Mason * - Fix TSO issues on PPC64 machines -- Jon Mason + * 5.7.1 12/16/04 + * - Resurrect 82547EI/GI related fix in e1000_intr to avoid deadlocks. This + * fix was removed as it caused system instability. The suspected cause of + * this is the called to e1000_irq_disable in e1000_intr. Inlined the + * required piece of e1000_irq_disable into e1000_intr. + * 5.7.0 12/10/04 + * - include fix to the condition that determines when to quit NAPI - Robert Olsson + * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down * 5.6.5 11/01/04 * - Enabling NETIF_F_SG without checksum offload is illegal - John Mason @@ -41,8 +49,13 @@ * - Remove redundant initialization - Jamal Hadi * - Reset buffer_info->dma in tx resource cleanup logic * 5.6.2 10/12/04 + * - Avoid filling tx_ring completely - shemminger@osdl.org + * - Replace schedule_timeout() with msleep()/msleep_interruptible() - + * nacc@us.ibm.com * - Sparse cleanup - shemminger@osdl.org * - Fix tx resource cleanup logic + * - LLTX support - ak@suse.de and hadi@cyberus.ca + * - {set, get}_wol is now symmetric for 82545EM adapters */ char e1000_driver_name[] = "e1000"; @@ -52,7 +65,7 @@ char e1000_driver_string[] = "Intel(R) P #else #define DRIVERNAPI "-NAPI" #endif -char e1000_driver_version[] = "5.6.10.1-k1"DRIVERNAPI; +char e1000_driver_version[] = "5.7.6-k1"DRIVERNAPI; char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table @@ -76,6 +89,7 @@ static struct pci_device_id e1000_pci_tb INTEL_E1000_ETHERNET_DEVICE(0x1011), INTEL_E1000_ETHERNET_DEVICE(0x1012), INTEL_E1000_ETHERNET_DEVICE(0x1013), + INTEL_E1000_ETHERNET_DEVICE(0x1014), INTEL_E1000_ETHERNET_DEVICE(0x1015), INTEL_E1000_ETHERNET_DEVICE(0x1016), INTEL_E1000_ETHERNET_DEVICE(0x1017), @@ -303,6 +317,9 @@ e1000_up(struct e1000_adapter *adapter) mod_timer(&adapter->watchdog_timer, jiffies); e1000_irq_enable(adapter); +#ifdef CONFIG_E1000_NAPI + netif_poll_enable(netdev); +#endif return 0; } @@ -316,6 +333,10 @@ e1000_down(struct e1000_adapter *adapter del_timer_sync(&adapter->tx_fifo_stall_timer); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); + +#ifdef CONFIG_E1000_NAPI + netif_poll_disable(netdev); +#endif adapter->link_speed = 0; adapter->link_duplex = 0; netif_carrier_off(netdev); @@ -409,6 +430,7 @@ e1000_probe(struct pci_dev *pdev, int i; int err; uint16_t eeprom_data; + uint16_t eeprom_apme_mask = E1000_EEPROM_APME; if((err = pci_enable_device(pdev))) return err; @@ -505,9 +527,6 @@ e1000_probe(struct pci_dev *pdev, } #ifdef NETIF_F_TSO - /* Disbaled for now until root-cause is found for - * hangs reported against non-IA archs. TSO can be - * enabled using ethtool -K eth tso on */ if((adapter->hw.mac_type >= e1000_82544) && (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; @@ -576,6 +595,11 @@ e1000_probe(struct pci_dev *pdev, case e1000_82542_rev2_1: case e1000_82543: break; + case e1000_82544: + e1000_read_eeprom(&adapter->hw, + EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data); + eeprom_apme_mask = E1000_EEPROM_82544_APM; + break; case e1000_82546: case e1000_82546_rev_3: if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) @@ -590,7 +614,7 @@ e1000_probe(struct pci_dev *pdev, EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); break; } - if(eeprom_data & E1000_EEPROM_APME) + if(eeprom_data & eeprom_apme_mask) adapter->wol |= E1000_WUFC_MAG; /* reset the hardware with the new settings */ @@ -797,6 +821,31 @@ e1000_close(struct net_device *netdev) } /** + * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary + * @adapter: address of board private structure + * @begin: address of beginning of memory + * @end: address of end of memory + **/ +static inline boolean_t +e1000_check_64k_bound(struct e1000_adapter *adapter, + void *start, unsigned long len) +{ + unsigned long begin = (unsigned long) start; + unsigned long end = begin + len; + + /* first rev 82545 and 82546 need to not allow any memory + * write location to cross a 64k boundary due to errata 23 */ + if (adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546 ) { + + /* check buffer doesn't cross 64kB */ + return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE; + } + + return TRUE; +} + +/** * e1000_setup_tx_resources - allocate Tx resources (Descriptors) * @adapter: board private structure * @@ -826,11 +875,42 @@ e1000_setup_tx_resources(struct e1000_ad txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); if(!txdr->desc) { +setup_tx_desc_die: DPRINTK(PROBE, ERR, "Unable to Allocate Memory for the Transmit descriptor ring\n"); vfree(txdr->buffer_info); return -ENOMEM; } + + /* fix for errata 23, cant cross 64kB boundary */ + if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) { + void *olddesc = txdr->desc; + dma_addr_t olddma = txdr->dma; + DPRINTK(TX_ERR,ERR,"txdr align check failed: %u bytes at %p\n", + txdr->size, txdr->desc); + /* try again, without freeing the previous */ + txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); + /* failed allocation, critial failure */ + if(!txdr->desc) { + pci_free_consistent(pdev, txdr->size, olddesc, olddma); + goto setup_tx_desc_die; + } + + if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) { + /* give up */ + pci_free_consistent(pdev, txdr->size, + txdr->desc, txdr->dma); + pci_free_consistent(pdev, txdr->size, olddesc, olddma); + DPRINTK(PROBE, ERR, + "Unable to Allocate aligned Memory for the Transmit" + " descriptor ring\n"); + vfree(txdr->buffer_info); + return -ENOMEM; + } else { + /* free old, move on with the new one since its okay */ + pci_free_consistent(pdev, txdr->size, olddesc, olddma); + } + } memset(txdr->desc, 0, txdr->size); txdr->next_to_use = 0; @@ -948,11 +1028,43 @@ e1000_setup_rx_resources(struct e1000_ad rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); if(!rxdr->desc) { +setup_rx_desc_die: DPRINTK(PROBE, ERR, - "Unable to Allocate Memory for the Recieve descriptor ring\n"); + "Unble to Allocate Memory for the Recieve descriptor ring\n"); vfree(rxdr->buffer_info); return -ENOMEM; } + + /* fix for errata 23, cant cross 64kB boundary */ + if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) { + void *olddesc = rxdr->desc; + dma_addr_t olddma = rxdr->dma; + DPRINTK(RX_ERR,ERR, + "rxdr align check failed: %u bytes at %p\n", + rxdr->size, rxdr->desc); + /* try again, without freeing the previous */ + rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); + /* failed allocation, critial failure */ + if(!rxdr->desc) { + pci_free_consistent(pdev, rxdr->size, olddesc, olddma); + goto setup_rx_desc_die; + } + + if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) { + /* give up */ + pci_free_consistent(pdev, rxdr->size, + rxdr->desc, rxdr->dma); + pci_free_consistent(pdev, rxdr->size, olddesc, olddma); + DPRINTK(PROBE, ERR, + "Unable to Allocate aligned Memory for the" + " Receive descriptor ring\n"); + vfree(rxdr->buffer_info); + return -ENOMEM; + } else { + /* free old, move on with the new one since its okay */ + pci_free_consistent(pdev, rxdr->size, olddesc, olddma); + } + } memset(rxdr->desc, 0, rxdr->size); rxdr->next_to_clean = 0; @@ -1086,6 +1198,7 @@ e1000_unmap_and_free_tx_resource(struct struct e1000_buffer *buffer_info) { struct pci_dev *pdev = adapter->pdev; + if(buffer_info->dma) { pci_unmap_page(pdev, buffer_info->dma, @@ -1114,6 +1227,11 @@ e1000_clean_tx_ring(struct e1000_adapter /* Free all the Tx ring sk_buffs */ + if (likely(adapter->previous_buffer_info.skb != NULL)) { + e1000_unmap_and_free_tx_resource(adapter, + &adapter->previous_buffer_info); + } + for(i = 0; i < tx_ring->count; i++) { buffer_info = &tx_ring->buffer_info[i]; e1000_unmap_and_free_tx_resource(adapter, buffer_info); @@ -1415,7 +1533,6 @@ e1000_watchdog(unsigned long data) struct e1000_adapter *adapter = (struct e1000_adapter *) data; struct net_device *netdev = adapter->netdev; struct e1000_desc_ring *txdr = &adapter->tx_ring; - unsigned int i; uint32_t link; e1000_check_for_link(&adapter->hw); @@ -1495,12 +1612,8 @@ e1000_watchdog(unsigned long data) /* Cause software interrupt to ensure rx ring is cleaned */ E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0); - /* Early detection of hung controller */ - i = txdr->next_to_clean; - if(txdr->buffer_info[i].dma && - time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) && - !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) - netif_stop_queue(netdev); + /* Force detection of hung controller every watchdog period*/ + adapter->detect_tx_hung = TRUE; /* Reset the timer */ mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); @@ -2132,10 +2245,28 @@ e1000_intr(int irq, void *data, struct p __netif_rx_schedule(netdev); } #else + /* Writing IMC and IMS is needed for 82547. + Due to Hub Link bus being occupied, an interrupt + de-assertion message is not able to be sent. + When an interrupt assertion message is generated later, + two messages are re-ordered and sent out. + That causes APIC to think 82547 is in de-assertion + state, while 82547 is in assertion state, resulting + in dead lock. Writing IMC forces 82547 into + de-assertion state. + */ + if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){ + atomic_inc(&adapter->irq_sem); + E1000_WRITE_REG(&adapter->hw, IMC, ~0); + } + for(i = 0; i < E1000_MAX_INTR; i++) if(unlikely(!e1000_clean_rx_irq(adapter) & !e1000_clean_tx_irq(adapter))) break; + + if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) + e1000_irq_enable(adapter); #endif return IRQ_HANDLED; @@ -2155,24 +2286,21 @@ e1000_clean(struct net_device *netdev, i int tx_cleaned; int work_done = 0; - if (!netif_carrier_ok(netdev)) - goto quit_polling; - tx_cleaned = e1000_clean_tx_irq(adapter); e1000_clean_rx_irq(adapter, &work_done, work_to_do); *budget -= work_done; netdev->quota -= work_done; - /* if no Rx and Tx cleanup work was done, exit the polling mode */ - if(!tx_cleaned || (work_done < work_to_do) || + /* if no Tx and not enough Rx work done, exit the polling mode */ + if((!tx_cleaned && (work_done < work_to_do)) || !netif_running(netdev)) { -quit_polling: netif_rx_complete(netdev); + netif_rx_complete(netdev); e1000_irq_enable(adapter); return 0; } - return (work_done >= work_to_do); + return 1; } #endif @@ -2196,11 +2324,34 @@ e1000_clean_tx_irq(struct e1000_adapter eop_desc = E1000_TX_DESC(*tx_ring, eop); while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { + /* pre-mature writeback of Tx descriptors */ + /* clear (free buffers and unmap pci_mapping) */ + /* previous_buffer_info */ + if (likely(adapter->previous_buffer_info.skb != NULL)) { + e1000_unmap_and_free_tx_resource(adapter, + &adapter->previous_buffer_info); + } + for(cleaned = FALSE; !cleaned; ) { tx_desc = E1000_TX_DESC(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; + cleaned = (i == eop); + + /* pre-mature writeback of Tx descriptors */ + /* save the cleaning of the this for the */ + /* next iteration */ + if (cleaned) { + memcpy(&adapter->previous_buffer_info, + buffer_info, + sizeof(struct e1000_buffer)); + memset(buffer_info, + 0, + sizeof(struct e1000_buffer)); + } else { + e1000_unmap_and_free_tx_resource(adapter, + buffer_info); + } - e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->buffer_addr = 0; tx_desc->lower.data = 0; tx_desc->upper.data = 0; @@ -2222,6 +2373,16 @@ e1000_clean_tx_irq(struct e1000_adapter netif_wake_queue(netdev); spin_unlock(&adapter->tx_lock); + + if(adapter->detect_tx_hung) { + /* detect a transmit hang in hardware, this serializes the + * check with the clearing of time_stamp and movement of i */ + adapter->detect_tx_hung = FALSE; + if(tx_ring->buffer_info[i].dma && + time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) && + !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) + netif_stop_queue(netdev); + } return cleaned; } @@ -2389,20 +2550,43 @@ e1000_alloc_rx_buffers(struct e1000_adap struct e1000_buffer *buffer_info; struct sk_buff *skb; int reserve_len = 2; - unsigned int i; + unsigned int i, bufsz; i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; while(!buffer_info->skb) { + bufsz = adapter->rx_buffer_len + reserve_len; - skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); - + skb = dev_alloc_skb(bufsz); if(unlikely(!skb)) { /* Better luck next round */ break; } + /* fix for errata 23, cant cross 64kB boundary */ + if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { + struct sk_buff *oldskb = skb; + DPRINTK(RX_ERR,ERR, + "skb align check failed: %u bytes at %p\n", + bufsz, skb->data); + /* try again, without freeing the previous */ + skb = dev_alloc_skb(bufsz); + if (!skb) { + dev_kfree_skb(oldskb); + break; + } + if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { + /* give up */ + dev_kfree_skb(skb); + dev_kfree_skb(oldskb); + break; /* while !buffer_info->skb */ + } else { + /* move on with the new one */ + dev_kfree_skb(oldskb); + } + } + /* Make buffer alignment 2 beyond a 16 byte boundary * this will result in a 16 byte aligned IP header after * the 14 byte MAC header is removed @@ -2418,6 +2602,25 @@ e1000_alloc_rx_buffers(struct e1000_adap adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); + /* fix for errata 23, cant cross 64kB boundary */ + if(!e1000_check_64k_bound(adapter, + (void *)(unsigned long)buffer_info->dma, + adapter->rx_buffer_len)) { + DPRINTK(RX_ERR,ERR, + "dma align check failed: %u bytes at %ld\n", + adapter->rx_buffer_len, (unsigned long)buffer_info->dma); + + dev_kfree_skb(skb); + buffer_info->skb = NULL; + + pci_unmap_single(pdev, + buffer_info->dma, + adapter->rx_buffer_len, + PCI_DMA_FROMDEVICE); + + break; /* while !buffer_info->skb */ + } + rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/ppp_async.c linux-2.4.30-rc1/drivers/net/ppp_async.c --- linux-2.4.29/drivers/net/ppp_async.c 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/ppp_async.c 2005-03-18 18:07:58.632889856 +0000 @@ -996,7 +996,7 @@ static void async_lcp_peek(struct asyncp data += 4; dlen -= 4; /* data[0] is code, data[1] is length */ - while (dlen >= 2 && dlen >= data[1]) { + while (dlen >= 2 && dlen >= data[1] && data[1] >= 2) { switch (data[0]) { case LCP_MRU: val = (data[2] << 8) + data[3]; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/sk98lin/skvpd.c linux-2.4.30-rc1/drivers/net/sk98lin/skvpd.c --- linux-2.4.29/drivers/net/sk98lin/skvpd.c 2004-04-14 13:05:30.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/sk98lin/skvpd.c 2005-03-18 18:07:39.665773296 +0000 @@ -466,6 +466,15 @@ SK_IOC IoC) /* IO Context */ pAC->vpd.vpd_size = vpd_size; + /* Asus K8V Se Deluxe bugfix. Correct VPD content */ + /* MBo April 2004 */ + if( ((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) && + ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) && + ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45) ) { + printk(KERN_INFO "sk98lin : humm... Asus mainboard with buggy VPD ? correcting data.\n"); + (unsigned char)pAC->vpd.vpd_buf[0x40] = 0x38; + } + /* find the end tag of the RO area */ if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tg3.c linux-2.4.30-rc1/drivers/net/tg3.c --- linux-2.4.29/drivers/net/tg3.c 2005-01-19 14:09:56.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tg3.c 2005-03-18 18:07:15.158498968 +0000 @@ -59,8 +59,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.15" -#define DRV_MODULE_RELDATE "January 6, 2005" +#define DRV_MODULE_VERSION "3.24" +#define DRV_MODULE_RELDATE "March 4, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -575,9 +575,10 @@ static void tg3_phy_set_wirespeed(struct if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) return; - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007); - tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); - tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4))); + if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) && + !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val)) + tg3_writephy(tp, MII_TG3_AUX_CTRL, + (val | (1 << 15) | (1 << 4))); } static int tg3_bmcr_reset(struct tg3 *tp) @@ -618,9 +619,10 @@ static int tg3_wait_macro_done(struct tg while (limit--) { u32 tmp32; - tg3_readphy(tp, 0x16, &tmp32); - if ((tmp32 & 0x1000) == 0) - break; + if (!tg3_readphy(tp, 0x16, &tmp32)) { + if ((tmp32 & 0x1000) == 0) + break; + } } if (limit <= 0) return -EBUSY; @@ -672,9 +674,9 @@ static int tg3_phy_write_and_check_testp for (i = 0; i < 6; i += 2) { u32 low, high; - tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low); - tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high); - if (tg3_wait_macro_done(tp)) { + if (tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low) || + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high) || + tg3_wait_macro_done(tp)) { *resetp = 1; return -EBUSY; } @@ -730,7 +732,9 @@ static int tg3_phy_reset_5703_4_5(struct } /* Disable transmitter and interrupt. */ - tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); + if (tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) + continue; + reg32 |= 0x3000; tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); @@ -739,7 +743,9 @@ static int tg3_phy_reset_5703_4_5(struct BMCR_FULLDPLX | TG3_BMCR_SPEED1000); /* Set to master mode. */ - tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig); + if (tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig)) + continue; + tg3_writephy(tp, MII_TG3_CTRL, (MII_TG3_CTRL_AS_MASTER | MII_TG3_CTRL_ENABLE_AS_MASTER)); @@ -777,9 +783,11 @@ static int tg3_phy_reset_5703_4_5(struct tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); - tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); - reg32 &= ~0x3000; - tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { + reg32 &= ~0x3000; + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); + } else if (!err) + err = -EBUSY; return err; } @@ -843,9 +851,9 @@ out: u32 phy_reg; /* Set bit 14 with read-modify-write to preserve other bits */ - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007); - tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg); - tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); + if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) && + !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg)) + tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); } tg3_phy_set_wirespeed(tp); return 0; @@ -877,7 +885,7 @@ static void tg3_frob_aux_power(struct tg GRC_LCLCTRL_GPIO_OUTPUT1)); udelay(100); } else { - int no_gpio2; + u32 no_gpio2; u32 grc_local_ctrl; if (tp_peer != tp && @@ -885,8 +893,8 @@ static void tg3_frob_aux_power(struct tg return; /* On 5753 and variants, GPIO2 cannot be used. */ - no_gpio2 = (tp->nic_sram_data_cfg & - NIC_SRAM_DATA_CFG_NO_GPIO2) != 0; + no_gpio2 = tp->nic_sram_data_cfg & + NIC_SRAM_DATA_CFG_NO_GPIO2; grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 | @@ -898,29 +906,17 @@ static void tg3_frob_aux_power(struct tg GRC_LCLCTRL_GPIO_OUTPUT2); } tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl); + grc_local_ctrl); udelay(100); - grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1 | - GRC_LCLCTRL_GPIO_OUTPUT2; - if (no_gpio2) { - grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT2); - } + grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | - grc_local_ctrl); + grc_local_ctrl); udelay(100); - grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | - GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | - GRC_LCLCTRL_GPIO_OUTPUT1; if (!no_gpio2) { + grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | grc_local_ctrl); udelay(100); @@ -1240,7 +1236,7 @@ static void tg3_aux_stat_to_speed_duplex }; } -static int tg3_phy_copper_begin(struct tg3 *tp) +static void tg3_phy_copper_begin(struct tg3 *tp) { u32 new_adv; int i; @@ -1355,15 +1351,16 @@ static int tg3_phy_copper_begin(struct t if (tp->link_config.duplex == DUPLEX_FULL) bmcr |= BMCR_FULLDPLX; - tg3_readphy(tp, MII_BMCR, &orig_bmcr); - if (bmcr != orig_bmcr) { + if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) && + (bmcr != orig_bmcr)) { tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK); for (i = 0; i < 1500; i++) { u32 tmp; udelay(10); - tg3_readphy(tp, MII_BMSR, &tmp); - tg3_readphy(tp, MII_BMSR, &tmp); + if (tg3_readphy(tp, MII_BMSR, &tmp) || + tg3_readphy(tp, MII_BMSR, &tmp)) + continue; if (!(tmp & BMSR_LSTATUS)) { udelay(40); break; @@ -1376,8 +1373,6 @@ static int tg3_phy_copper_begin(struct t tg3_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); } - - return 0; } static int tg3_init_5401phy_dsp(struct tg3 *tp) @@ -1412,7 +1407,9 @@ static int tg3_copper_is_advertising_all { u32 adv_reg, all_mask; - tg3_readphy(tp, MII_ADVERTISE, &adv_reg); + if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) + return 0; + all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL); if ((adv_reg & all_mask) != all_mask) @@ -1420,7 +1417,9 @@ static int tg3_copper_is_advertising_all if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { u32 tg3_ctrl; - tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl); + if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) + return 0; + all_mask = (MII_TG3_CTRL_ADV_1000_HALF | MII_TG3_CTRL_ADV_1000_FULL); if ((tg3_ctrl & all_mask) != all_mask) @@ -1460,8 +1459,8 @@ static int tg3_setup_copper_phy(struct t GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && netif_carrier_ok(tp->dev)) { tg3_readphy(tp, MII_BMSR, &bmsr); - tg3_readphy(tp, MII_BMSR, &bmsr); - if (!(bmsr & BMSR_LSTATUS)) + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + !(bmsr & BMSR_LSTATUS)) force_reset = 1; } if (force_reset) @@ -1469,9 +1468,8 @@ static int tg3_setup_copper_phy(struct t if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { tg3_readphy(tp, MII_BMSR, &bmsr); - tg3_readphy(tp, MII_BMSR, &bmsr); - - if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) + if (tg3_readphy(tp, MII_BMSR, &bmsr) || + !(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) bmsr = 0; if (!(bmsr & BMSR_LSTATUS)) { @@ -1482,8 +1480,8 @@ static int tg3_setup_copper_phy(struct t tg3_readphy(tp, MII_BMSR, &bmsr); for (i = 0; i < 1000; i++) { udelay(10); - tg3_readphy(tp, MII_BMSR, &bmsr); - if (bmsr & BMSR_LSTATUS) { + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + (bmsr & BMSR_LSTATUS)) { udelay(40); break; } @@ -1545,8 +1543,8 @@ static int tg3_setup_copper_phy(struct t bmsr = 0; for (i = 0; i < 100; i++) { tg3_readphy(tp, MII_BMSR, &bmsr); - tg3_readphy(tp, MII_BMSR, &bmsr); - if (bmsr & BMSR_LSTATUS) + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + (bmsr & BMSR_LSTATUS)) break; udelay(40); } @@ -1557,8 +1555,8 @@ static int tg3_setup_copper_phy(struct t tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat); for (i = 0; i < 2000; i++) { udelay(10); - tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat); - if (aux_stat) + if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) && + aux_stat) break; } @@ -1569,7 +1567,8 @@ static int tg3_setup_copper_phy(struct t bmcr = 0; for (i = 0; i < 200; i++) { tg3_readphy(tp, MII_BMCR, &bmcr); - tg3_readphy(tp, MII_BMCR, &bmcr); + if (tg3_readphy(tp, MII_BMCR, &bmcr)) + continue; if (bmcr && bmcr != 0x7fff) break; udelay(10); @@ -1606,10 +1605,13 @@ static int tg3_setup_copper_phy(struct t (tp->link_config.autoneg == AUTONEG_ENABLE)) { u32 local_adv, remote_adv; - tg3_readphy(tp, MII_ADVERTISE, &local_adv); + if (tg3_readphy(tp, MII_ADVERTISE, &local_adv)) + local_adv = 0; local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - tg3_readphy(tp, MII_LPA, &remote_adv); + if (tg3_readphy(tp, MII_LPA, &remote_adv)) + remote_adv = 0; + remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM); /* If we are not advertising full pause capability, @@ -1628,8 +1630,8 @@ relink: tg3_phy_copper_begin(tp); tg3_readphy(tp, MII_BMSR, &tmp); - tg3_readphy(tp, MII_BMSR, &tmp); - if (tmp & BMSR_LSTATUS) + if (!tg3_readphy(tp, MII_BMSR, &tmp) && + (tmp & BMSR_LSTATUS)) current_link_up = 1; } @@ -2130,8 +2132,9 @@ static int tg3_setup_fiber_hw_autoneg(st if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) port_a = 0; - serdes_cfg = tr32(MAC_SERDES_CFG) & - ((1 << 23) | (1 << 22) | (1 << 21) | (1 << 20)); + /* preserve bits 0-11,13,14 for signal pre-emphasis */ + /* preserve bits 20-23 for voltage regulator */ + serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff; } sg_dig_ctrl = tr32(SG_DIG_CTRL); @@ -2142,9 +2145,9 @@ static int tg3_setup_fiber_hw_autoneg(st u32 val = serdes_cfg; if (port_a) - val |= 0xc010880; + val |= 0xc010000; else - val |= 0x4010880; + val |= 0x4010000; tw32_f(MAC_SERDES_CFG, val); } tw32_f(SG_DIG_CTRL, 0x01388400); @@ -2167,7 +2170,7 @@ static int tg3_setup_fiber_hw_autoneg(st if (sg_dig_ctrl != expected_sg_dig_ctrl) { if (workaround) - tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011880); + tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30)); udelay(5); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); @@ -2208,9 +2211,9 @@ static int tg3_setup_fiber_hw_autoneg(st u32 val = serdes_cfg; if (port_a) - val |= 0xc010880; + val |= 0xc010000; else - val |= 0x4010880; + val |= 0x4010000; tw32_f(MAC_SERDES_CFG, val); } @@ -2218,8 +2221,12 @@ static int tg3_setup_fiber_hw_autoneg(st tw32_f(SG_DIG_CTRL, 0x01388400); udelay(40); + /* Link parallel detection - link is up */ + /* only if we have PCS_SYNC and not */ + /* receiving config code words */ mac_status = tr32(MAC_STATUS); - if (mac_status & MAC_STATUS_PCS_SYNCED) { + if ((mac_status & MAC_STATUS_PCS_SYNCED) && + !(mac_status & MAC_STATUS_RCVD_CFG)) { tg3_setup_flow_control(tp, 0, 0); current_link_up = 1; } @@ -2690,7 +2697,11 @@ static int tg3_rx(struct tg3 *tp, int bu len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */ - if (len > RX_COPY_THRESHOLD) { + if (len > RX_COPY_THRESHOLD + && tp->rx_offset == 2 + /* rx_offset != 2 iff this is a 5701 card running + * in PCI-X mode [see tg3_get_invariants()] */ + ) { int skb_size; skb_size = tg3_alloc_rx_skb(tp, opaque_key, @@ -3085,11 +3096,19 @@ static int tg3_start_xmit(struct sk_buff skb->nh.iph->check = 0; skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); - skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, - skb->nh.iph->daddr, - 0, IPPROTO_TCP, 0); + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { + skb->h.th->check = 0; + base_flags &= ~TXD_FLAG_TCPUDP_CSUM; + } + else { + skb->h.th->check = + ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) { if (tcp_opt_len || skb->nh.iph->ihl > 5) { int tsflags; @@ -3156,7 +3175,7 @@ static int tg3_start_xmit(struct sk_buff would_hit_hwbug = entry + 1; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tg3_set_txd(tp, entry, mapping, len, base_flags, (i == last)|(mss << 1)); else @@ -3655,8 +3674,9 @@ static void tg3_nvram_unlock(struct tg3 /* tp->lock is held. */ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) { - tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { switch (kind) { @@ -3860,19 +3880,20 @@ static int tg3_chip_reset(struct tg3 *tp tw32_f(MAC_MODE, 0); udelay(40); - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { - printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " - "firmware will not restart magic=%08x\n", - tp->dev->name, val); - return -ENODEV; + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + if (i >= 100000) { + printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " + "firmware will not restart magic=%08x\n", + tp->dev->name, val); + return -ENODEV; + } } if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && @@ -4747,7 +4768,7 @@ static int tg3_load_tso_firmware(struct unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err, i; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) return 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { @@ -4831,9 +4852,8 @@ static void __tg3_set_mac_addr(struct tg tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { for (i = 0; i < 12; i++) { tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high); tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low); @@ -4879,7 +4899,8 @@ static void tg3_set_bdinfo(struct tg3 *t (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS), maxlen_flags); - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750)) tg3_write_mem(tp, (bdinfo_addr + TG3_BDINFO_NIC_ADDR), nic_addr); @@ -5181,7 +5202,7 @@ static int tg3_reset_hw(struct tg3 *tp) } #if TG3_TSO_SUPPORT != 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) rdmac_mode |= (1 << 27); #endif @@ -5331,7 +5352,7 @@ static int tg3_reset_hw(struct tg3 *tp) tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); #if TG3_TSO_SUPPORT != 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); #endif tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE); @@ -5381,8 +5402,10 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(10); if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + !(tp->tg3_flags2 & TG3_FLG2_SERDES_PREEMPHASIS)) { /* Set drive transmission level to 1.2V */ + /* only if the signal pre-emphasis bit is not set */ val = tr32(MAC_SERDES_CFG); val &= 0xfffff000; val |= 0x880; @@ -5411,9 +5434,10 @@ static int tg3_reset_hw(struct tg3 *tp) u32 tmp; /* Clear CRC stats. */ - tg3_readphy(tp, 0x1e, &tmp); - tg3_writephy(tp, 0x1e, tmp | 0x8000); - tg3_readphy(tp, 0x14, &tmp); + if (!tg3_readphy(tp, 0x1e, &tmp)) { + tg3_writephy(tp, 0x1e, tmp | 0x8000); + tg3_readphy(tp, 0x14, &tmp); + } } __tg3_set_rx_mode(tp->dev); @@ -6003,9 +6027,11 @@ static unsigned long calc_crc_errors(str u32 val; spin_lock_irqsave(&tp->lock, flags); - tg3_readphy(tp, 0x1e, &val); - tg3_writephy(tp, 0x1e, val | 0x8000); - tg3_readphy(tp, 0x14, &val); + if (!tg3_readphy(tp, 0x1e, &val)) { + tg3_writephy(tp, 0x1e, val | 0x8000); + tg3_readphy(tp, 0x14, &val); + } else + val = 0; spin_unlock_irqrestore(&tp->lock, flags); tp->phy_crc_errors += val; @@ -6349,11 +6375,13 @@ do { p = (u32 *)(orig_p + (reg)); \ static int tg3_get_eeprom_len(struct net_device *dev) { - return EEPROM_CHIP_SIZE; + struct tg3 *tp = netdev_priv(dev); + + return tp->nvram_size; } -static int tg3_nvram_read_using_eeprom(struct tg3 *tp, - u32 offset, u32 *val); +static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val); + static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct tg3 *tp = dev->priv; @@ -6365,10 +6393,7 @@ static int tg3_get_eeprom(struct net_dev len = eeprom->len; eeprom->len = 0; - ret = tg3_nvram_read_using_eeprom(tp, 0, &eeprom->magic); - if (ret) - return ret; - eeprom->magic = swab32(eeprom->magic); + eeprom->magic = TG3_EEPROM_MAGIC; if (offset & 3) { /* adjustments to start on required 4 byte boundary */ @@ -6378,9 +6403,10 @@ static int tg3_get_eeprom(struct net_dev /* i.e. offset=1 len=2 */ b_count = len; } - ret = tg3_nvram_read_using_eeprom(tp, offset-b_offset, &val); + ret = tg3_nvram_read(tp, offset-b_offset, &val); if (ret) return ret; + val = cpu_to_le32(val); memcpy(data, ((char*)&val) + b_offset, b_count); len -= b_count; offset += b_count; @@ -6390,12 +6416,13 @@ static int tg3_get_eeprom(struct net_dev /* read bytes upto the last 4 byte boundary */ pd = &data[eeprom->len]; for (i = 0; i < (len - (len & 3)); i += 4) { - ret = tg3_nvram_read_using_eeprom(tp, offset + i, - (u32*)(pd + i)); + ret = tg3_nvram_read(tp, offset + i, &val); if (ret) { eeprom->len += i; return ret; } + val = cpu_to_le32(val); + memcpy(pd + i, &val, 4); } eeprom->len += i; @@ -6404,15 +6431,72 @@ static int tg3_get_eeprom(struct net_dev pd = &data[eeprom->len]; b_count = len & 3; b_offset = offset + len - b_count; - ret = tg3_nvram_read_using_eeprom(tp, b_offset, &val); + ret = tg3_nvram_read(tp, b_offset, &val); if (ret) return ret; + val = cpu_to_le32(val); memcpy(pd, ((char*)&val), b_count); eeprom->len += b_count; } return 0; } +static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf); + +static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) +{ + struct tg3 *tp = netdev_priv(dev); + int ret; + u32 offset, len, b_offset, odd_len, start, end; + u8 *buf; + + if (eeprom->magic != TG3_EEPROM_MAGIC) + return -EINVAL; + + offset = eeprom->offset; + len = eeprom->len; + + if ((b_offset = (offset & 3))) { + /* adjustments to start on required 4 byte boundary */ + ret = tg3_nvram_read(tp, offset-b_offset, &start); + if (ret) + return ret; + start = cpu_to_le32(start); + len += b_offset; + offset &= ~3; + } + + odd_len = 0; + if ((len & 3) && ((len > 4) || (b_offset == 0))) { + /* adjustments to end on required 4 byte boundary */ + odd_len = 1; + len = (len + 3) & ~3; + ret = tg3_nvram_read(tp, offset+len-4, &end); + if (ret) + return ret; + end = cpu_to_le32(end); + } + + buf = data; + if (b_offset || odd_len) { + buf = kmalloc(len, GFP_KERNEL); + if (buf == 0) + return -ENOMEM; + if (b_offset) + memcpy(buf, &start, 4); + if (odd_len) + memcpy(buf+len-4, &end, 4); + memcpy(buf + b_offset, data, eeprom->len); + } + + ret = tg3_nvram_write_block(tp, offset, len, buf); + + if (buf != data) + kfree(buf); + + return ret; +} + static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct tg3 *tp = netdev_priv(dev); @@ -6561,10 +6645,10 @@ static int tg3_nway_reset(struct net_dev int r; spin_lock_irq(&tp->lock); - tg3_readphy(tp, MII_BMCR, &bmcr); - tg3_readphy(tp, MII_BMCR, &bmcr); r = -EINVAL; - if (bmcr & BMCR_ANENABLE) { + tg3_readphy(tp, MII_BMCR, &bmcr); + if (!tg3_readphy(tp, MII_BMCR, &bmcr) && + (bmcr & BMCR_ANENABLE)) { tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); r = 0; } @@ -6812,6 +6896,7 @@ static struct ethtool_ops tg3_ethtool_op .get_link = ethtool_op_get_link, .get_eeprom_len = tg3_get_eeprom_len, .get_eeprom = tg3_get_eeprom, + .set_eeprom = tg3_set_eeprom, .get_ringparam = tg3_get_ringparam, .set_ringparam = tg3_set_ringparam, .get_pauseparam = tg3_get_pauseparam, @@ -6831,6 +6916,103 @@ static struct ethtool_ops tg3_ethtool_op .get_ethtool_stats = tg3_get_ethtool_stats, }; +static void __devinit tg3_get_eeprom_size(struct tg3 *tp) +{ + u32 cursize, val; + + tp->nvram_size = EEPROM_CHIP_SIZE; + + if (tg3_nvram_read(tp, 0, &val) != 0) + return; + + if (swab32(val) != TG3_EEPROM_MAGIC) + return; + + /* + * Size the chip by reading offsets at increasing powers of two. + * When we encounter our validation signature, we know the addressing + * has wrapped around, and thus have our chip size. + */ + cursize = 0x800; + + while (cursize < tp->nvram_size) { + if (tg3_nvram_read(tp, cursize, &val) != 0) + return; + + if (swab32(val) == TG3_EEPROM_MAGIC) + break; + + cursize <<= 1; + } + + tp->nvram_size = cursize; +} + +static void __devinit tg3_get_nvram_size(struct tg3 *tp) +{ + u32 val; + + if (tg3_nvram_read(tp, 0xf0, &val) == 0) { + if (val != 0) { + tp->nvram_size = (val >> 16) * 1024; + return; + } + } + tp->nvram_size = 0x20000; +} + +static void __devinit tg3_get_nvram_info(struct tg3 *tp) +{ + u32 nvcfg1; + + nvcfg1 = tr32(NVRAM_CFG1); + if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) { + tp->tg3_flags2 |= TG3_FLG2_FLASH; + } + else { + nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; + tw32(NVRAM_CFG1, nvcfg1); + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { + case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + break; + case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE; + break; + case FLASH_VENDOR_ATMEL_EEPROM: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + break; + case FLASH_VENDOR_ST: + tp->nvram_jedecnum = JEDEC_ST; + tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + break; + case FLASH_VENDOR_SAIFUN: + tp->nvram_jedecnum = JEDEC_SAIFUN; + tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE; + break; + case FLASH_VENDOR_SST_SMALL: + case FLASH_VENDOR_SST_LARGE: + tp->nvram_jedecnum = JEDEC_SST; + tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE; + break; + } + } + else { + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + } +} + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { @@ -6855,32 +7037,27 @@ static void __devinit tg3_nvram_init(str if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { - u32 nvcfg1; + tp->tg3_flags |= TG3_FLAG_NVRAM; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { u32 nvaccess = tr32(NVRAM_ACCESS); - tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); + tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); } - nvcfg1 = tr32(NVRAM_CFG1); - - tp->tg3_flags |= TG3_FLAG_NVRAM; - if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) { - if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE) - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - } else { - nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; - tw32(NVRAM_CFG1, nvcfg1); - } + tg3_get_nvram_info(tp); + tg3_get_nvram_size(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { u32 nvaccess = tr32(NVRAM_ACCESS); - tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); + tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); } + } else { tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED); + + tg3_get_eeprom_size(tp); } } @@ -6918,11 +7095,30 @@ static int tg3_nvram_read_using_eeprom(s return 0; } -static int __devinit tg3_nvram_read(struct tg3 *tp, - u32 offset, u32 *val) +#define NVRAM_CMD_TIMEOUT 10000 + +static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd) { int i; + tw32(NVRAM_CMD, nvram_cmd); + for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) { + udelay(10); + if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) { + udelay(10); + break; + } + } + if (i == NVRAM_CMD_TIMEOUT) { + return -EBUSY; + } + return 0; +} + +static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) +{ + int ret; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); return -EINVAL; @@ -6931,10 +7127,14 @@ static int __devinit tg3_nvram_read(stru if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); - if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) - offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) << - NVRAM_BUFFERED_PAGE_POS) + - (offset % NVRAM_BUFFERED_PAGE_SIZE); + if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) && + (tp->tg3_flags2 & TG3_FLG2_FLASH) && + (tp->nvram_jedecnum == JEDEC_ATMEL)) { + + offset = ((offset / tp->nvram_pagesize) << + ATMEL_AT45DB0X1B_PAGE_POS) + + (offset % tp->nvram_pagesize); + } if (offset > NVRAM_ADDR_MSK) return -EINVAL; @@ -6948,19 +7148,11 @@ static int __devinit tg3_nvram_read(stru } tw32(NVRAM_ADDR, offset); - tw32(NVRAM_CMD, - NVRAM_CMD_RD | NVRAM_CMD_GO | - NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); + ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO | + NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE); - /* Wait for done bit to clear. */ - for (i = 0; i < 1000; i++) { - udelay(10); - if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) { - udelay(10); - *val = swab32(tr32(NVRAM_RDDATA)); - break; - } - } + if (ret == 0) + *val = swab32(tr32(NVRAM_RDDATA)); tg3_nvram_unlock(tp); @@ -6970,10 +7162,268 @@ static int __devinit tg3_nvram_read(stru tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); } - if (i >= 1000) - return -EBUSY; + return ret; +} - return 0; +static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, + u32 offset, u32 len, u8 *buf) +{ + int i, j, rc = 0; + u32 val; + + for (i = 0; i < len; i += 4) { + u32 addr, data; + + addr = offset + i; + + memcpy(&data, buf + i, 4); + + tw32(GRC_EEPROM_DATA, cpu_to_le32(data)); + + val = tr32(GRC_EEPROM_ADDR); + tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); + + val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK | + EEPROM_ADDR_READ); + tw32(GRC_EEPROM_ADDR, val | + (0 << EEPROM_ADDR_DEVID_SHIFT) | + (addr & EEPROM_ADDR_ADDR_MASK) | + EEPROM_ADDR_START | + EEPROM_ADDR_WRITE); + + for (j = 0; j < 10000; j++) { + val = tr32(GRC_EEPROM_ADDR); + + if (val & EEPROM_ADDR_COMPLETE) + break; + udelay(100); + } + if (!(val & EEPROM_ADDR_COMPLETE)) { + rc = -EBUSY; + break; + } + } + + return rc; +} + +/* offset and length are dword aligned */ +static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, + u8 *buf) +{ + int ret = 0; + u32 pagesize = tp->nvram_pagesize; + u32 pagemask = pagesize - 1; + u32 nvram_cmd; + u8 *tmp; + + tmp = kmalloc(pagesize, GFP_KERNEL); + if (tmp == NULL) + return -ENOMEM; + + while (len) { + int j; + u32 phy_addr, page_off, size, nvaccess; + + phy_addr = offset & ~pagemask; + + for (j = 0; j < pagesize; j += 4) { + if ((ret = tg3_nvram_read(tp, phy_addr + j, + (u32 *) (tmp + j)))) + break; + } + if (ret) + break; + + page_off = offset & pagemask; + size = pagesize; + if (len < size) + size = len; + + len -= size; + + memcpy(tmp + page_off, buf, size); + + offset = offset + (pagesize - page_off); + + nvaccess = tr32(NVRAM_ACCESS); + tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); + + /* + * Before we can erase the flash page, we need + * to issue a special "write enable" command. + */ + nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; + + if (tg3_nvram_exec_cmd(tp, nvram_cmd)) + break; + + /* Erase the target page */ + tw32(NVRAM_ADDR, phy_addr); + + nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR | + NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE; + + if (tg3_nvram_exec_cmd(tp, nvram_cmd)) + break; + + /* Issue another write enable to start the write. */ + nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE; + + if (tg3_nvram_exec_cmd(tp, nvram_cmd)) + break; + + for (j = 0; j < pagesize; j += 4) { + u32 data; + + data = *((u32 *) (tmp + j)); + tw32(NVRAM_WRDATA, cpu_to_be32(data)); + + tw32(NVRAM_ADDR, phy_addr + j); + + nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | + NVRAM_CMD_WR; + + if (j == 0) + nvram_cmd |= NVRAM_CMD_FIRST; + else if (j == (pagesize - 4)) + nvram_cmd |= NVRAM_CMD_LAST; + + if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd))) + break; + } + if (ret) + break; + } + + nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE; + tg3_nvram_exec_cmd(tp, nvram_cmd); + + kfree(tmp); + + return ret; +} + +/* offset and length are dword aligned */ +static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, + u8 *buf) +{ + int i, ret = 0; + + for (i = 0; i < len; i += 4, offset += 4) { + u32 data, page_off, phy_addr, nvram_cmd; + + memcpy(&data, buf + i, 4); + tw32(NVRAM_WRDATA, cpu_to_be32(data)); + + page_off = offset % tp->nvram_pagesize; + + if ((tp->tg3_flags2 & TG3_FLG2_FLASH) && + (tp->nvram_jedecnum == JEDEC_ATMEL)) { + + phy_addr = ((offset / tp->nvram_pagesize) << + ATMEL_AT45DB0X1B_PAGE_POS) + page_off; + } + else { + phy_addr = offset; + } + + tw32(NVRAM_ADDR, phy_addr); + + nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR; + + if ((page_off == 0) || (i == 0)) + nvram_cmd |= NVRAM_CMD_FIRST; + else if (page_off == (tp->nvram_pagesize - 4)) + nvram_cmd |= NVRAM_CMD_LAST; + + if (i == (len - 4)) + nvram_cmd |= NVRAM_CMD_LAST; + + if ((tp->nvram_jedecnum == JEDEC_ST) && + (nvram_cmd & NVRAM_CMD_FIRST)) { + + if ((ret = tg3_nvram_exec_cmd(tp, + NVRAM_CMD_WREN | NVRAM_CMD_GO | + NVRAM_CMD_DONE))) + + break; + } + if (!(tp->tg3_flags2 & TG3_FLG2_FLASH)) { + /* We always do complete word writes to eeprom. */ + nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST); + } + + if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd))) + break; + } + return ret; +} + +/* offset and length are dword aligned */ +static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) +{ + int ret; + + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n"); + return -EINVAL; + } + + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + GRC_LCLCTRL_GPIO_OE1); + udelay(40); + } + + if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) { + ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf); + } + else { + u32 grc_mode; + + tg3_nvram_lock(tp); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + u32 nvaccess = tr32(NVRAM_ACCESS); + + tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE); + + tw32(NVRAM_WRITE1, 0x406); + } + + grc_mode = tr32(GRC_MODE); + tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE); + + if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) || + !(tp->tg3_flags2 & TG3_FLG2_FLASH)) { + + ret = tg3_nvram_write_block_buffered(tp, offset, len, + buf); + } + else { + ret = tg3_nvram_write_block_unbuffered(tp, offset, len, + buf); + } + + grc_mode = tr32(GRC_MODE); + tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + u32 nvaccess = tr32(NVRAM_ACCESS); + + tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE); + } + tg3_nvram_unlock(tp); + } + + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { + tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | + GRC_LCLCTRL_GPIO_OE1 | GRC_LCLCTRL_GPIO_OUTPUT1); + udelay(40); + } + + return ret; } struct subsys_tbl_ent { @@ -7047,11 +7497,19 @@ static int __devinit tg3_phy_probe(struc tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { u32 nic_cfg, led_cfg; - u32 nic_phy_id, cfg2; + u32 nic_phy_id, ver, cfg2 = 0; tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); tp->nic_sram_data_cfg = nic_cfg; + tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver); + ver >>= NIC_SRAM_DATA_VER_SHIFT; + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703) && + (ver > 0) && (ver < 0x100)) + tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2); + eeprom_signature_found = 1; if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == @@ -7070,8 +7528,7 @@ static int __devinit tg3_phy_probe(struc eeprom_phy_id = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { - tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &led_cfg); - led_cfg &= (NIC_SRAM_DATA_CFG_LED_MODE_MASK | + led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK | SHASTA_EXT_LED_MODE_MASK); } else led_cfg = nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK; @@ -7116,9 +7573,8 @@ static int __devinit tg3_phy_probe(struc tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) tp->led_ctrl = LED_CTRL_MODE_PHY_2; - if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) && + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; @@ -7130,9 +7586,13 @@ static int __devinit tg3_phy_probe(struc if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL) tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; - tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &cfg2); if (cfg2 & (1 << 17)) tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; + + /* serdes signal pre-emphasis in register 0x590 set by */ + /* bootcode if bit 18 is set */ + if (cfg2 & (1 << 18)) + tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; } /* Reading the PHY ID register can conflict with ASF @@ -7188,9 +7648,8 @@ static int __devinit tg3_phy_probe(struc u32 bmsr, adv_reg, tg3_ctrl; tg3_readphy(tp, MII_BMSR, &bmsr); - tg3_readphy(tp, MII_BMSR, &bmsr); - - if (bmsr & BMSR_LSTATUS) + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + (bmsr & BMSR_LSTATUS)) goto skip_phy_reset; err = tg3_phy_reset(tp); @@ -7414,6 +7873,9 @@ static int __devinit tg3_get_invariants( tp->pci_hdr_type = (cacheline_sz_reg >> 16) & 0xff; tp->pci_bist = (cacheline_sz_reg >> 24) & 0xff; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) + tp->tg3_flags2 |= TG3_FLG2_HW_TSO; + if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; @@ -8302,11 +8764,13 @@ static int __devinit tg3_init_one(struct } #if TG3_TSO_SUPPORT != 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + } + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || - ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750)) { + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tg3.h linux-2.4.30-rc1/drivers/net/tg3.h --- linux-2.4.29/drivers/net/tg3.h 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tg3.h 2005-03-18 18:07:43.313218800 +0000 @@ -1274,6 +1274,7 @@ #define GRC_MODE_HOST_STACKUP 0x00010000 #define GRC_MODE_HOST_SENDBDS 0x00020000 #define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000 +#define GRC_MODE_NVRAM_WR_ENABLE 0x00200000 #define GRC_MODE_NO_RX_PHDR_CSUM 0x00800000 #define GRC_MODE_IRQ_ON_TX_CPU_ATTN 0x01000000 #define GRC_MODE_IRQ_ON_RX_CPU_ATTN 0x02000000 @@ -1366,6 +1367,8 @@ #define NVRAM_CMD_ERASE 0x00000040 #define NVRAM_CMD_FIRST 0x00000080 #define NVRAM_CMD_LAST 0x00000100 +#define NVRAM_CMD_WREN 0x00010000 +#define NVRAM_CMD_WRDI 0x00020000 #define NVRAM_STAT 0x00007004 #define NVRAM_WRDATA 0x00007008 #define NVRAM_ADDR 0x0000700c @@ -1375,8 +1378,18 @@ #define NVRAM_CFG1_FLASHIF_ENAB 0x00000001 #define NVRAM_CFG1_BUFFERED_MODE 0x00000002 #define NVRAM_CFG1_PASS_THRU 0x00000004 +#define NVRAM_CFG1_STATUS_BITS 0x00000070 #define NVRAM_CFG1_BIT_BANG 0x00000008 +#define NVRAM_CFG1_FLASH_SIZE 0x02000000 #define NVRAM_CFG1_COMPAT_BYPASS 0x80000000 +#define NVRAM_CFG1_VENDOR_MASK 0x03000003 +#define FLASH_VENDOR_ATMEL_EEPROM 0x02000000 +#define FLASH_VENDOR_ATMEL_FLASH_BUFFERED 0x02000003 +#define FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED 0x00000003 +#define FLASH_VENDOR_ST 0x03000001 +#define FLASH_VENDOR_SAIFUN 0x01000003 +#define FLASH_VENDOR_SST_SMALL 0x00000001 +#define FLASH_VENDOR_SST_LARGE 0x02000001 #define NVRAM_CFG2 0x00007018 #define NVRAM_CFG3 0x0000701c #define NVRAM_SWARB 0x00007020 @@ -1396,15 +1409,16 @@ #define SWARB_REQ1 0x00002000 #define SWARB_REQ2 0x00004000 #define SWARB_REQ3 0x00008000 -#define NVRAM_BUFFERED_PAGE_SIZE 264 -#define NVRAM_BUFFERED_PAGE_POS 9 #define NVRAM_ACCESS 0x00007024 #define ACCESS_ENABLE 0x00000001 #define ACCESS_WR_ENABLE 0x00000002 -/* 0x7024 --> 0x7400 unused */ +#define NVRAM_WRITE1 0x00007028 +/* 0x702c --> 0x7400 unused */ /* 0x7400 --> 0x8000 unused */ +#define TG3_EEPROM_MAGIC 0x669955aa + /* 32K Window into NIC internal memory */ #define NIC_SRAM_WIN_BASE 0x00008000 @@ -1438,6 +1452,9 @@ #define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000 #define NIC_SRAM_DATA_CFG_NO_GPIO2 0x00100000 +#define NIC_SRAM_DATA_VER 0x00000b5c +#define NIC_SRAM_DATA_VER_SHIFT 16 + #define NIC_SRAM_DATA_PHY_ID 0x00000b74 #define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000 #define NIC_SRAM_DATA_PHY_ID2_MASK 0x0000ffff @@ -2090,6 +2107,9 @@ struct tg3 { #define TG3_FLG2_PHY_JUST_INITTED 0x00001000 #define TG3_FLG2_PHY_SERDES 0x00002000 #define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 +#define TG3_FLG2_FLASH 0x00008000 +#define TG3_FLG2_HW_TSO 0x00010000 +#define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -2164,6 +2184,34 @@ struct tg3 { struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; struct tq_struct reset_task; + + u32 nvram_size; + u32 nvram_pagesize; + u32 nvram_jedecnum; + +#define JEDEC_ATMEL 0x1f +#define JEDEC_ST 0x20 +#define JEDEC_SAIFUN 0x4f +#define JEDEC_SST 0xbf + +#define ATMEL_AT24C64_CHIP_SIZE (64 * 1024) +#define ATMEL_AT24C64_PAGE_SIZE (32) + +#define ATMEL_AT24C512_CHIP_SIZE (512 * 1024) +#define ATMEL_AT24C512_PAGE_SIZE (128) + +#define ATMEL_AT45DB0X1B_PAGE_POS 9 +#define ATMEL_AT45DB0X1B_PAGE_SIZE 264 + +#define ATMEL_AT25F512_PAGE_SIZE 256 + +#define ST_M45PEX0_PAGE_SIZE 256 + +#define SAIFUN_SA25F0XX_PAGE_SIZE 256 + +#define SST_25VF0X0_PAGE_SIZE 4098 + + }; #endif /* !(_T3_H) */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/21142.c linux-2.4.30-rc1/drivers/net/tulip/21142.c --- linux-2.4.29/drivers/net/tulip/21142.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/21142.c 2005-03-18 18:06:42.231504632 +0000 @@ -14,8 +14,8 @@ */ -#include "tulip.h" #include +#include "tulip.h" #include diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/eeprom.c linux-2.4.30-rc1/drivers/net/tulip/eeprom.c --- linux-2.4.29/drivers/net/tulip/eeprom.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/eeprom.c 2005-03-18 18:08:20.356587352 +0000 @@ -14,6 +14,7 @@ */ +#include #include "tulip.h" #include #include diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/interrupt.c linux-2.4.30-rc1/drivers/net/tulip/interrupt.c --- linux-2.4.29/drivers/net/tulip/interrupt.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/interrupt.c 2005-03-18 18:06:46.467860608 +0000 @@ -14,10 +14,10 @@ */ +#include #include "tulip.h" #include #include -#include int tulip_rx_copybreak; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/media.c linux-2.4.30-rc1/drivers/net/tulip/media.c --- linux-2.4.29/drivers/net/tulip/media.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/media.c 2005-03-18 18:06:47.274737944 +0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include "tulip.h" diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/pnic.c linux-2.4.30-rc1/drivers/net/tulip/pnic.c --- linux-2.4.29/drivers/net/tulip/pnic.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/pnic.c 2005-03-18 18:07:52.869765984 +0000 @@ -15,6 +15,7 @@ */ #include +#include #include "tulip.h" diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/pnic2.c linux-2.4.30-rc1/drivers/net/tulip/pnic2.c --- linux-2.4.29/drivers/net/tulip/pnic2.c 2003-06-13 14:51:35.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/pnic2.c 2005-03-18 18:06:29.494440960 +0000 @@ -76,8 +76,8 @@ -#include "tulip.h" #include +#include "tulip.h" #include diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/timer.c linux-2.4.30-rc1/drivers/net/tulip/timer.c --- linux-2.4.29/drivers/net/tulip/timer.c 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/timer.c 2005-03-18 18:06:08.935566384 +0000 @@ -14,6 +14,7 @@ */ +#include #include "tulip.h" diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/tulip.h linux-2.4.30-rc1/drivers/net/tulip/tulip.h --- linux-2.4.29/drivers/net/tulip/tulip.h 2002-11-28 23:53:14.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/tulip.h 2005-03-18 18:08:20.008640248 +0000 @@ -146,6 +146,9 @@ enum status_bits { TxIntr = 0x01, }; +/* bit mask for CSR5 TX/RX process state */ +#define CSR5_TS 0x00700000 +#define CSR5_RS 0x000e0000 enum tulip_mode_bits { TxThreshold = (1 << 22), @@ -484,9 +487,19 @@ static inline void tulip_stop_rxtx(struc u32 csr6 = inl(ioaddr + CSR6); if (csr6 & RxTx) { + unsigned i=1300/10; outl(csr6 & ~RxTx, ioaddr + CSR6); barrier(); - (void) inl(ioaddr + CSR6); /* mmio sync */ + /* wait until in-flight frame completes. + * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin) + * Typically expect this loop to end in < 50us on 100BT. + */ + while (--i && (inl(ioaddr + CSR5) & (CSR5_TS|CSR5_RS))) + udelay(10); + + if (!i) + printk (KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", + tp->pdev->slot_name); } } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/net/tulip/tulip_core.c linux-2.4.30-rc1/drivers/net/tulip/tulip_core.c --- linux-2.4.29/drivers/net/tulip/tulip_core.c 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/drivers/net/tulip/tulip_core.c 2005-03-18 18:07:40.052714472 +0000 @@ -20,8 +20,8 @@ #include #include -#include "tulip.h" #include +#include "tulip.h" #include #include #include diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/pci/quirks.c linux-2.4.30-rc1/drivers/pci/quirks.c --- linux-2.4.29/drivers/pci/quirks.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/pci/quirks.c 2005-03-18 18:06:19.498960504 +0000 @@ -368,9 +368,6 @@ static void __init quirk_via_ioapic(stru * non-x86 architectures (yes Via exists on PPC among other places), * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get * interrupts delivered properly. - * - * TODO: When we have device-specific interrupt routers, - * quirk_via_irqpic will go away from quirks. */ /* @@ -393,22 +390,6 @@ static void __init quirk_via_acpi(struct d->irq = irq; } -static void __init quirk_via_irqpic(struct pci_dev *dev) -{ - u8 irq, new_irq = dev->irq & 0xf; - - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); - - if (new_irq != irq) { - printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n", - dev->slot_name, irq, new_irq); - - udelay(15); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); - } -} - - /* * PIIX3 USB: We have to disable USB interrupts that are * hardwired to PIRQD# and may be shared with an @@ -639,12 +620,14 @@ static void __init quirk_disable_pxb(str * VIA northbridges care about PCI_INTERRUPT_LINE */ -int interrupt_line_quirk; +int via_interrupt_line_quirk; static void __init quirk_via_bridge(struct pci_dev *pdev) { - if(pdev->devfn == 0) - interrupt_line_quirk = 1; + if(pdev->devfn == 0) { + printk(KERN_INFO "PCI: Via IRQ fixup\n"); + via_interrupt_line_quirk = 1; + } } /* @@ -773,9 +756,6 @@ static struct pci_fixup pci_fixups[] __i #endif { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irqpic }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering }, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/pcmcia/cistpl.c linux-2.4.30-rc1/drivers/pcmcia/cistpl.c --- linux-2.4.29/drivers/pcmcia/cistpl.c 2004-02-18 13:36:31.000000000 +0000 +++ linux-2.4.30-rc1/drivers/pcmcia/cistpl.c 2005-03-18 18:07:01.201620736 +0000 @@ -140,7 +140,6 @@ int read_cis_mem(socket_info_t *s, int a } else { u_int inc = 1; if (attr) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; } - sys += (addr & (s->cap.map_size-1)); mem->card_start = addr & ~(s->cap.map_size-1); while (len) { set_cis_map(s, mem); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/sbus/audio/audio.c linux-2.4.30-rc1/drivers/sbus/audio/audio.c --- linux-2.4.29/drivers/sbus/audio/audio.c 2001-10-11 06:42:46.000000000 +0000 +++ linux-2.4.30-rc1/drivers/sbus/audio/audio.c 2005-03-18 18:06:09.931414992 +0000 @@ -65,6 +65,14 @@ #define tprintk(x) #endif +static int audio_input_buffers = 8; +MODULE_PARM(audio_input_buffers, "i"); +MODULE_PARM_DESC(audio_input_buffers,"Number of input 8KB buffers."); + +static int audio_output_buffers = 8; +MODULE_PARM(audio_output_buffers, "i"); +MODULE_PARM_DESC(audio_output_buffers,"Number of output 8KB buffer."); + static short lis_get_elist_ent( strevent_t *list, pid_t pid ); static int lis_add_to_elist( strevent_t **list, pid_t pid, short events ); static int lis_del_from_elist( strevent_t **list, pid_t pid, short events ); @@ -438,7 +446,7 @@ static int sparcaudio_mixer_ioctl(struct m = drv->ops->get_input_balance(drv); i = OSS_TO_GAIN(k); j = OSS_TO_BAL(k); - oprintk((" for stereo to do %d (bal %d):", i, j)); + oprintk((" for stereo to do %ld (bal %ld):", i, j)); if (drv->ops->set_input_volume) drv->ops->set_input_volume(drv, i); if (drv->ops->set_input_balance) @@ -488,7 +496,7 @@ static int sparcaudio_mixer_ioctl(struct oprintk((" started as (0x%x)\n", BAL_TO_OSS(l,m))); i = OSS_TO_GAIN(k); j = OSS_TO_BAL(k); - oprintk((" for stereo to %d (bal %d)\n", i, j)); + oprintk((" for stereo to %ld (bal %ld)\n", i, j)); if (drv->ops->set_output_volume) drv->ops->set_output_volume(drv, i); if (drv->ops->set_output_balance) @@ -565,7 +573,7 @@ static int sparcaudio_mixer_ioctl(struct if (k & SOUND_MASK_CD) j = AUDIO_CD; if (k & SOUND_MASK_LINE) j = AUDIO_LINE_IN; if (k & SOUND_MASK_MIC) j = AUDIO_MICROPHONE; - oprintk(("setting inport to %d\n", j)); + oprintk(("setting inport to %ld\n", j)); i = drv->ops->set_input_port(drv, j); return put_user(i, (int *)arg); @@ -798,7 +806,7 @@ static int sparcaudio_ioctl(struct inode retval = -EINVAL; break; } - get_user(i, (int *)arg) + get_user(i, (int *)arg); tprintk(("setting speed to %d\n", i)); drv->ops->set_input_rate(drv, i); drv->ops->set_output_rate(drv, i); @@ -1955,8 +1963,6 @@ int register_sparcaudio_driver(struct sp * Input buffers, on the other hand, always fill completely, * so we don't need input counts - each contains input_buffer_size * bytes of audio data. - * - * TODO: Make number of input/output buffers tunable parameters */ init_waitqueue_head(&drv->open_wait); @@ -1964,7 +1970,7 @@ int register_sparcaudio_driver(struct sp init_waitqueue_head(&drv->output_drain_wait); init_waitqueue_head(&drv->input_read_wait); - drv->num_output_buffers = 8; + drv->num_output_buffers = audio_output_buffers; drv->output_buffer_size = (4096 * 2); drv->playing_count = 0; drv->output_offset = 0; @@ -1997,7 +2003,7 @@ int register_sparcaudio_driver(struct sp } /* Setup the circular queue of input buffers. */ - drv->num_input_buffers = 8; + drv->num_input_buffers = audio_input_buffers; drv->input_buffer_size = (4096 * 2); drv->recording_count = 0; drv->input_front = 0; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/sbus/audio/dbri.c linux-2.4.30-rc1/drivers/sbus/audio/dbri.c --- linux-2.4.29/drivers/sbus/audio/dbri.c 2002-11-28 23:53:14.000000000 +0000 +++ linux-2.4.30-rc1/drivers/sbus/audio/dbri.c 2005-03-18 18:07:53.588656696 +0000 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -161,7 +162,7 @@ static volatile s32 *dbri_cmdlock(struct static void dbri_process_interrupt_buffer(struct dbri *); -static void dbri_cmdsend(struct dbri *dbri, volatile s32 *cmd) +static void dbri_cmdsend(struct dbri *dbri, volatile s32 *cmd, int pause) { int MAXLOOPS = 1000000; int maxloops = MAXLOOPS; @@ -181,25 +182,30 @@ static void dbri_cmdsend(struct dbri *db } else if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS-1) { printk("DBRI: Command buffer overflow! (bug in driver)\n"); } else { - *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); + if (pause) + *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); dbri->wait_seen = 0; sbus_writel(dbri->dma_dvma, dbri->regs + REG8); - while ((--maxloops) > 0 && - (sbus_readl(dbri->regs + REG0) & D_P)) - barrier(); - if (maxloops == 0) { - printk("DBRI: Chip never completed command buffer\n"); - } else { - while ((--maxloops) > 0 && (! dbri->wait_seen)) - dbri_process_interrupt_buffer(dbri); + if (pause) { + while ((--maxloops) > 0 && + (sbus_readl(dbri->regs + REG0) & D_P)) + barrier(); if (maxloops == 0) { - printk("DBRI: Chip never acked WAIT\n"); + printk("DBRI: Chip never completed command buffer\n"); } else { - dprintk(D_INT, ("DBRI: Chip completed command " - "buffer (%d)\n", - MAXLOOPS - maxloops)); + while ((--maxloops) > 0 && (! dbri->wait_seen)) + dbri_process_interrupt_buffer(dbri); + if (maxloops == 0) { + printk("DBRI: Chip never acked WAIT\n"); + } else { + dprintk(D_INT, ("DBRI: Chip completed command " + "buffer (%d)\n", + MAXLOOPS - maxloops)); + } } + } else { + dprintk(D_INT, ("DBRI: NO PAUSE\n")); } } @@ -257,7 +263,10 @@ static void dbri_initialize(struct dbri /* We should query the openprom to see what burst sizes this * SBus supports. For now, just disable all SBus bursts */ tmp = sbus_readl(dbri->regs + REG0); - tmp &= ~(D_G | D_S | D_E); + /* A brute approach - DBRI falls back to working burst size by itself + * On SS20 D_S does not work, so do not try so high. */ + tmp |= D_G | D_E; + tmp &= ~D_S; sbus_writel(tmp, dbri->regs + REG0); /* @@ -268,7 +277,7 @@ static void dbri_initialize(struct dbri *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); *(cmd++) = dma_addr; - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } @@ -455,7 +464,7 @@ static void dbri_process_one_interrupt(s dbri->pipes[pipe].sdp | D_SDP_P | D_SDP_C | D_SDP_2SAME); *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } if (code == D_INTR_FXDT) { @@ -579,7 +588,7 @@ static void reset_pipe(struct dbri *dbri cmd = dbri_cmdlock(dbri); *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); *(cmd++) = 0; - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); desc = dbri->pipes[pipe].desc; while (desc != -1) { @@ -722,7 +731,7 @@ static void link_time_slot(struct dbri * *(cmd++) = D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); } - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } /* I don't use this function, so it's basically untested. */ @@ -752,7 +761,7 @@ static void unlink_time_slot(struct dbri *(cmd++) = D_TS_NEXT(nextpipe); } - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } /* xmit_fixed() / recv_fixed() @@ -803,7 +812,7 @@ static void xmit_fixed(struct dbri *dbri *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); *(cmd++) = data; - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } static void recv_fixed(struct dbri *dbri, int pipe, volatile __u32 *ptr) @@ -884,7 +893,9 @@ static void xmit_on_pipe(struct dbri *db } if (len > ((1 << 13) - 1)) { - mylen = (1 << 13) - 1; + /* One should not leave a buffer shorter than */ + /* a single sample. Otherwise bad things happens.*/ + mylen = (1 << 13) - 4; } else { mylen = len; } @@ -954,7 +965,7 @@ static void xmit_on_pipe(struct dbri *db cmd = dbri_cmdlock(dbri); *(cmd++) = DBRI_CMD(D_CDP, 0, pipe); - dbri_cmdsend(dbri,cmd); + dbri_cmdsend(dbri,cmd, 0); } else { /* Pipe isn't active - issue an SDP command to start * our chain of TDs running. @@ -965,7 +976,7 @@ static void xmit_on_pipe(struct dbri *db dbri->pipes[pipe].sdp | D_SDP_P | D_SDP_EVERY | D_SDP_C); *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 0); } restore_flags(flags); @@ -1083,7 +1094,7 @@ static void recv_on_pipe(struct dbri *db *(cmd++) = DBRI_CMD(D_SDP, 0, dbri->pipes[pipe].sdp | D_SDP_P | D_SDP_C); *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_rd); - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } @@ -1191,7 +1202,7 @@ static void reset_chi(struct dbri *dbri, *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE|D_CDM_XEN|D_CDM_REN); - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); } /* @@ -1538,7 +1549,6 @@ static void dbri_start_output(struct spa xmit_on_pipe(dbri, 4, buffer, count, &dbri_audio_output_callback, drv); -#if 0 /* Notify midlevel that we're a DMA-capable driver that * can accept another buffer immediately. We should probably * check that we've got enough resources (i.e, descriptors) @@ -1551,9 +1561,14 @@ static void dbri_start_output(struct spa * DBRI with a chain of buffers, but the midlevel code is * so tricky that I really don't want to deal with it. */ + /* + * This must be enabled otherwise the output is noisy + * as return to user space is done when all buffers + * are already played, so user space player has no time + * to prepare next ones without a period of silence. - Krzysztof Helt + */ sparcaudio_output_done(drv, 2); -#endif } static void dbri_stop_output(struct sparcaudio_driver *drv) @@ -1842,6 +1857,12 @@ static int dbri_get_input_rate(struct sp return dbri_get_output_rate(drv); } +static int dbri_get_formats(struct sparcaudio_driver *drv) +{ +/* 8-bit format is not working */ + return (AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE); +} + /******************* sparcaudio midlevel - ports ***********************/ static int dbri_set_output_port(struct sparcaudio_driver *drv, int port) @@ -1983,6 +2004,19 @@ static struct sparcaudio_operations dbri dbri_get_input_ports, dbri_set_output_muted, dbri_get_output_muted, + NULL, /* dbri_set_output_pause, */ + NULL, /* dbri_get_output_pause, */ + NULL, /* dbri_set_input_pause, */ + NULL, /* dbri_get_input_pause, */ + NULL, /* dbri_set_output_samples, */ + NULL, /* dbri_get_output_samples, */ + NULL, /* dbri_set_input_samples, */ + NULL, /* dbri_get_input_samples, */ + NULL, /* dbri_set_output_error, */ + NULL, /* dbri_get_output_error, */ + NULL, /* dbri_set_input_error, */ + NULL, /* dbri_get_input_error, */ + dbri_get_formats }; @@ -2093,7 +2127,7 @@ void dbri_liu_activate(int dev, int prio #endif *(cmd++) = DBRI_CMD(D_TE, 0, val); - dbri_cmdsend(dbri, cmd); + dbri_cmdsend(dbri, cmd, 1); /* Activate the interface */ tmp = sbus_readl(dbri->regs + REG0); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/sbus/char/zs.c linux-2.4.30-rc1/drivers/sbus/char/zs.c --- linux-2.4.29/drivers/sbus/char/zs.c 2005-01-19 14:09:59.000000000 +0000 +++ linux-2.4.30-rc1/drivers/sbus/char/zs.c 2005-03-18 18:08:34.299467712 +0000 @@ -65,19 +65,19 @@ static int num_serial = 2; /* sun4/sun4c /* On 32-bit sparcs we need to delay after register accesses * to accomodate sun4 systems, but we do not need to flush writes. - * On 64-bit sparc we only need to flush single writes to ensure + * On 64-bit and sun4d we need to flush single writes to ensure * completion. */ #ifndef __sparc_v9__ #define ZSDELAY() udelay(5) #define ZSDELAY_LONG() udelay(20) -#define ZS_WSYNC(channel) do { } while(0) #else #define ZSDELAY() #define ZSDELAY_LONG() +#endif + #define ZS_WSYNC(__channel) \ sbus_readb(&((__channel)->control)) -#endif struct sun_zslayout **zs_chips; struct sun_zschannel **zs_channels; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/sbus/sbus.c linux-2.4.30-rc1/drivers/sbus/sbus.c --- linux-2.4.29/drivers/sbus/sbus.c 2003-08-25 11:44:42.000000000 +0000 +++ linux-2.4.30-rc1/drivers/sbus/sbus.c 2005-03-18 18:07:13.642729400 +0000 @@ -215,6 +215,8 @@ static void __init sbus_do_child_sibling * prom_sbus_ranges_init(), with all sun4d stuff cut away. * Ask DaveM what is going on here, how is sun4d supposed to work... XXX */ +/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ + static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus) { int len; @@ -227,6 +229,20 @@ static void __init sbus_bus_ranges_init( return; } sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges); +#ifdef CONFIG_SPARC32 + if (sparc_cpu_model == sun4d) { + struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; + int num_iounit_ranges; + + len = prom_getproperty(parent_node, "ranges", + (char *) iounit_ranges, + sizeof (iounit_ranges)); + if (len != -1) { + num_iounit_ranges = (len/sizeof(struct linux_prom_ranges)); + prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges); + } + } +#endif } static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/Config.in linux-2.4.30-rc1/drivers/scsi/Config.in --- linux-2.4.29/drivers/scsi/Config.in 2005-01-19 14:09:59.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/Config.in 2005-03-18 18:07:17.406157272 +0000 @@ -73,6 +73,7 @@ dep_tristate ' AHCI SATA support (EXPER dep_tristate ' ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SVW $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate ' Intel PIIX/ICH SATA support' CONFIG_SCSI_ATA_PIIX $CONFIG_SCSI_SATA $CONFIG_PCI dep_tristate ' NVIDIA SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_NV $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL +dep_tristate ' Pacific Digital SATA QStor support' CONFIG_SCSI_SATA_QSTOR $CONFIG_SCSI_SATA $CONFIG_PCI dep_tristate ' Promise SATA TX2/TX4 support (EXPERIMENTAL)' CONFIG_SCSI_SATA_PROMISE $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate ' Promise SATA SX4 support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SX4 $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL dep_tristate ' Silicon Image SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SIL $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/Makefile linux-2.4.30-rc1/drivers/scsi/Makefile --- linux-2.4.29/drivers/scsi/Makefile 2005-01-19 14:09:59.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/Makefile 2005-03-18 18:08:08.340414088 +0000 @@ -134,6 +134,7 @@ obj-$(CONFIG_SCSI_SATA_AHCI) += libata.o obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o +obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/ahci.c linux-2.4.30-rc1/drivers/scsi/ahci.c --- linux-2.4.29/drivers/scsi/ahci.c 2005-01-19 14:10:01.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/ahci.c 2005-03-18 18:08:27.693471976 +0000 @@ -40,8 +40,6 @@ #define DRV_NAME "ahci" #define DRV_VERSION "1.00" -#define msleep libata_msleep /* 2.4-specific */ - enum { AHCI_PCI_BAR = 5, AHCI_MAX_SG = 168, /* hardware max is 64K */ @@ -180,6 +178,7 @@ static void ahci_port_stop(struct ata_po static void ahci_host_stop(struct ata_host_set *host_set); static void ahci_qc_prep(struct ata_queued_cmd *qc); 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 Scsi_Host_Template ahci_sht = { @@ -206,6 +205,8 @@ static struct ata_port_operations ahci_o .port_disable = ata_port_disable, .check_status = ahci_check_status, + .check_altstatus = ahci_check_status, + .check_err = ahci_check_err, .dev_select = ata_noop_dev_select, .phy_reset = ahci_phy_reset, @@ -248,6 +249,12 @@ static struct pci_device_id ahci_pci_tbl board_ahci }, /* ICH7 */ { PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ICH7M */ + { PCI_VENDOR_ID_INTEL, 0x27c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ICH7R */ + { PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ICH7R */ + { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_ahci }, /* ULi M5288 */ { } /* terminate list */ }; @@ -448,6 +455,13 @@ static u8 ahci_check_status(struct ata_p return readl(mmio + PORT_TFDATA) & 0xFF; } +static u8 ahci_check_err(struct ata_port *ap) +{ + void *mmio = (void *) ap->ioaddr.cmd_addr; + + return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF; +} + static void ahci_fill_sg(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; @@ -515,15 +529,6 @@ static void ahci_qc_prep(struct ata_queu ahci_fill_sg(qc); } -static inline void ahci_dma_complete (struct ata_port *ap, - struct ata_queued_cmd *qc, - int have_err) -{ - /* get drive status; clear intr; complete txn */ - ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag), - have_err ? ATA_ERR : 0); -} - static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) { void *mmio = ap->host_set->mmio_base; @@ -569,7 +574,7 @@ static void ahci_intr_error(struct ata_p writel(tmp, port_mmio + PORT_CMD); readl(port_mmio + PORT_CMD); /* flush */ - printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->port_no); + printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id); } static void ahci_eng_timeout(struct ata_port *ap) @@ -761,10 +766,10 @@ static int ahci_host_init(struct ata_pro using_dac = hpriv->cap & HOST_CAP_64; if (using_dac && - !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { hpriv->flags |= HOST_CAP_64; } else { - rc = pci_set_dma_mask(pdev, 0xffffffffULL); + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (rc) { printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n", pci_name(pdev)); @@ -929,6 +934,7 @@ static int ahci_init_one (struct pci_dev unsigned long base; void *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; + int pci_dev_busy = 0; int rc; VPRINTK("ENTER\n"); @@ -941,8 +947,10 @@ static int ahci_init_one (struct pci_dev return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } pci_enable_intx(pdev); @@ -1002,7 +1010,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/aic7xxx/aic79xx_pci.c linux-2.4.30-rc1/drivers/scsi/aic7xxx/aic79xx_pci.c --- linux-2.4.29/drivers/scsi/aic7xxx/aic79xx_pci.c 2003-08-25 11:44:42.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/aic7xxx/aic79xx_pci.c 2005-03-18 18:07:08.736475264 +0000 @@ -451,8 +451,10 @@ ahd_pci_test_register_access(struct ahd_ * or read prefetching could be initiated by the * CPU or host bridge. Our device does not support * either, so look for data corruption and/or flaged - * PCI errors. + * PCI errors. First pause without causing another + * chip reset. */ + hcntrl &= ~CHIPRST; ahd_outb(ahd, HCNTRL, hcntrl|PAUSE); while (ahd_is_paused(ahd) == 0) ; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/aic7xxx/aic7xxx_pci.c linux-2.4.30-rc1/drivers/scsi/aic7xxx/aic7xxx_pci.c --- linux-2.4.29/drivers/scsi/aic7xxx/aic7xxx_pci.c 2003-08-25 11:44:42.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/aic7xxx/aic7xxx_pci.c 2005-03-18 18:06:24.927135296 +0000 @@ -1284,8 +1284,10 @@ ahc_pci_test_register_access(struct ahc_ * or read prefetching could be initiated by the * CPU or host bridge. Our device does not support * either, so look for data corruption and/or flagged - * PCI errors. + * PCI errors. First pause without causing another + * chip reset. */ + hcntrl &= ~CHIPRST; ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); while (ahc_is_paused(ahc) == 0) ; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/ata_piix.c linux-2.4.30-rc1/drivers/scsi/ata_piix.c --- linux-2.4.29/drivers/scsi/ata_piix.c 2005-01-19 14:10:01.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/ata_piix.c 2005-03-18 18:08:27.699471064 +0000 @@ -139,6 +139,8 @@ static struct ata_port_operations piix_p .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -164,6 +166,8 @@ static struct ata_port_operations piix_s .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/libata-core.c linux-2.4.30-rc1/drivers/scsi/libata-core.c --- linux-2.4.29/drivers/scsi/libata-core.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/libata-core.c 2005-03-18 18:07:37.916039296 +0000 @@ -376,7 +376,7 @@ void ata_tf_read(struct ata_port *ap, st } /** - * ata_check_status - Read device status reg & clear interrupt + * ata_check_status_pio - Read device status reg & clear interrupt * @ap: port where the device is * * Reads ATA taskfile status register for currently-selected device @@ -414,6 +414,27 @@ u8 ata_check_status(struct ata_port *ap) return ata_check_status_pio(ap); } +u8 ata_altstatus(struct ata_port *ap) +{ + if (ap->ops->check_altstatus) + return ap->ops->check_altstatus(ap); + + if (ap->flags & ATA_FLAG_MMIO) + return readb((void __iomem *)ap->ioaddr.altstatus_addr); + return inb(ap->ioaddr.altstatus_addr); +} + +u8 ata_chk_err(struct ata_port *ap) +{ + if (ap->ops->check_err) + return ap->ops->check_err(ap); + + if (ap->flags & ATA_FLAG_MMIO) { + return readb((void __iomem *) ap->ioaddr.error_addr); + } + return inb(ap->ioaddr.error_addr); +} + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert @@ -1160,7 +1181,6 @@ err_out_nosup: printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n", ap->id, device); err_out: - ata_irq_on(ap); /* re-enable interrupts */ dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */ DPRINTK("EXIT, err\n"); } @@ -1668,7 +1688,8 @@ void ata_bus_reset(struct ata_port *ap) ata_dev_try_classify(ap, 1); /* re-enable interrupts */ - ata_irq_on(ap); + if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ + ata_irq_on(ap); /* is double-select really necessary? */ if (ap->device[1].class != ATA_DEV_NONE) @@ -1699,6 +1720,69 @@ err_out: DPRINTK("EXIT\n"); } +static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev) +{ + printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n", + ap->id, dev->devno); +} + +static const char * ata_dma_blacklist [] = { + "WDC AC11000H", + "WDC AC22100H", + "WDC AC32500H", + "WDC AC33100H", + "WDC AC31600H", + "WDC AC32100H", + "WDC AC23200L", + "Compaq CRD-8241B", + "CRD-8400B", + "CRD-8480B", + "CRD-8482B", + "CRD-84", + "SanDisk SDP3B", + "SanDisk SDP3B-64", + "SANYO CD-ROM CRD", + "HITACHI CDR-8", + "HITACHI CDR-8335", + "HITACHI CDR-8435", + "Toshiba CD-ROM XM-6202B", + "CD-532E-A", + "E-IDE CD-ROM CR-840", + "CD-ROM Drive/F5A", + "WPI CDD-820", + "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", +}; + +static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev) +{ + unsigned char model_num[40]; + char *s; + unsigned int len; + int i; + + ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, + sizeof(model_num)); + s = &model_num[0]; + len = strnlen(s, sizeof(model_num)); + + /* ATAPI specifies that empty space is blank-filled; remove blanks */ + while ((len > 0) && (s[len - 1] == ' ')) { + len--; + s[len] = 0; + } + + for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) + if (!strncmp(ata_dma_blacklist[i], s, len)) + return 1; + + return 0; +} + static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift) { struct ata_device *master, *slave; @@ -1711,17 +1795,37 @@ static unsigned int ata_get_mode_mask(st if (shift == ATA_SHIFT_UDMA) { mask = ap->udma_mask; - if (ata_dev_present(master)) + if (ata_dev_present(master)) { mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dev_present(slave)) + if (ata_dma_blacklisted(ap, master)) { + mask = 0; + ata_pr_blacklisted(ap, master); + } + } + if (ata_dev_present(slave)) { mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); + if (ata_dma_blacklisted(ap, slave)) { + mask = 0; + ata_pr_blacklisted(ap, slave); + } + } } else if (shift == ATA_SHIFT_MWDMA) { mask = ap->mwdma_mask; - if (ata_dev_present(master)) + if (ata_dev_present(master)) { mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); - if (ata_dev_present(slave)) + if (ata_dma_blacklisted(ap, master)) { + mask = 0; + ata_pr_blacklisted(ap, master); + } + } + if (ata_dev_present(slave)) { mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); + if (ata_dma_blacklisted(ap, slave)) { + mask = 0; + ata_pr_blacklisted(ap, slave); + } + } } else if (shift == ATA_SHIFT_PIO) { mask = ap->pio_mask; @@ -2518,10 +2622,10 @@ static void ata_qc_timeout(struct ata_qu case ATA_PROT_DMA: case ATA_PROT_ATAPI_DMA: - host_stat = ata_bmdma_status(ap); + host_stat = ap->ops->bmdma_status(ap); /* before we do anything else, clear DMA-Start bit */ - ata_bmdma_stop(ap); + ap->ops->bmdma_stop(ap); /* fall through */ @@ -2530,7 +2634,7 @@ static void ata_qc_timeout(struct ata_qu drv_stat = ata_chk_status(ap); /* ack bmdma irq events */ - ata_bmdma_ack_irq(ap); + ap->ops->irq_clear(ap); printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n", ap->id, qc->tf.command, drv_stat, host_stat); @@ -2669,6 +2773,24 @@ static void __ata_qc_complete(struct ata } /** + * ata_qc_free - free unused ata_queued_cmd + * @qc: Command to complete + * + * Designed to free unused ata_queued_cmd object + * in case something prevents using it. + * + * LOCKING: + * + */ +void ata_qc_free(struct ata_queued_cmd *qc) +{ + assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ + assert(qc->waiting == NULL); /* nothing should be waiting */ + + __ata_qc_complete(qc); +} + +/** * ata_qc_complete - Complete an active ATA command * @qc: Command to complete * @drv_stat: ATA status register contents @@ -2717,7 +2839,7 @@ static inline int ata_should_dma_map(str return 1; /* fall through */ - + default: return 0; } @@ -2959,7 +3081,43 @@ void ata_bmdma_setup(struct ata_queued_c void ata_bmdma_irq_clear(struct ata_port *ap) { - ata_bmdma_ack_irq(ap); + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; + writeb(readb(mmio), mmio); + } else { + unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; + outb(inb(addr), addr); + } + +} + +u8 ata_bmdma_status(struct ata_port *ap) +{ + u8 host_stat; + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + host_stat = readb(mmio + ATA_DMA_STATUS); + } else + host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + return host_stat; +} + +void ata_bmdma_stop(struct ata_port *ap) +{ + if (ap->flags & ATA_FLAG_MMIO) { + void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + + /* clear start/stop bit */ + writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, + mmio + ATA_DMA_CMD); + } else { + /* clear start/stop bit */ + outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, + ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + } + + /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ + ata_altstatus(ap); /* dummy read */ } /** @@ -2989,7 +3147,7 @@ inline unsigned int ata_host_intr (struc case ATA_PROT_ATAPI_DMA: case ATA_PROT_ATAPI: /* check status of DMA engine */ - host_stat = ata_bmdma_status(ap); + host_stat = ap->ops->bmdma_status(ap); VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat); /* if it's not our irq... */ @@ -2997,7 +3155,7 @@ inline unsigned int ata_host_intr (struc goto idle_irq; /* before we do anything else, clear DMA-Start bit */ - ata_bmdma_stop(ap); + ap->ops->bmdma_stop(ap); /* fall through */ @@ -3016,7 +3174,7 @@ inline unsigned int ata_host_intr (struc ap->id, qc->tf.protocol, status); /* ack bmdma irq events */ - ata_bmdma_ack_irq(ap); + ap->ops->irq_clear(ap); /* complete taskfile transaction */ ata_qc_complete(qc, status); @@ -3470,32 +3628,28 @@ void ata_std_ports(struct ata_ioports *i } static struct ata_probe_ent * -ata_probe_ent_alloc(int n, struct device *dev, struct ata_port_info **port) +ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port) { struct ata_probe_ent *probe_ent; - int i; - probe_ent = kmalloc(sizeof(*probe_ent) * n, GFP_KERNEL); + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); if (!probe_ent) { printk(KERN_ERR DRV_NAME "(%s): out of memory\n", pci_name(to_pci_dev(dev))); return NULL; } - memset(probe_ent, 0, sizeof(*probe_ent) * n); + memset(probe_ent, 0, sizeof(*probe_ent)); - for (i = 0; i < n; i++) { - INIT_LIST_HEAD(&probe_ent[i].node); - probe_ent[i].dev = dev; - - probe_ent[i].sht = port[i]->sht; - probe_ent[i].host_flags = port[i]->host_flags; - probe_ent[i].pio_mask = port[i]->pio_mask; - probe_ent[i].mwdma_mask = port[i]->mwdma_mask; - probe_ent[i].udma_mask = port[i]->udma_mask; - probe_ent[i].port_ops = port[i]->port_ops; + INIT_LIST_HEAD(&probe_ent->node); + probe_ent->dev = dev; - } + probe_ent->sht = port->sht; + probe_ent->host_flags = port->host_flags; + probe_ent->pio_mask = port->pio_mask; + probe_ent->mwdma_mask = port->mwdma_mask; + probe_ent->udma_mask = port->udma_mask; + probe_ent->port_ops = port->port_ops; return probe_ent; } @@ -3505,7 +3659,7 @@ struct ata_probe_ent * ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) { struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(1, pci_dev_to_dev(pdev), port); + ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); if (!probe_ent) return NULL; @@ -3531,39 +3685,47 @@ ata_pci_init_native_mode(struct pci_dev return probe_ent; } -struct ata_probe_ent * -ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port) +static struct ata_probe_ent * +ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, + struct ata_probe_ent **ppe2) { - struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(2, pci_dev_to_dev(pdev), port); + struct ata_probe_ent *probe_ent, *probe_ent2; + + probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); if (!probe_ent) return NULL; + probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]); + if (!probe_ent2) { + kfree(probe_ent); + return NULL; + } + + probe_ent->n_ports = 1; + probe_ent->irq = 14; - probe_ent[0].n_ports = 1; - probe_ent[0].irq = 14; + probe_ent->hard_port_no = 0; + probe_ent->legacy_mode = 1; - probe_ent[0].hard_port_no = 0; - probe_ent[0].legacy_mode = 1; + probe_ent2->n_ports = 1; + probe_ent2->irq = 15; - probe_ent[1].n_ports = 1; - probe_ent[1].irq = 15; + probe_ent2->hard_port_no = 1; + probe_ent2->legacy_mode = 1; - probe_ent[1].hard_port_no = 1; - probe_ent[1].legacy_mode = 1; - - probe_ent[0].port[0].cmd_addr = 0x1f0; - probe_ent[0].port[0].altstatus_addr = - probe_ent[0].port[0].ctl_addr = 0x3f6; - probe_ent[0].port[0].bmdma_addr = pci_resource_start(pdev, 4); - - probe_ent[1].port[0].cmd_addr = 0x170; - probe_ent[1].port[0].altstatus_addr = - probe_ent[1].port[0].ctl_addr = 0x376; - probe_ent[1].port[0].bmdma_addr = pci_resource_start(pdev, 4)+8; + probe_ent->port[0].cmd_addr = 0x1f0; + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = 0x3f6; + probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4); + + probe_ent2->port[0].cmd_addr = 0x170; + probe_ent2->port[0].altstatus_addr = + probe_ent2->port[0].ctl_addr = 0x376; + probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8; - ata_std_ports(&probe_ent[0].port[0]); - ata_std_ports(&probe_ent[1].port[0]); + ata_std_ports(&probe_ent->port[0]); + ata_std_ports(&probe_ent2->port[0]); + *ppe2 = probe_ent2; return probe_ent; } @@ -3587,6 +3749,7 @@ int ata_pci_init_one (struct pci_dev *pd struct ata_port_info *port[2]; u8 tmp8, mask; unsigned int legacy_mode = 0; + int disable_dev_on_err = 1; int rc; DPRINTK("ENTER\n"); @@ -3597,7 +3760,8 @@ int ata_pci_init_one (struct pci_dev *pd else port[1] = port[0]; - if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0) { + if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 + && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { /* TODO: support transitioning to native mode? */ pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); mask = (1 << 2) | (1 << 0); @@ -3616,18 +3780,22 @@ int ata_pci_init_one (struct pci_dev *pd return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + disable_dev_on_err = 0; goto err_out; + } if (legacy_mode) { - if (!request_region(0x1f0, 8, "libata")) + if (!request_region(0x1f0, 8, "libata")) { + disable_dev_on_err = 0; printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); - else + } else legacy_mode |= (1 << 0); - if (!request_region(0x170, 8, "libata")) + if (!request_region(0x170, 8, "libata")) { + disable_dev_on_err = 0; printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); - else + } else legacy_mode |= (1 << 1); } @@ -3642,9 +3810,7 @@ int ata_pci_init_one (struct pci_dev *pd goto err_out_regions; if (legacy_mode) { - probe_ent = ata_pci_init_legacy_mode(pdev, port); - if (probe_ent) - probe_ent2 = &probe_ent[1]; + probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2); } else probe_ent = ata_pci_init_native_mode(pdev, port); if (!probe_ent) { @@ -3656,17 +3822,14 @@ int ata_pci_init_one (struct pci_dev *pd spin_lock(&ata_module_lock); if (legacy_mode) { - int free = 0; if (legacy_mode & (1 << 0)) list_add_tail(&probe_ent->node, &ata_probe_list); else - free++; + kfree(probe_ent); if (legacy_mode & (1 << 1)) list_add_tail(&probe_ent2->node, &ata_probe_list); else - free++; - if (free > 1) - kfree(probe_ent); + kfree(probe_ent2); } else { list_add_tail(&probe_ent->node, &ata_probe_list); } @@ -3681,7 +3844,8 @@ err_out_regions: release_region(0x170, 8); pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (disable_dev_on_err) + pci_disable_device(pdev); return rc; } @@ -3723,15 +3887,12 @@ void ata_pci_remove_one (struct pci_dev if (host_set->mmio_base) iounmap(host_set->mmio_base); - pci_release_regions(pdev); - for (i = 0; i < host_set->n_ports; i++) { - struct ata_ioports *ioaddr; - ap = host_set->ports[i]; - ioaddr = &ap->ioaddr; if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { + struct ata_ioports *ioaddr = &ap->ioaddr; + if (ioaddr->cmd_addr == 0x1f0) release_region(0x1f0, 8); else if (ioaddr->cmd_addr == 0x170) @@ -3740,6 +3901,8 @@ void ata_pci_remove_one (struct pci_dev } kfree(host_set); + + pci_release_regions(pdev); pci_disable_device(pdev); dev_set_drvdata(dev, NULL); } @@ -3839,6 +4002,8 @@ EXPORT_SYMBOL_GPL(ata_std_dev_select); EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); EXPORT_SYMBOL_GPL(ata_check_status); +EXPORT_SYMBOL_GPL(ata_altstatus); +EXPORT_SYMBOL_GPL(ata_chk_err); EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); @@ -3847,6 +4012,8 @@ EXPORT_SYMBOL_GPL(ata_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); EXPORT_SYMBOL_GPL(ata_bmdma_start); EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); +EXPORT_SYMBOL_GPL(ata_bmdma_status); +EXPORT_SYMBOL_GPL(ata_bmdma_stop); EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(__sata_phy_reset); @@ -3857,7 +4024,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); EXPORT_SYMBOL_GPL(ata_scsi_error); EXPORT_SYMBOL_GPL(ata_scsi_detect); EXPORT_SYMBOL_GPL(ata_add_to_probe_list); -EXPORT_SYMBOL_GPL(libata_msleep); EXPORT_SYMBOL_GPL(ssleep); EXPORT_SYMBOL_GPL(ata_scsi_release); EXPORT_SYMBOL_GPL(ata_host_intr); @@ -3867,7 +4033,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_simulate); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); -EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode); EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/libata-scsi.c linux-2.4.30-rc1/drivers/scsi/libata-scsi.c --- linux-2.4.29/drivers/scsi/libata-scsi.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/libata-scsi.c 2005-03-18 18:06:31.312164624 +0000 @@ -203,7 +203,7 @@ void ata_to_sense_error(struct ata_queue {0x40, MEDIUM_ERROR, 0x11, 0x04}, // Uncorrectable ECC error Unrecovered read error /* BBD - block marked bad */ {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error - {0xFF, 0xFF, 0xFF, 0xFF}, // END mark + {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; static unsigned char stat_table[][4] = { /* Must be first because BUSY means no other bits valid */ @@ -211,22 +211,22 @@ void ata_to_sense_error(struct ata_queue {0x20, HARDWARE_ERROR, 0x00, 0x00}, // Device fault {0x08, ABORTED_COMMAND, 0x47, 0x00}, // Timed out in xfer, fake parity for now {0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered - {0xFF, 0xFF, 0xFF, 0xFF}, // END mark + {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; int i = 0; cmd->result = SAM_STAT_CHECK_CONDITION; - + /* * Is this an error we can process/parse */ - + if(drv_stat & ATA_ERR) /* Read the err bits */ err = ata_chk_err(qc->ap); /* Display the ATA level error info */ - + printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat); if(drv_stat & 0x80) { @@ -243,7 +243,7 @@ void ata_to_sense_error(struct ata_queue if(drv_stat & 0x01) printk("Error "); } printk("}\n"); - + if(err) { printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err); @@ -260,11 +260,11 @@ void ata_to_sense_error(struct ata_queue if(err & 0x02) printk("TrackZeroNotFound "); if(err & 0x01) printk("AddrMarkNotFound "); printk("}\n"); - + /* Should we dump sector info here too ?? */ } - - + + /* Look for err */ while(sense_table[i][0] != 0xFF) { @@ -283,7 +283,8 @@ void ata_to_sense_error(struct ata_queue /* No immediate match */ if(err) printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err); - + + i = 0; /* Fall back to interpreting status bits */ while(stat_table[i][0] != 0xFF) { @@ -301,7 +302,7 @@ void ata_to_sense_error(struct ata_queue /* No error ?? */ printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat); /* additional-sense-code[-qualifier] */ - + sb[0] = 0x70; sb[2] = MEDIUM_ERROR; sb[7] = 0x0A; @@ -449,19 +450,24 @@ static unsigned int ata_scsi_verify_xlat } if (lba48) { + tf->command = ATA_CMD_VERIFY_EXT; + tf->hob_nsect = (n_sect >> 8) & 0xff; tf->hob_lbah = (sect >> 40) & 0xff; tf->hob_lbam = (sect >> 32) & 0xff; tf->hob_lbal = (sect >> 24) & 0xff; - } else + } else { + tf->command = ATA_CMD_VERIFY; + tf->device |= (sect >> 24) & 0xf; + } tf->nsect = n_sect & 0xff; - tf->hob_lbah = (sect >> 16) & 0xff; - tf->hob_lbam = (sect >> 8) & 0xff; - tf->hob_lbal = sect & 0xff; + tf->lbah = (sect >> 16) & 0xff; + tf->lbam = (sect >> 8) & 0xff; + tf->lbal = sect & 0xff; return 0; } @@ -561,7 +567,7 @@ static unsigned int ata_scsi_rw_xlat(str return 1; /* stores LBA27:24 in lower 4 bits of device reg */ - tf->device |= scsicmd[2]; + tf->device |= scsicmd[6]; qc->nsect = scsicmd[13]; } @@ -657,6 +663,7 @@ static void ata_scsi_translate(struct at return; err_out: + ata_qc_free(qc); ata_bad_cdb(cmd, done); DPRINTK("EXIT - badcmd\n"); } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/libata.h linux-2.4.30-rc1/drivers/scsi/libata.h --- linux-2.4.29/drivers/scsi/libata.h 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/libata.h 2005-03-18 18:06:45.463013368 +0000 @@ -37,6 +37,7 @@ struct ata_scsi_args { /* libata-core.c */ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); +extern void ata_qc_free(struct ata_queued_cmd *qc); extern int ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/megaraid2.c linux-2.4.30-rc1/drivers/scsi/megaraid2.c --- linux-2.4.29/drivers/scsi/megaraid2.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/megaraid2.c 2005-03-18 18:06:43.954242736 +0000 @@ -14,7 +14,7 @@ * - speed-ups (list handling fixes, issued_list, optimizations.) * - lots of cleanups. * - * Version : v2.10.3 (Apr 08, 2004) + * Version : v2.10.8.2 (July 26, 2004) * * Authors: Atul Mukker * Sreenivas Bagalkote @@ -46,7 +46,7 @@ #include "megaraid2.h" -#ifdef LSI_CONFIG_COMPAT +#if defined(__x86_64__) #include #endif @@ -90,10 +90,15 @@ static struct notifier_block mega_notifi static struct mega_hbas mega_hbas[MAX_CONTROLLERS]; /* + * Lock to protect access to IOCTL + */ +static struct semaphore megaraid_ioc_mtx; + +/* * The File Operations structure for the serial/ioctl interface of the driver */ static struct file_operations megadev_fops = { - .ioctl = megadev_ioctl, + .ioctl = megadev_ioctl_entry, .open = megadev_open, .release = megadev_close, .owner = THIS_MODULE, @@ -107,7 +112,7 @@ static struct file_operations megadev_fo static struct mcontroller mcontroller[MAX_CONTROLLERS]; /* The current driver version */ -static u32 driver_ver = 0x02100000; +static u32 driver_ver = 0x02104000; /* major number used by the device for character interface */ static int major; @@ -189,6 +194,11 @@ megaraid_detect(Scsi_Host_Template *host */ mega_reorder_hosts(); + /* + * Initialize the IOCTL lock + */ + init_MUTEX( &megaraid_ioc_mtx ); + #ifdef CONFIG_PROC_FS mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root); @@ -223,7 +233,7 @@ megaraid_detect(Scsi_Host_Template *host "MegaRAID Shutdown routine not registered!!\n"); } -#ifdef LSI_CONFIG_COMPAT +#if defined(__x86_64__) /* * Register the 32-bit ioctl conversion */ @@ -273,6 +283,8 @@ mega_find_card(Scsi_Host_Template *host_ unsigned long tbase; unsigned long flag = 0; int i, j; + u8 did_int_pthru_f = 0; + u8 did_int_data_f = 0; while((pdev = pci_find_device(pci_vendor, pci_device, pdev))) { @@ -328,6 +340,7 @@ mega_find_card(Scsi_Host_Template *host_ (subsysvid != HP_SUBSYS_VID) && (subsysvid != INTEL_SUBSYS_VID) && (subsysvid != FSC_SUBSYS_VID) && + (subsysvid != ACER_SUBSYS_VID) && (subsysvid != LSI_SUBSYS_VID) ) continue; @@ -465,6 +478,33 @@ mega_find_card(Scsi_Host_Template *host_ alloc_scb_f = 1; + /* + * Allocate memory for ioctls + */ + adapter->int_pthru = pci_alloc_consistent ( + adapter->dev, + sizeof(mega_passthru), + &adapter->int_pthru_dma_hndl ); + + if( adapter->int_pthru == NULL ) { + printk(KERN_WARNING "megaraid: out of RAM.\n"); + goto fail_attach; + } + else + did_int_pthru_f = 1; + + adapter->int_data = pci_alloc_consistent ( + adapter->dev, + INT_MEMBLK_SZ, + &adapter->int_data_dma_hndl ); + + if( adapter->int_data == NULL ) { + printk(KERN_WARNING "megaraid: out of RAM.\n"); + goto fail_attach; + } + else + did_int_data_f = 1; + /* Request our IRQ */ if( adapter->flag & BOARD_MEMMAP ) { if(request_irq(irq, megaraid_isr_memmapped, SA_SHIRQ, @@ -676,6 +716,19 @@ mega_find_card(Scsi_Host_Template *host_ continue; fail_attach: + if( did_int_data_f ) { + pci_free_consistent( + adapter->dev, INT_MEMBLK_SZ, adapter->int_data, + adapter->int_data_dma_hndl ); + } + + if( did_int_pthru_f ) { + pci_free_consistent( + adapter->dev, sizeof(mega_passthru), + (void*) adapter->int_pthru, + adapter->int_pthru_dma_hndl ); + } + if( did_setup_mbox_f ) { pci_free_consistent(adapter->dev, sizeof(mbox64_t), (void *)adapter->una_mbox64, @@ -937,6 +990,78 @@ mega_query_adapter(adapter_t *adapter) /** + * 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 * @@ -949,52 +1074,26 @@ mega_runpendq(adapter_t *adapter) __mega_runpendq(adapter); } -/* - * megaraid_queue() - * @scmd - Issue this scsi command - * @done - the callback hook into the scsi mid-layer - * - * The command queuing entry point for the mid-layer. - */ -static int -megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) -{ - adapter_t *adapter; - scb_t *scb; - int busy=0; - - adapter = (adapter_t *)scmd->host->hostdata; - - scmd->scsi_done = done; +static void +__mega_runpendq(adapter_t *adapter) +{ + scb_t *scb; + struct list_head *pos, *next; - /* - * Allocate and build a SCB request - * busy flag will be set if mega_build_cmd() command could not - * allocate scb. We will return non-zero status in that case. - * NOTE: scb can be null even though certain commands completed - * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, we would - * return 0 in that case. - */ + /* Issue any pending commands to the card */ + list_for_each_safe(pos, next, &adapter->pending_list) { - scb = mega_build_cmd(adapter, scmd, &busy); + scb = list_entry(pos, scb_t, list); - if(scb) { - scb->state |= SCB_PENDQ; - list_add_tail(&scb->list, &adapter->pending_list); + if( !(scb->state & SCB_ISSUED) ) { - /* - * Check if the HBA is in quiescent state, e.g., during a - * delete logical drive opertion. If it is, don't run - * the pending_list. - */ - if(atomic_read(&adapter->quiescent) == 0) { - mega_runpendq(adapter); + if( issue_scb(adapter, scb) != 0 ) + return; } - return 0; } - return busy; + return; } @@ -1068,25 +1167,136 @@ mega_get_ldrv_num(adapter_t *adapter, Sc } /* - * If "delete logical drive" feature is enabled on this controller. - * Do only if at least one delete logical drive operation was done. - * - * Also, after logical drive deletion, instead of logical drive number, + * If "delete logical drive" feature is enabled on this controller, * the value returned should be 0x80+logical drive id. - * - * These is valid only for IO commands. */ + if (adapter->support_random_del) + ldrv_num += 0x80; - if (adapter->support_random_del && adapter->read_ldidmap ) - switch (cmd->cmnd[0]) { - case READ_6: /* fall through */ - case WRITE_6: /* fall through */ - case READ_10: /* fall through */ - case WRITE_10: - ldrv_num += 0x80; + 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); - return ldrv_num; + 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() + * @scmd - Issue this scsi command + * @done - the callback hook into the scsi mid-layer + * + * The command queuing entry point for the mid-layer. + */ +static int +megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) +{ + adapter_t *adapter; + scb_t *scb; + int busy=0; + + adapter = (adapter_t *)scmd->host->hostdata; + + scmd->scsi_done = done; + + + /* + * Allocate and build a SCB request + * busy flag will be set if mega_build_cmd() command could not + * allocate scb. We will return non-zero status in that case. + * NOTE: scb can be null even though certain commands completed + * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, we would + * return 0 in that case. + */ + + scb = mega_build_cmd(adapter, scmd, &busy); + + if(scb) { + scb->state |= SCB_PENDQ; + list_add_tail(&scb->list, &adapter->pending_list); + + /* + * Check if the HBA is in quiescent state, e.g., during a + * delete logical drive opertion. If it is, don't run + * the pending_list. + */ + if(atomic_read(&adapter->quiescent) == 0) { + mega_runpendq(adapter); + } + return 0; + } + + return busy; } @@ -1112,7 +1322,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_ mbox_t *mbox; long seg; char islogical; - int max_ldrv_num; int channel = 0; int target = 0; int ldrv_num = 0; /* logical drive number */ @@ -1184,24 +1393,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_ } ldrv_num = mega_get_ldrv_num(adapter, cmd, channel); - - - max_ldrv_num = (adapter->flag & BOARD_40LD) ? - MAX_LOGICAL_DRIVES_40LD : MAX_LOGICAL_DRIVES_8LD; - - /* - * max_ldrv_num increases by 0x80 if some logical drive was - * deleted. - */ - if(adapter->read_ldidmap) - max_ldrv_num += 0x80; - - if(ldrv_num > max_ldrv_num ) { - cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); - return NULL; - } - } else { if( cmd->lun > 7) { @@ -1671,111 +1862,6 @@ mega_prepare_extpassthru(adapter_t *adap } -static void -__mega_runpendq(adapter_t *adapter) -{ - scb_t *scb; - struct list_head *pos, *next; - - /* Issue any pending commands to the card */ - list_for_each_safe(pos, next, &adapter->pending_list) { - - scb = list_entry(pos, scb_t, list); - - if( !(scb->state & SCB_ISSUED) ) { - - if( issue_scb(adapter, scb) != 0 ) - return; - } - } - - return; -} - - -/** - * 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 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; -} - - -/* - * 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; -} - /** * issue_scb_block() * @adapter - pointer to our soft state @@ -1865,77 +1951,47 @@ issue_scb_block(adapter_t *adapter, u_ch // invalidate the completed command id array. After command // completion, firmware would write the valid id. for (i = 0; i < MAX_FIRMWARE_STATUS; i++) { - mbox->completed[i] = 0xFF; - } - - return status; - -bug_blocked_mailbox: - printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n"); - udelay (1000); - return -1; -} - - -/** - * 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); + mbox->completed[i] = 0xFF; + } - while ((nstatus = adapter->mbox->numstatus) == 0xFF) { - cpu_relax(); - } - adapter->mbox->numstatus = 0xFF; + return status; - for (i = 0; i < nstatus; i++) { - while ((completed[i] = adapter->mbox->completed[i]) - == 0xFF) { - cpu_relax(); - } +bug_blocked_mailbox: + printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n"); + udelay (1000); + return -1; +} - 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; +/** + * 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; - /* - * decrement the pending queue counter - */ - atomic_sub(nstatus, &adapter->pend_cmds); - /* Acknowledge interrupt */ - irq_ack(adapter); + spin_lock_irqsave(adapter->host_lock, flags); - mega_cmd_done(adapter, completed, nstatus, status); + megaraid_iombox_ack_sequence(adapter); - } while(1); + /* Loop through any pending requests */ + if( atomic_read(&adapter->quiescent ) == 0) { + mega_runpendq(adapter); + } + + spin_unlock_irqrestore(adapter->host_lock, flags); + + return; } @@ -2007,38 +2063,6 @@ megaraid_memmbox_ack_sequence(adapter_t /** - * 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_isr_memmapped() * @irq - irq * @devp - pointer to our soft state @@ -2069,7 +2093,6 @@ megaraid_isr_memmapped(int irq, void *de return; } - /** * mega_cmd_done() * @adapter - pointer to our soft state @@ -2381,7 +2404,6 @@ mega_free_scb(adapter_t *adapter, scb_t list_add(&scb->list, &adapter->free_list); } - static int __mega_busywait_mbox (adapter_t *adapter) { @@ -2412,6 +2434,10 @@ mega_build_sglist(adapter_t *adapter, sc cmd = scb->cmd; + /* return 0 elements if no data transfer */ + if (!cmd->request_buffer || !cmd->request_bufflen) + return 0; + /* Scatter-gather not used */ if( !cmd->use_sg ) { @@ -2535,7 +2561,6 @@ mega_8_to_40ld(mraid_inquiry *inquiry, m enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i]; } - static inline void mega_free_sgl(adapter_t *adapter) { @@ -2666,6 +2691,13 @@ megaraid_release(struct Scsi_Host *host) pci_free_consistent(adapter->dev, sizeof(mbox64_t), (void *)adapter->una_mbox64, adapter->una_mbox64_dma); + pci_free_consistent( adapter->dev, sizeof(mega_passthru), + (void*) adapter->int_pthru, + adapter->int_pthru_dma_hndl ); + + pci_free_consistent( adapter->dev, INT_MEMBLK_SZ, adapter->int_data, + adapter->int_data_dma_hndl ); + hba_count--; if( hba_count == 0 ) { @@ -2694,7 +2726,7 @@ megaraid_release(struct Scsi_Host *host) */ scsi_unregister(host); -#ifdef LSI_CONFIG_COMPAT +#if defined(__x86_64__) unregister_ioctl32_conversion(MEGAIOCCMD); #endif @@ -2736,30 +2768,36 @@ megaraid_command (Scsi_Cmnd *cmd) } -/** - * megaraid_abort - abort the scsi command - * @scp - command to be aborted - * - * Abort a previous SCSI request. Only commands on the pending list can be - * aborted. All the commands issued to the F/W must complete. - */ static int megaraid_abort(Scsi_Cmnd *scp) { adapter_t *adapter; struct list_head *pos, *next; scb_t *scb; - long iter; - int rval = SUCCESS; + + printk("megaraid: aborting-%ld cmd=%x \n", + scp->serial_number, scp->cmnd[0], scp->channel, + scp->target, scp->lun); adapter = (adapter_t *)scp->host->hostdata; - ASSERT( spin_is_locked(adapter->host_lock) ); + /* + * Check if hw_error flag was set in previous RESET call. If it was, + * then FW is hanging and unlikely to function. We can return FAILURE + * from here and expect the RESET handler to be called. + */ - printk("megaraid: aborting-%ld cmd=%x \n", - scp->serial_number, scp->cmnd[0], scp->channel, scp->target, - scp->lun); + if (adapter->hw_error) { + printk("megaraid: hw error, cannot abort\n"); + return FAILED; + } + + ASSERT( spin_is_locked(adapter->host_lock) ); + /* + * If cmd is waiting to be issued to FW, ABORT it with SUCEESS. If it + * has already been issued, return FAILURE and expect RESET later. + */ list_for_each_safe( pos, next, &adapter->pending_list ) { @@ -2769,15 +2807,11 @@ megaraid_abort(Scsi_Cmnd *scp) scb->state |= SCB_ABORT; - /* - * Check if this command was never issued. If this is - * the case, take it off from the pending list and - * complete. - */ if( !(scb->state & SCB_ISSUED) ) { - printk(KERN_WARNING - "megaraid: %ld:%d, driver owner.\n", + /* Not issued to the FW yet; ABORT it */ + + printk( "megaraid: %ld:%d, driver owner.\n", scp->serial_number, scb->idx); scp->result = (DID_ABORT << 16); @@ -2786,67 +2820,31 @@ megaraid_abort(Scsi_Cmnd *scp) scp->scsi_done(scp); - break; + return SUCCESS; + } + else { + /* Issued to the FW; can do nothing */ + return FAILED; } } } /* - * By this time, either all commands are completed or aborted by - * mid-layer. Do not return until all the commands are actually - * completed by the firmware + * cmd is _not_ in our pending_list. Most likely we completed the cmd */ - iter = 0; - while( atomic_read(&adapter->pend_cmds) > 0 ) { - /* - * Perform the ack sequence, since interrupts are not - * available right now! - */ - if( adapter->flag & BOARD_MEMMAP ) { - megaraid_memmbox_ack_sequence(adapter); - } - else { - megaraid_iombox_ack_sequence(adapter); - } - - /* - * print a message once every second only - */ - if( !(iter % 1000) ) { - printk( - "megaraid: Waiting for %d commands to flush: iter:%ld\n", - atomic_read(&adapter->pend_cmds), iter); - } - - if( iter++ < MBOX_ABORT_SLEEP*1000 ) { - mdelay(1); - } - else { - printk(KERN_WARNING - "megaraid: critical hardware error!\n"); - - rval = FAILED; - - break; - } - } - - if( rval == SUCCESS ) { - printk(KERN_INFO - "megaraid: abort sequence successfully completed.\n"); - } - - return rval; + return SUCCESS; } static int megaraid_reset(Scsi_Cmnd *cmd) { - adapter_t *adapter; - megacmd_t mc; - long iter; - int rval = SUCCESS; + DECLARE_WAIT_QUEUE_HEAD(wq); + int i; + scb_t *scb; + adapter_t *adapter; + struct list_head *pos, *next; + int rval; adapter = (adapter_t *)cmd->host->hostdata; @@ -2856,31 +2854,54 @@ megaraid_reset(Scsi_Cmnd *cmd) cmd->serial_number, cmd->cmnd[0], cmd->channel, cmd->target, cmd->lun); + /* + * Check if hw_error flag was set in previous RESET call. If it was, + * then we needn't do any handling here. The controller will be marked + * offline soon + */ -#if MEGA_HAVE_CLUSTERING - mc.cmd = MEGA_CLUSTER_CMD; - mc.opcode = MEGA_RESET_RESERVATIONS; - - spin_unlock_irq(adapter->host_lock); - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { - printk(KERN_WARNING - "megaraid: reservation reset failed.\n"); + if (adapter->hw_error) { + printk("megaraid: hw error, cannot reset\n"); + return FAILED; } - else { - printk(KERN_INFO "megaraid: reservation reset.\n"); + + /* + * Return all the pending cmds to the mid-layer with the cmd result + * DID_RESET. Make sure you don't return the cmds ISSUED to FW. + */ + list_for_each_safe( pos, next, &adapter->pending_list ) { + + scb = list_entry(pos, scb_t, list); + scb->state |= SCB_RESET; + + if( !(scb->state & SCB_ISSUED) ) { + + /* Not issued to the FW; return with RESET */ + cmd->result = (DID_RESET << 16); + + mega_free_scb(adapter, scb); + cmd->scsi_done(cmd); + } } - spin_lock_irq(adapter->host_lock); -#endif /* - * Do not return until all the commands are actually completed by the - * firmware + * Under exceptional conditions, FW may take up to 3 mins to complete + * processing all pending commands. We'll wait for maximum 3 mins to + * see if all outstanding commands are completed. */ - iter = 0; - while( atomic_read(&adapter->pend_cmds) > 0 ) { + + if (atomic_read(&adapter->pend_cmds) == 0) + return SUCCESS; + + printk("megaraid: %d pending cmds; max wait %d seconds\n", + atomic_read(&adapter->pend_cmds), MBOX_RESET_WAIT ); + + for(i=0; (ipend_cmds)); i++){ + + ASSERT( spin_is_locked(adapter->host_lock) ); + /* - * Perform the ack sequence, since interrupts are not - * available right now! + * Perform the ack sequence, since interrupts are unavailable */ if( adapter->flag & BOARD_MEMMAP ) { megaraid_memmbox_ack_sequence(adapter); @@ -2889,55 +2910,35 @@ megaraid_reset(Scsi_Cmnd *cmd) megaraid_iombox_ack_sequence(adapter); } - /* - * print a message once every second only - */ - if( !(iter % 1000) ) { - printk( - "megaraid: Waiting for %d commands to flush: iter:%ld\n", - atomic_read(&adapter->pend_cmds), iter); - } + spin_unlock(adapter->host_lock); - if( iter++ < MBOX_RESET_SLEEP*1000 ) { - mdelay(1); + /* Print a message once every 5 seconds */ + if (!(i % 5)) { + printk("megaraid: pending %d; remaining %d seconds\n", + atomic_read(&adapter->pend_cmds), + MBOX_RESET_WAIT - i); } - else { - printk(KERN_WARNING - "megaraid: critical hardware error!\n"); - rval = FAILED; - - break; - } - } + sleep_on_timeout(&wq, HZ); - if( rval == SUCCESS ) { - printk(KERN_INFO - "megaraid: reset sequence successfully completed.\n"); + spin_lock(adapter->host_lock); } - return rval; -} - + /* + * If after 3 mins there are still outstanding cmds, set the hw_error + * flag so that we can return from subsequent ABORT/RESET handlers + * without any processing + */ -/** - * mega_allocate_inquiry() - * @dma_handle - handle returned for dma address - * @pdev - handle to pci device - * - * allocates memory for inquiry structure - */ -static inline caddr_t -mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev) -{ - return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle); -} + rval = SUCCESS; + if (atomic_read(&adapter->pend_cmds)) { + adapter->hw_error = 1; + printk("megaraid: critical hardware error!\n" ); + rval = FAILED; + } -static inline void -mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev) -{ - pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle); + return rval; } @@ -3199,6 +3200,26 @@ proc_read_mbox(char *page, char **start, return len; } +/** + * mega_allocate_inquiry() + * @dma_handle - handle returned for dma address + * @pdev - handle to pci device + * + * allocates memory for inquiry structure + */ +static inline caddr_t +mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev) +{ + return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle); +} + + +static inline void +mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev) +{ + pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle); +} + /** * proc_rebuild_rate() @@ -3988,6 +4009,7 @@ static int megaraid_reboot_notify (struct notifier_block *this, unsigned long code, void *unused) { + DECLARE_WAIT_QUEUE_HEAD(wq); adapter_t *adapter; struct Scsi_Host *host; u8 raw_mbox[sizeof(mbox_t)]; @@ -4040,10 +4062,10 @@ megaraid_reboot_notify (struct notifier_ printk(KERN_INFO "megaraid: cache flush delay: "); for( i = 9; i >= 0; i-- ) { printk("\b\b\b[%d]", i); - mdelay(1000); + sleep_on_timeout(&wq, HZ); } printk("\b\b\b[done]\n"); - mdelay(1000); + sleep_on_timeout(&wq, HZ); return NOTIFY_DONE; } @@ -4150,17 +4172,27 @@ megadev_open (struct inode *inode, struc } -#ifdef LSI_CONFIG_COMPAT +#if defined(__x86_64__) static int megadev_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filep) { struct inode *inode = filep->f_dentry->d_inode; - return megadev_ioctl(inode, filep, cmd, arg); + return megadev_ioctl_entry(inode, filep, cmd, arg); } #endif +static int +megadev_ioctl_entry(struct inode *inode, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int rval; + down( &megaraid_ioc_mtx ); + rval = megadev_ioctl( inode, filep, cmd, arg ); + up( &megaraid_ioc_mtx ); + return rval; +} /** * megadev_ioctl() @@ -4184,9 +4216,8 @@ megadev_ioctl(struct inode *inode, struc int rval; mega_passthru *upthru; /* user address for passthru */ mega_passthru *pthru; /* copy user passthru here */ - dma_addr_t pthru_dma_hndl; void *data = NULL; /* data to be transferred */ - dma_addr_t data_dma_hndl; /* dma handle for data xfer area */ + dma_addr_t data_dma_hndl = 0; megacmd_t mc; megastat_t *ustats; int num_ldrv; @@ -4302,7 +4333,7 @@ megadev_ioctl(struct inode *inode, struc /* * Which adapter */ - if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) + if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) return (-ENODEV); adapter = hba_soft_state[adapno]; @@ -4358,13 +4389,7 @@ megadev_ioctl(struct inode *inode, struc if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) { /* Passthru commands */ - pthru = pci_alloc_consistent(pdev, - sizeof(mega_passthru), - &pthru_dma_hndl); - - if( pthru == NULL ) { - return (-ENOMEM); - } + pthru = adapter->int_pthru; /* * The user passthru structure @@ -4376,29 +4401,27 @@ megadev_ioctl(struct inode *inode, struc */ if( copy_from_user(pthru, (char *)upthru, sizeof(mega_passthru)) ) { - - pci_free_consistent(pdev, - sizeof(mega_passthru), pthru, - pthru_dma_hndl); - return (-EFAULT); } /* - * Is there a data transfer + * Is there a data transfer; If the data transfer + * length is <= INT_MEMBLK_SZ, usr the buffer + * allocated at the load time. Otherwise, allocate it + * here. */ - if( pthru->dataxferlen ) { - data = pci_alloc_consistent(pdev, - pthru->dataxferlen, - &data_dma_hndl); - - if( data == NULL ) { - pci_free_consistent(pdev, - sizeof(mega_passthru), - pthru, - pthru_dma_hndl); + if (pthru->dataxferlen) { + if (pthru->dataxferlen > INT_MEMBLK_SZ) { + data = pci_alloc_consistent ( + pdev, + pthru->dataxferlen, + &data_dma_hndl ); - return (-ENOMEM); + if (data == NULL) + return (-ENOMEM); + } + else { + data = adapter->int_data; } /* @@ -4406,7 +4429,11 @@ megadev_ioctl(struct inode *inode, struc * address at just allocated memory */ uxferaddr = pthru->dataxferaddr; - pthru->dataxferaddr = data_dma_hndl; + if (data_dma_hndl) + pthru->dataxferaddr = data_dma_hndl; + else + pthru->dataxferaddr = + adapter->int_data_dma_hndl; } @@ -4421,14 +4448,14 @@ megadev_ioctl(struct inode *inode, struc (char *)((ulong)uxferaddr), pthru->dataxferlen) ) { rval = (-EFAULT); - goto freemem_and_return; + goto freedata_and_return; } } memset(&mc, 0, sizeof(megacmd_t)); mc.cmd = MEGA_MBOXCMD_PASSTHRU; - mc.xferaddr = (u32)pthru_dma_hndl; + mc.xferaddr = (u32)adapter->int_pthru_dma_hndl; /* * Issue the command @@ -4437,7 +4464,7 @@ megadev_ioctl(struct inode *inode, struc rval = mega_n_to_m((void *)arg, &mc); - if( rval ) goto freemem_and_return; + if( rval ) goto freedata_and_return; /* @@ -4456,18 +4483,14 @@ megadev_ioctl(struct inode *inode, struc */ copy_to_user(upthru->reqsensearea, pthru->reqsensearea, 14); - -freemem_and_return: - if( pthru->dataxferlen ) { - pci_free_consistent(pdev, - pthru->dataxferlen, data, - data_dma_hndl); +freedata_and_return: + if (data_dma_hndl) { + pci_free_consistent( pdev, pthru->dataxferlen, + data, data_dma_hndl ); } - pci_free_consistent(pdev, sizeof(mega_passthru), - pthru, pthru_dma_hndl); - return rval; + } else { /* DCMD commands */ @@ -4476,13 +4499,18 @@ freemem_and_return: * Is there a data transfer */ if( uioc.xferlen ) { - data = pci_alloc_consistent(pdev, - uioc.xferlen, &data_dma_hndl); + if (uioc.xferlen > INT_MEMBLK_SZ) { + data = pci_alloc_consistent( + pdev, + uioc.xferlen, + &data_dma_hndl ); - if( data == NULL ) { - return (-ENOMEM); + if (data == NULL) + return (-ENOMEM); + } + else { + data = adapter->int_data; } - uxferaddr = MBOX(uioc)->xferaddr; } @@ -4497,9 +4525,9 @@ freemem_and_return: (char *)((ulong)uxferaddr), uioc.xferlen) ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + pci_free_consistent( + pdev, uioc.xferlen, + data, data_dma_hndl ); return (-EFAULT); } @@ -4507,7 +4535,10 @@ freemem_and_return: memcpy(&mc, MBOX(uioc), sizeof(megacmd_t)); - mc.xferaddr = (u32)data_dma_hndl; + if (data_dma_hndl ) + mc.xferaddr = (u32)data_dma_hndl; + else + mc.xferaddr = (u32)(adapter->int_data_dma_hndl); /* * Issue the command @@ -4517,12 +4548,10 @@ freemem_and_return: rval = mega_n_to_m((void *)arg, &mc); if( rval ) { - if( uioc.xferlen ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + if (data_dma_hndl) { + pci_free_consistent( pdev, uioc.xferlen, + data, data_dma_hndl ); } - return rval; } @@ -4537,10 +4566,9 @@ freemem_and_return: } } - if( uioc.xferlen ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + if (data_dma_hndl) { + pci_free_consistent( pdev, uioc.xferlen, + data, data_dma_hndl ); } return rval; @@ -4725,19 +4753,22 @@ mega_n_to_m(void *arg, megacmd_t *mc) else { uioc_mimd = (struct uioctl_t *)arg; - if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) ) + if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) ) { return (-EFAULT); + } if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) { umc = (megacmd_t *)uioc_mimd->mbox; - if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) + if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) { return -EFAULT; + } upthru = (mega_passthru *)((ulong)kmc.xferaddr); - if( put_user(mc->status, (u8 *)&upthru->scsistatus) ) + if( put_user(mc->status, (u8 *)&upthru->scsistatus) ){ return (-EFAULT); + } } } @@ -5148,7 +5179,6 @@ mega_support_cluster(adapter_t *adapter) } - /** * mega_reorder_hosts() * @@ -5363,6 +5393,7 @@ mega_adapinq(adapter_t *adapter, dma_add } + /** mega_internal_dev_inquiry() * @adapter - pointer to our soft state * @ch - channel for this device diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/megaraid2.h linux-2.4.30-rc1/drivers/scsi/megaraid2.h --- linux-2.4.29/drivers/scsi/megaraid2.h 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/megaraid2.h 2005-03-18 18:06:14.268755616 +0000 @@ -6,7 +6,7 @@ #define MEGARAID_VERSION \ - "v2.10.3 (Release Date: Thu Apr 8 16:16:05 EDT 2004)\n" + "v2.10.8.2 (Release Date: Mon Jul 26 12:15:51 EDT 2004)\n" /* * Driver features - change the values to enable or disable features in the @@ -82,6 +82,7 @@ #define LSI_SUBSYS_VID 0x1000 #define INTEL_SUBSYS_VID 0x8086 #define FSC_SUBSYS_VID 0x1734 +#define ACER_SUBSYS_VID 0x1025 #define HBA_SIGNATURE 0x3344 #define HBA_SIGNATURE_471 0xCCCC @@ -978,6 +979,15 @@ typedef struct { cmds */ int has_cluster; /* cluster support on this HBA */ + +#define INT_MEMBLK_SZ (28*1024) + mega_passthru *int_pthru; /*internal pthru*/ + dma_addr_t int_pthru_dma_hndl; + caddr_t int_data; /*internal data*/ + dma_addr_t int_data_dma_hndl; + + int hw_error; + }adapter_t; @@ -1085,18 +1095,21 @@ typedef enum { LOCK_INT, LOCK_EXT } lock #define MBOX_ABORT_SLEEP 60 #define MBOX_RESET_SLEEP 30 +#define MBOX_RESET_WAIT 180 const char *megaraid_info (struct Scsi_Host *); static int megaraid_detect(Scsi_Host_Template *); static void mega_find_card(Scsi_Host_Template *, u16, u16); static int mega_query_adapter(adapter_t *); -static int issue_scb(adapter_t *, scb_t *); +static inline int issue_scb(adapter_t *, scb_t *); static int mega_setup_mailbox(adapter_t *); static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *); +static inline scb_t *mega_allocate_scb(adapter_t *, Scsi_Cmnd *); static void __mega_runpendq(adapter_t *); +static inline void mega_runpendq(adapter_t *); static int issue_scb_block(adapter_t *, u_char *); static void megaraid_isr_memmapped(int, void *, struct pt_regs *); @@ -1113,6 +1126,7 @@ static int megaraid_reset(Scsi_Cmnd *); static int mega_build_sglist (adapter_t *adapter, scb_t *scb, u32 *buffer, u32 *length); +static inline int mega_busywait_mbox (adapter_t *); static int __mega_busywait_mbox (adapter_t *); static void mega_cmd_done(adapter_t *, u8 [], int, int); static inline void mega_free_sgl (adapter_t *adapter); @@ -1123,15 +1137,13 @@ static int megaraid_reboot_notify (struc unsigned long, void *); static int megadev_open (struct inode *, struct file *); -#if defined(CONFIG_COMPAT) || defined( __x86_64__) || defined(IA32_EMULATION) -#define LSI_CONFIG_COMPAT -#endif - -#ifdef LSI_CONFIG_COMPAT +#if defined(__x86_64__) static int megadev_compat_ioctl(unsigned int, unsigned int, unsigned long, struct file *); #endif +static int megadev_ioctl_entry (struct inode *, struct file *, unsigned int, + unsigned long); static int megadev_ioctl (struct inode *, struct file *, unsigned int, unsigned long); static int mega_m_to_n(void *, nitioctl_t *); @@ -1164,6 +1176,8 @@ static int proc_rdrv(adapter_t *, char * static int mega_adapinq(adapter_t *, dma_addr_t); static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t); +static inline caddr_t mega_allocate_inquiry(dma_addr_t *, struct pci_dev *); +static inline void mega_free_inquiry(caddr_t, dma_addr_t, struct pci_dev *); static int mega_print_inquiry(char *, char *); #endif @@ -1174,6 +1188,7 @@ static mega_ext_passthru* mega_prepare_e scb_t *, Scsi_Cmnd *, int, int); static void mega_enum_raid_scsi(adapter_t *); static void mega_get_boot_drv(adapter_t *); +static inline int mega_get_ldrv_num(adapter_t *, Scsi_Cmnd *, int); static int mega_support_random_del(adapter_t *); static int mega_del_logdrv(adapter_t *, int); static int mega_do_del_logdrv(adapter_t *, int); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/osst.c linux-2.4.30-rc1/drivers/scsi/osst.c --- linux-2.4.29/drivers/scsi/osst.c 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/osst.c 2005-03-18 18:07:24.794034144 +0000 @@ -5505,7 +5505,6 @@ static struct file_operations osst_fops read: osst_read, write: osst_write, ioctl: osst_ioctl, - llseek: no_llseek, open: os_scsi_tape_open, flush: os_scsi_tape_flush, release: os_scsi_tape_close, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_nv.c linux-2.4.30-rc1/drivers/scsi/sata_nv.c --- linux-2.4.29/drivers/scsi/sata_nv.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_nv.c 2005-03-18 18:08:24.615939832 +0000 @@ -20,6 +20,10 @@ * If you do not delete the provisions above, a recipient may use your * version of this file under either the OSL or the GPL. * + * 0.06 + * - Added generic SATA support by using a pci_device_id that filters on + * the IDE storage class code. + * * 0.03 * - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using * mmio_base, which is only set for the CK804/MCP04 case. @@ -44,7 +48,7 @@ #include #define DRV_NAME "sata_nv" -#define DRV_VERSION "0.5" +#define DRV_VERSION "0.6" #define NV_PORTS 2 #define NV_PIO_MASK 0x1f @@ -95,7 +99,8 @@ #define NV_MCP_SATA_CFG_20_SATA_SPACE_EN 0x04 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t nv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs); static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void nv_host_stop (struct ata_host_set *host_set); @@ -108,6 +113,7 @@ static void nv_check_hotplug_ck804(struc enum nv_host_type { + GENERIC, NFORCE2, NFORCE3, CK804 @@ -128,6 +134,9 @@ static struct pci_device_id nv_pci_tbl[] PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, + { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, { 0, } /* terminate list */ }; @@ -136,7 +145,6 @@ static struct pci_device_id nv_pci_tbl[] struct nv_host_desc { enum nv_host_type host_type; - unsigned long host_flags; void (*enable_hotplug)(struct ata_probe_ent *probe_ent); void (*disable_hotplug)(struct ata_host_set *host_set); void (*check_hotplug)(struct ata_host_set *host_set); @@ -144,21 +152,24 @@ struct nv_host_desc }; static struct nv_host_desc nv_device_tbl[] = { { + .host_type = GENERIC, + .enable_hotplug = NULL, + .disable_hotplug= NULL, + .check_hotplug = NULL, + }, + { .host_type = NFORCE2, - .host_flags = 0x00000000, .enable_hotplug = nv_enable_hotplug, .disable_hotplug= nv_disable_hotplug, .check_hotplug = nv_check_hotplug, }, { .host_type = NFORCE3, - .host_flags = 0x00000000, .enable_hotplug = nv_enable_hotplug, .disable_hotplug= nv_disable_hotplug, .check_hotplug = nv_check_hotplug, }, { .host_type = CK804, - .host_flags = NV_HOST_FLAGS_SCR_MMIO, .enable_hotplug = nv_enable_hotplug_ck804, .disable_hotplug= nv_disable_hotplug_ck804, .check_hotplug = nv_check_hotplug_ck804, @@ -168,6 +179,7 @@ static struct nv_host_desc nv_device_tbl struct nv_host { struct nv_host_desc *host_desc; + unsigned long host_flags; }; static struct pci_driver nv_pci_driver = { @@ -207,6 +219,8 @@ static struct ata_port_operations nv_ops .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, @@ -245,7 +259,8 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, nv_pci_tbl); MODULE_VERSION(DRV_VERSION); -irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t nv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host_set *host_set = dev_instance; struct nv_host *host = host_set->private_data; @@ -285,8 +300,8 @@ static u32 nv_scr_read (struct ata_port if (sc_reg > SCR_CONTROL) return 0xffffffffU; - if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) - return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) + return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4)); else return inl(ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -299,8 +314,8 @@ static void nv_scr_write (struct ata_por if (sc_reg > SCR_CONTROL) return; - if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) - writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) + writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4)); else outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -322,7 +337,16 @@ static int nv_init_one (struct pci_dev * struct nv_host *host; struct ata_port_info *ppi; struct ata_probe_ent *probe_ent; + int pci_dev_busy = 0; int rc; + u32 bar; + + // Make sure this is a SATA controller by counting the number of bars + // (NVIDIA SATA controllers will always have six bars). Otherwise, + // it's an IDE controller and we ignore it. + for (bar=0; bar<6; bar++) + if (pci_resource_start(pdev, bar) == 0) + return -ENODEV; if (!printed_version++) printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); @@ -332,8 +356,10 @@ static int nv_init_one (struct pci_dev * goto err_out; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out_disable; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -350,11 +376,15 @@ static int nv_init_one (struct pci_dev * if (!host) goto err_out_free_ent; + memset(host, 0, sizeof(struct nv_host)); host->host_desc = &nv_device_tbl[ent->driver_data]; probe_ent->private_data = host; - if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) { + if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM) + host->host_flags |= NV_HOST_FLAGS_SCR_MMIO; + + if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) { unsigned long base; probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5), @@ -395,7 +425,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out_disable: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); err_out: return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_promise.c linux-2.4.30-rc1/drivers/scsi/sata_promise.c --- linux-2.4.29/drivers/scsi/sata_promise.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_promise.c 2005-03-18 18:06:13.469877064 +0000 @@ -42,8 +42,6 @@ #define DRV_NAME "sata_promise" #define DRV_VERSION "1.01" -#define msleep libata_msleep /* 2.4-specific */ - enum { PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ @@ -158,10 +156,18 @@ static struct pci_device_id pdc_ata_pci_ board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, + { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_20319 }, + { } /* terminate list */ }; @@ -408,9 +414,11 @@ static irqreturn_t pdc_interrupt (int ir return IRQ_NONE; } - spin_lock(&host_set->lock); + spin_lock(&host_set->lock); + + writel(mask, mmio_base + PDC_INT_SEQMASK); - for (i = 0; i < host_set->n_ports; i++) { + for (i = 0; i < host_set->n_ports; i++) { VPRINTK("port %u\n", i); ap = host_set->ports[i]; tmp = mask & (1 << (i + 1)); @@ -548,6 +556,7 @@ static int pdc_ata_init_one (struct pci_ unsigned long base; void *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; + int pci_dev_busy = 0; int rc; if (!printed_version++) @@ -562,8 +571,10 @@ static int pdc_ata_init_one (struct pci_ return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -637,7 +648,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_qstor.c linux-2.4.30-rc1/drivers/scsi/sata_qstor.c --- linux-2.4.29/drivers/scsi/sata_qstor.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_qstor.c 2005-03-18 18:06:28.749554200 +0000 @@ -0,0 +1,717 @@ +/* + * sata_qstor.c - Pacific Digital Corporation QStor SATA + * + * Maintained by: Mark Lord + * + * Copyright 2005 Pacific Digital Corporation. + * (OSL/GPL code release authorized by Jalil Fadavi). + * + * The contents of this file are subject to the Open + * Software License version 1.1 that can be found at + * http://www.opensource.org/licenses/osl-1.1.txt and is included herein + * by reference. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License version 2 (the "GPL") as distributed + * in the kernel source COPYING file, in which case the provisions of + * the GPL are applicable instead of the above. If you wish to allow + * the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under + * the OSL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. + * If you do not delete the provisions above, a recipient may use your + * version of this file under either the OSL or the GPL. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include +#include +#include + +#define DRV_NAME "sata_qstor" +#define DRV_VERSION "0.04" + +enum { + QS_PORTS = 4, + QS_MAX_PRD = LIBATA_MAX_PRD, + QS_CPB_ORDER = 6, + QS_CPB_BYTES = (1 << QS_CPB_ORDER), + QS_PRD_BYTES = QS_MAX_PRD * 16, + QS_PKT_BYTES = QS_CPB_BYTES + QS_PRD_BYTES, + + QS_DMA_BOUNDARY = ~0UL, + + /* global register offsets */ + QS_HCF_CNFG3 = 0x0003, /* host configuration offset */ + QS_HID_HPHY = 0x0004, /* host physical interface info */ + QS_HCT_CTRL = 0x00e4, /* global interrupt mask offset */ + QS_HST_SFF = 0x0100, /* host status fifo offset */ + QS_HVS_SERD3 = 0x0393, /* PHY enable offset */ + + /* global control bits */ + QS_HPHY_64BIT = (1 << 1), /* 64-bit bus detected */ + QS_CNFG3_GSRST = 0x01, /* global chip reset */ + QS_SERD3_PHY_ENA = 0xf0, /* PHY detection ENAble*/ + + /* per-channel register offsets */ + QS_CCF_CPBA = 0x0710, /* chan CPB base address */ + QS_CCF_CSEP = 0x0718, /* chan CPB separation factor */ + QS_CFC_HUFT = 0x0800, /* host upstream fifo threshold */ + QS_CFC_HDFT = 0x0804, /* host downstream fifo threshold */ + QS_CFC_DUFT = 0x0808, /* dev upstream fifo threshold */ + QS_CFC_DDFT = 0x080c, /* dev downstream fifo threshold */ + QS_CCT_CTR0 = 0x0900, /* chan control-0 offset */ + QS_CCT_CTR1 = 0x0901, /* chan control-1 offset */ + QS_CCT_CFF = 0x0a00, /* chan command fifo offset */ + + /* channel control bits */ + QS_CTR0_REG = (1 << 1), /* register mode (vs. pkt mode) */ + QS_CTR0_CLER = (1 << 2), /* clear channel errors */ + QS_CTR1_RDEV = (1 << 1), /* sata phy/comms reset */ + QS_CTR1_RCHN = (1 << 4), /* reset channel logic */ + QS_CCF_RUN_PKT = 0x107, /* RUN a new dma PKT */ + + /* pkt sub-field headers */ + QS_HCB_HDR = 0x01, /* Host Control Block header */ + QS_DCB_HDR = 0x02, /* Device Control Block header */ + + /* pkt HCB flag bits */ + QS_HF_DIRO = (1 << 0), /* data DIRection Out */ + QS_HF_DAT = (1 << 3), /* DATa pkt */ + QS_HF_IEN = (1 << 4), /* Interrupt ENable */ + QS_HF_VLD = (1 << 5), /* VaLiD pkt */ + + /* pkt DCB flag bits */ + QS_DF_PORD = (1 << 2), /* Pio OR Dma */ + QS_DF_ELBA = (1 << 3), /* Extended LBA (lba48) */ + + /* PCI device IDs */ + board_2068_idx = 0, /* QStor 4-port SATA/RAID */ +}; + +typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t; + +struct qs_port_priv { + u8 *pkt; + dma_addr_t pkt_dma; + qs_state_t state; +}; + +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); +static irqreturn_t qs_intr (int irq, void *dev_instance, struct pt_regs *regs); +static int qs_port_start(struct ata_port *ap); +static void qs_host_stop(struct ata_host_set *host_set); +static void qs_port_stop(struct ata_port *ap); +static void qs_phy_reset(struct ata_port *ap); +static void qs_qc_prep(struct ata_queued_cmd *qc); +static int qs_qc_issue(struct ata_queued_cmd *qc); +static int qs_check_atapi_dma(struct ata_queued_cmd *qc); +static void qs_bmdma_stop(struct ata_port *ap); +static u8 qs_bmdma_status(struct ata_port *ap); +static void qs_irq_clear(struct ata_port *ap); +static void qs_eng_timeout(struct ata_port *ap); + +static Scsi_Host_Template qs_ata_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .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, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = QS_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .use_new_eh_code = ATA_SHT_NEW_EH_CODE, + .emulated = ATA_SHT_EMULATED, + //FIXME .use_clustering = ATA_SHT_USE_CLUSTERING, + .use_clustering = ENABLE_CLUSTERING, + .proc_name = DRV_NAME, + .bios_param = ata_std_bios_param, +}; + +static struct ata_port_operations qs_ata_ops = { + .port_disable = ata_port_disable, + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .check_atapi_dma = qs_check_atapi_dma, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + .phy_reset = qs_phy_reset, + .qc_prep = qs_qc_prep, + .qc_issue = qs_qc_issue, + .eng_timeout = qs_eng_timeout, + .irq_handler = qs_intr, + .irq_clear = qs_irq_clear, + .scr_read = qs_scr_read, + .scr_write = qs_scr_write, + .port_start = qs_port_start, + .port_stop = qs_port_stop, + .host_stop = qs_host_stop, + .bmdma_stop = qs_bmdma_stop, + .bmdma_status = qs_bmdma_status, +}; + +static struct ata_port_info qs_port_info[] = { + /* board_2068_idx */ + { + .sht = &qs_ata_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SATA_RESET | + //FIXME ATA_FLAG_SRST | + ATA_FLAG_MMIO, + .pio_mask = 0x10, /* pio4 */ + .udma_mask = 0x7f, /* udma0-6 */ + .port_ops = &qs_ata_ops, + }, +}; + +static struct pci_device_id qs_ata_pci_tbl[] = { + { PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2068_idx }, + + { } /* terminate list */ +}; + +static struct pci_driver qs_ata_pci_driver = { + .name = DRV_NAME, + .id_table = qs_ata_pci_tbl, + .probe = qs_ata_init_one, + .remove = ata_pci_remove_one, +}; + +static int qs_check_atapi_dma(struct ata_queued_cmd *qc) +{ + return 1; /* ATAPI DMA not supported */ +} + +static void qs_bmdma_stop(struct ata_port *ap) +{ + /* nothing */ +} + +static u8 qs_bmdma_status(struct ata_port *ap) +{ + return 0; +} + +static void qs_irq_clear(struct ata_port *ap) +{ + /* nothing */ +} + +static inline void qs_enter_reg_mode(struct ata_port *ap) +{ + u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000); + + writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); + readb(chan + QS_CCT_CTR0); /* flush */ +} + +static inline void qs_reset_channel_logic(struct ata_port *ap) +{ + u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000); + + writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1); + readb(chan + QS_CCT_CTR0); /* flush */ + qs_enter_reg_mode(ap); +} + +static void qs_phy_reset(struct ata_port *ap) +{ + struct qs_port_priv *pp = ap->private_data; + + pp->state = qs_state_idle; + qs_reset_channel_logic(ap); + sata_phy_reset(ap); +} + +static void qs_eng_timeout(struct ata_port *ap) +{ + struct qs_port_priv *pp = ap->private_data; + + if (pp->state != qs_state_idle) /* healthy paranoia */ + pp->state = qs_state_mmio; + qs_reset_channel_logic(ap); + ata_eng_timeout(ap); +} + +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) +{ + if (sc_reg > SCR_CONTROL) + return ~0U; + return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); +} + +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) +{ + if (sc_reg > SCR_CONTROL) + return; + writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); +} + +static void qs_fill_sg(struct ata_queued_cmd *qc) +{ + struct scatterlist *sg = qc->sg; + struct ata_port *ap = qc->ap; + struct qs_port_priv *pp = ap->private_data; + unsigned int nelem; + u8 *prd = pp->pkt + QS_CPB_BYTES; + + assert(sg != NULL); + assert(qc->n_elem > 0); + + for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { + u64 addr; + u32 len; + + addr = sg_dma_address(sg); + *(__le64 *)prd = cpu_to_le64(addr); + prd += sizeof(u64); + + len = sg_dma_len(sg); + *(__le32 *)prd = cpu_to_le32(len); + prd += sizeof(u64); + + VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem, + (unsigned long long)addr, len); + } +} + +static void qs_qc_prep(struct ata_queued_cmd *qc) +{ + struct qs_port_priv *pp = qc->ap->private_data; + u8 dflags = QS_DF_PORD, *buf = pp->pkt; + u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD; + u64 addr; + + VPRINTK("ENTER\n"); + + qs_enter_reg_mode(qc->ap); + if (qc->tf.protocol != ATA_PROT_DMA) { + ata_qc_prep(qc); + return; + } + + qs_fill_sg(qc); + + if ((qc->tf.flags & ATA_TFLAG_WRITE)) + hflags |= QS_HF_DIRO; + if ((qc->tf.flags & ATA_TFLAG_LBA48)) + dflags |= QS_DF_ELBA; + + /* host control block (HCB) */ + buf[ 0] = QS_HCB_HDR; + buf[ 1] = hflags; + *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); + *(__le32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem); + addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; + *(__le64 *)(&buf[16]) = cpu_to_le64(addr); + + /* device control block (DCB) */ + buf[24] = QS_DCB_HDR; + buf[28] = dflags; + + /* frame information structure (FIS) */ + ata_tf_to_fis(&qc->tf, &buf[32], 0); +} + +static inline void qs_packet_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000); + + VPRINTK("ENTER, ap %p\n", ap); + + writeb(QS_CTR0_CLER, chan + QS_CCT_CTR0); + wmb(); /* flush PRDs and pkt to memory */ + writel(QS_CCF_RUN_PKT, chan + QS_CCT_CFF); + readl(chan + QS_CCT_CFF); /* flush */ +} + +static int qs_qc_issue(struct ata_queued_cmd *qc) +{ + struct qs_port_priv *pp = qc->ap->private_data; + + switch (qc->tf.protocol) { + case ATA_PROT_DMA: + + pp->state = qs_state_pkt; + qs_packet_start(qc); + return 0; + + case ATA_PROT_ATAPI_DMA: + BUG(); + break; + + default: + break; + } + + pp->state = qs_state_mmio; + return ata_qc_issue_prot(qc); +} + +static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) +{ + unsigned int handled = 0; + u8 sFFE; + u8 __iomem *mmio_base = host_set->mmio_base; + + do { + u32 sff0 = readl(mmio_base + QS_HST_SFF); + u32 sff1 = readl(mmio_base + QS_HST_SFF + 4); + u8 sEVLD = (sff1 >> 30) & 0x01; /* valid flag */ + sFFE = sff1 >> 31; /* empty flag */ + + if (sEVLD) { + u8 sDST = sff0 >> 16; /* dev status */ + u8 sHST = sff1 & 0x3f; /* host status */ + unsigned int port_no = (sff1 >> 8) & 0x03; + struct ata_port *ap = host_set->ports[port_no]; + + DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", + sff1, sff0, port_no, sHST, sDST); + handled = 1; + if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { + struct ata_queued_cmd *qc; + struct qs_port_priv *pp = ap->private_data; + if (!pp || pp->state != qs_state_pkt) + continue; + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { + switch (sHST) { + case 0: /* sucessful CPB */ + case 3: /* device error */ + pp->state = qs_state_idle; + qs_enter_reg_mode(qc->ap); + ata_qc_complete(qc, sDST); + break; + default: + break; + } + } + } + } + } while (!sFFE); + return handled; +} + +static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) +{ + unsigned int handled = 0, port_no; + + for (port_no = 0; port_no < host_set->n_ports; ++port_no) { + struct ata_port *ap; + ap = host_set->ports[port_no]; + if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { + struct ata_queued_cmd *qc; + struct qs_port_priv *pp = ap->private_data; + if (!pp || pp->state != qs_state_mmio) + continue; + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { + + /* check main status, clearing INTRQ */ + u8 status = ata_chk_status(ap); + if ((status & ATA_BUSY)) + continue; + DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", + ap->id, qc->tf.protocol, status); + + /* complete taskfile transaction */ + pp->state = qs_state_idle; + ata_qc_complete(qc, status); + handled = 1; + } + } + } + return handled; +} + +static irqreturn_t qs_intr(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct ata_host_set *host_set = dev_instance; + unsigned int handled = 0; + + VPRINTK("ENTER\n"); + + spin_lock(&host_set->lock); + handled = qs_intr_pkt(host_set) | qs_intr_mmio(host_set); + spin_unlock(&host_set->lock); + + VPRINTK("EXIT\n"); + + return IRQ_RETVAL(handled); +} + +static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base) +{ + port->cmd_addr = + port->data_addr = base + 0x400; + port->error_addr = + port->feature_addr = base + 0x408; /* hob_feature = 0x409 */ + port->nsect_addr = base + 0x410; /* hob_nsect = 0x411 */ + port->lbal_addr = base + 0x418; /* hob_lbal = 0x419 */ + port->lbam_addr = base + 0x420; /* hob_lbam = 0x421 */ + port->lbah_addr = base + 0x428; /* hob_lbah = 0x429 */ + port->device_addr = base + 0x430; + port->status_addr = + port->command_addr = base + 0x438; + port->altstatus_addr = + port->ctl_addr = base + 0x440; + port->scr_addr = base + 0xc00; +} + +static int qs_port_start(struct ata_port *ap) +{ + struct device *dev = ap->host_set->dev; + struct qs_port_priv *pp; + void __iomem *mmio_base = ap->host_set->mmio_base; + void __iomem *chan = mmio_base + (ap->port_no * 0x4000); + u64 addr; + int rc; + + rc = ata_port_start(ap); + if (rc) + return rc; + qs_enter_reg_mode(ap); + pp = kcalloc(1, sizeof(*pp), GFP_KERNEL); + if (!pp) { + rc = -ENOMEM; + goto err_out; + } + pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, + GFP_KERNEL); + if (!pp->pkt) { + rc = -ENOMEM; + goto err_out_kfree; + } + memset(pp->pkt, 0, QS_PKT_BYTES); + ap->private_data = pp; + + addr = (u64)pp->pkt_dma; + writel((u32) addr, chan + QS_CCF_CPBA); + writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); + return 0; + +err_out_kfree: + kfree(pp); +err_out: + ata_port_stop(ap); + return rc; +} + +static void qs_port_stop(struct ata_port *ap) +{ + struct device *dev = ap->host_set->dev; + struct qs_port_priv *pp = ap->private_data; + + if (pp != NULL) { + ap->private_data = NULL; + if (pp->pkt != NULL) + dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt, + pp->pkt_dma); + kfree(pp); + } + ata_port_stop(ap); +} + +static void qs_host_stop(struct ata_host_set *host_set) +{ + void __iomem *mmio_base = host_set->mmio_base; + + writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ + writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ +} + +static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) +{ + void __iomem *mmio_base = pe->mmio_base; + unsigned int port_no; + + writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ + writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ + + /* reset each channel in turn */ + for (port_no = 0; port_no < pe->n_ports; ++port_no) { + u8 __iomem *chan = mmio_base + (port_no * 0x4000); + writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1); + writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); + readb(chan + QS_CCT_CTR0); /* flush */ + } + writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */ + + for (port_no = 0; port_no < pe->n_ports; ++port_no) { + u8 __iomem *chan = mmio_base + (port_no * 0x4000); + /* set FIFO depths to same settings as Windows driver */ + writew(32, chan + QS_CFC_HUFT); + writew(32, chan + QS_CFC_HDFT); + writew(10, chan + QS_CFC_DUFT); + writew( 8, chan + QS_CFC_DDFT); + /* set CPB size in bytes, as a power of two */ + writeb(QS_CPB_ORDER, chan + QS_CCF_CSEP); + } + writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */ +} + +/* + * The QStor understands 64-bit buses, and uses 64-bit fields + * for DMA pointers regardless of bus width. We just have to + * make sure our DMA masks are set appropriately for whatever + * bridge lies between us and the QStor, and then the DMA mapping + * code will ensure we only ever "see" appropriate buffer addresses. + * If we're 32-bit limited somewhere, then our 64-bit fields will + * just end up with zeros in the upper 32-bits, without any special + * logic required outside of this routine (below). + */ +static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) +{ + u32 bus_info = readl(mmio_base + QS_HID_HPHY); + int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT); + + if (have_64bit_bus && + !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { + /* do nothing */ + } else { + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + printk(KERN_ERR DRV_NAME + "(%s): 32-bit DMA enable failed\n", + pci_name(pdev)); + return rc; + } + } + return 0; +} + +static int qs_ata_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int printed_version; + struct ata_probe_ent *probe_ent = NULL; + void __iomem *mmio_base; + unsigned int board_idx = (unsigned int) ent->driver_data; + int rc, port_no; + + if (!printed_version++) + printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out; + + if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) { + rc = -ENODEV; + goto err_out_regions; + } + + mmio_base = ioremap(pci_resource_start(pdev, 4), + pci_resource_len(pdev, 4)); + if (mmio_base == NULL) { + rc = -ENOMEM; + goto err_out_regions; + } + + rc = qs_set_dma_masks(pdev, mmio_base); + if (rc) + goto err_out_iounmap; + + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); + if (probe_ent == NULL) { + rc = -ENOMEM; + goto err_out_iounmap; + } + + memset(probe_ent, 0, sizeof(*probe_ent)); + probe_ent->dev = pci_dev_to_dev(pdev); + INIT_LIST_HEAD(&probe_ent->node); + + probe_ent->sht = qs_port_info[board_idx].sht; + probe_ent->host_flags = qs_port_info[board_idx].host_flags; + probe_ent->pio_mask = qs_port_info[board_idx].pio_mask; + probe_ent->mwdma_mask = qs_port_info[board_idx].mwdma_mask; + probe_ent->udma_mask = qs_port_info[board_idx].udma_mask; + probe_ent->port_ops = qs_port_info[board_idx].port_ops; + + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->mmio_base = mmio_base; + probe_ent->n_ports = QS_PORTS; + + for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { + unsigned long chan = (unsigned long)mmio_base + + (port_no * 0x4000); + qs_ata_setup_port(&probe_ent->port[port_no], chan); + } + + pci_set_master(pdev); + + /* initialize adapter */ + qs_host_init(board_idx, probe_ent); + + ata_add_to_probe_list(probe_ent); + return 0; + +err_out_iounmap: + iounmap(mmio_base); +err_out_regions: + pci_release_regions(pdev); +err_out: + pci_disable_device(pdev); + return rc; +} + +static int __init qs_ata_init(void) +{ + int rc; + + rc = pci_module_init(&qs_ata_pci_driver); + if (rc) + return rc; + + rc = scsi_register_module(MODULE_SCSI_HA, &qs_ata_sht); + if (rc) { + rc = -ENODEV; + goto err_out; + } + + return 0; + +err_out: + pci_unregister_driver(&qs_ata_pci_driver); + return rc; +} + +static void __exit qs_ata_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &qs_ata_sht); + pci_unregister_driver(&qs_ata_pci_driver); +} + +MODULE_AUTHOR("Mark Lord"); +MODULE_DESCRIPTION("Pacific Digital Corporation QStor SATA low-level driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, qs_ata_pci_tbl); +MODULE_VERSION(DRV_VERSION); + +module_init(qs_ata_init); +module_exit(qs_ata_exit); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_sil.c linux-2.4.30-rc1/drivers/scsi/sata_sil.c --- linux-2.4.29/drivers/scsi/sata_sil.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_sil.c 2005-03-18 18:07:33.213754152 +0000 @@ -71,12 +71,14 @@ static struct pci_device_id sil_pci_tbl[ { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, + { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { } /* terminate list */ }; /* TODO firmware versions should be added - eric */ -struct sil_drivelist { +static const struct sil_drivelist { const char * product; unsigned int quirk; } sil_blacklist [] = { @@ -84,10 +86,12 @@ struct sil_drivelist { { "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE }, { "ST360015AS", SIL_QUIRK_MOD15WRITE }, + { "ST380013AS", SIL_QUIRK_MOD15WRITE }, { "ST380023AS", SIL_QUIRK_MOD15WRITE }, { "ST3120023AS", SIL_QUIRK_MOD15WRITE }, { "ST3160023AS", SIL_QUIRK_MOD15WRITE }, { "ST3120026AS", SIL_QUIRK_MOD15WRITE }, + { "ST3200822AS", SIL_QUIRK_MOD15WRITE }, { "ST340014ASL", SIL_QUIRK_MOD15WRITE }, { "ST360014ASL", SIL_QUIRK_MOD15WRITE }, { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, @@ -136,6 +140,8 @@ static struct ata_port_operations sil_op .post_set_mode = sil_post_set_mode, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, @@ -333,6 +339,7 @@ static int sil_init_one (struct pci_dev void *mmio_base; int rc; unsigned int i; + int pci_dev_busy = 0; u32 tmp, irq_mask; if (!printed_version++) @@ -347,8 +354,10 @@ static int sil_init_one (struct pci_dev return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -430,7 +439,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_sis.c linux-2.4.30-rc1/drivers/scsi/sata_sis.c --- linux-2.4.29/drivers/scsi/sata_sis.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_sis.c 2005-03-18 18:07:17.861088112 +0000 @@ -103,6 +103,8 @@ static struct ata_port_operations sis_op .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, @@ -201,14 +203,17 @@ static int sis_init_one (struct pci_dev int rc; u32 genctl; struct ata_port_info *ppi; + int pci_dev_busy = 0; rc = pci_enable_device(pdev); if (rc) return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -255,7 +260,8 @@ err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_svw.c linux-2.4.30-rc1/drivers/scsi/sata_svw.c --- linux-2.4.29/drivers/scsi/sata_svw.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_svw.c 2005-03-18 18:07:49.795233384 +0000 @@ -156,7 +156,7 @@ static void k2_sata_tf_read(struct ata_p * spin_lock_irqsave(host_set lock) */ -void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) +static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); @@ -186,7 +186,7 @@ void k2_bmdma_setup_mmio (struct ata_que * spin_lock_irqsave(host_set lock) */ -void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) +static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void *mmio = (void *) ap->ioaddr.bmdma_addr; @@ -302,6 +302,8 @@ static struct ata_port_operations k2_sat .phy_reset = sata_phy_reset, .bmdma_setup = k2_bmdma_setup_mmio, .bmdma_start = k2_bmdma_start_mmio, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, @@ -339,6 +341,7 @@ static int k2_sata_init_one (struct pci_ struct ata_probe_ent *probe_ent = NULL; unsigned long base; void *mmio_base; + int pci_dev_busy = 0; int rc; if (!printed_version++) @@ -360,8 +363,10 @@ static int k2_sata_init_one (struct pci_ /* Request PCI regions */ rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -429,7 +434,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_sx4.c linux-2.4.30-rc1/drivers/scsi/sata_sx4.c --- linux-2.4.29/drivers/scsi/sata_sx4.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_sx4.c 2005-03-18 18:07:24.262115008 +0000 @@ -1191,8 +1191,7 @@ static unsigned int pdc20621_prog_dimm_g error = 0; break; } - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((i * 100) * HZ / 1000 + 1); + msleep(i*100); } return error; } @@ -1225,8 +1224,7 @@ static unsigned int pdc20621_dimm_init(s readl(mmio + PDC_TIME_CONTROL); /* Wait 3 seconds */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(3 * HZ); + msleep(3000); /* When timer is enabled, counter is decreased every internal @@ -1369,6 +1367,7 @@ static int pdc_sata_init_one (struct pci void *mmio_base, *dimm_mmio = NULL; struct pdc_host_priv *hpriv = NULL; unsigned int board_idx = (unsigned int) ent->driver_data; + int pci_dev_busy = 0; int rc; if (!printed_version++) @@ -1383,8 +1382,10 @@ static int pdc_sata_init_one (struct pci return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -1469,7 +1470,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_uli.c linux-2.4.30-rc1/drivers/scsi/sata_uli.c --- linux-2.4.29/drivers/scsi/sata_uli.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_uli.c 2005-03-18 18:06:13.454879344 +0000 @@ -98,6 +98,8 @@ static struct ata_port_operations uli_op .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -186,14 +188,17 @@ static int uli_init_one (struct pci_dev struct ata_port_info *ppi; int rc; unsigned int board_idx = (unsigned int) ent->driver_data; + int pci_dev_busy = 0; rc = pci_enable_device(pdev); if (rc) return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) @@ -256,7 +261,8 @@ err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_via.c linux-2.4.30-rc1/drivers/scsi/sata_via.c --- linux-2.4.29/drivers/scsi/sata_via.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_via.c 2005-03-18 18:08:22.660237144 +0000 @@ -24,6 +24,11 @@ If you do not delete the provisions above, a recipient may use your version of this file under either the OSL or the GPL. + ---------------------------------------------------------------------- + + To-do list: + * VT6421 PATA support + */ #include @@ -38,11 +43,14 @@ #include #define DRV_NAME "sata_via" -#define DRV_VERSION "1.0" +#define DRV_VERSION "1.1" -enum { - via_sata = 0, +enum board_ids_enum { + vt6420, + vt6421, +}; +enum { SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ SATA_INT_GATE = 0x41, /* SATA interrupt gating */ SATA_NATIVE_MODE = 0x42, /* Native mode enable */ @@ -50,10 +58,8 @@ enum { PORT0 = (1 << 1), PORT1 = (1 << 0), - - ENAB_ALL = PORT0 | PORT1, - - INT_GATE_ALL = PORT0 | PORT1, + ALL_PORTS = PORT0 | PORT1, + N_PORTS = 2, NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), @@ -66,7 +72,8 @@ static u32 svia_scr_read (struct ata_por static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static struct pci_device_id svia_pci_tbl[] = { - { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, via_sata }, + { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, + { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 }, { } /* terminate list */ }; @@ -111,6 +118,9 @@ static struct ata_port_operations svia_s .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, + .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, @@ -159,18 +169,132 @@ static const unsigned int svia_bar_sizes 8, 4, 8, 4, 16, 256 }; +static const unsigned int vt6421_bar_sizes[] = { + 16, 16, 16, 16, 32, 128 +}; + static unsigned long svia_scr_addr(unsigned long addr, unsigned int port) { return addr + (port * 128); } +static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port) +{ + return addr + (port * 64); +} + +static void vt6421_init_addrs(struct ata_probe_ent *probe_ent, + struct pci_dev *pdev, + unsigned int port) +{ + unsigned long reg_addr = pci_resource_start(pdev, port); + unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8); + unsigned long scr_addr; + + probe_ent->port[port].cmd_addr = reg_addr; + probe_ent->port[port].altstatus_addr = + probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS; + probe_ent->port[port].bmdma_addr = bmdma_addr; + + scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port); + probe_ent->port[port].scr_addr = scr_addr; + + ata_std_ports(&probe_ent->port[port]); +} + +static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev) +{ + struct ata_probe_ent *probe_ent; + struct ata_port_info *ppi = &svia_port_info; + + probe_ent = ata_pci_init_native_mode(pdev, &ppi); + if (!probe_ent) + return NULL; + + probe_ent->port[0].scr_addr = + svia_scr_addr(pci_resource_start(pdev, 5), 0); + probe_ent->port[1].scr_addr = + svia_scr_addr(pci_resource_start(pdev, 5), 1); + + return probe_ent; +} + +static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev) +{ + struct ata_probe_ent *probe_ent; + unsigned int i; + + probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); + if (!probe_ent) + return NULL; + + memset(probe_ent, 0, sizeof(*probe_ent)); + probe_ent->dev = pci_dev_to_dev(pdev); + INIT_LIST_HEAD(&probe_ent->node); + + probe_ent->sht = &svia_sht; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY; + probe_ent->port_ops = &svia_sata_ops; + probe_ent->n_ports = N_PORTS; + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = SA_SHIRQ; + probe_ent->pio_mask = 0x1f; + probe_ent->mwdma_mask = 0x07; + probe_ent->udma_mask = 0x7f; + + for (i = 0; i < N_PORTS; i++) + vt6421_init_addrs(probe_ent, pdev, i); + + return probe_ent; +} + +static void svia_configure(struct pci_dev *pdev) +{ + u8 tmp8; + + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); + printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n", + pci_name(pdev), + (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); + + /* make sure SATA channels are enabled */ + pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n", + pci_name(pdev), (int) tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); + } + + /* make sure interrupts for each channel sent to us */ + pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n", + pci_name(pdev), (int) tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); + } + + /* make sure native mode is enabled */ + pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); + if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { + printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n", + pci_name(pdev), (int) tmp8); + tmp8 |= NATIVE_MODE_ALL; + pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); + } +} + static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; unsigned int i; int rc; - struct ata_port_info *ppi; struct ata_probe_ent *probe_ent; + int board_id = (int) ent->driver_data; + const int *bar_sizes; + int pci_dev_busy = 0; u8 tmp8; if (!printed_version++) @@ -181,20 +305,28 @@ static int svia_init_one (struct pci_dev return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } - pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); - if (tmp8 & SATA_2DEV) { - printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n", - pci_name(pdev), (int) tmp8); - rc = -EIO; - goto err_out_regions; + if (board_id == vt6420) { + pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); + if (tmp8 & SATA_2DEV) { + printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n", + pci_name(pdev), (int) tmp8); + rc = -EIO; + goto err_out_regions; + } + + bar_sizes = &svia_bar_sizes[0]; + } else { + bar_sizes = &vt6421_bar_sizes[0]; } for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) if ((pci_resource_start(pdev, i) == 0) || - (pci_resource_len(pdev, i) < svia_bar_sizes[i])) { + (pci_resource_len(pdev, i) < bar_sizes[i])) { printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n", pci_name(pdev), i, pci_resource_start(pdev, i), @@ -207,8 +339,11 @@ static int svia_init_one (struct pci_dev if (rc) goto err_out_regions; - ppi = &svia_port_info; - probe_ent = ata_pci_init_native_mode(pdev, &ppi); + if (board_id == vt6420) + probe_ent = vt6420_init_probe_ent(pdev); + else + probe_ent = vt6421_init_probe_ent(pdev); + if (!probe_ent) { printk(KERN_ERR DRV_NAME "(%s): out of memory\n", pci_name(pdev)); @@ -216,42 +351,7 @@ static int svia_init_one (struct pci_dev goto err_out_regions; } - probe_ent->port[0].scr_addr = - svia_scr_addr(pci_resource_start(pdev, 5), 0); - probe_ent->port[1].scr_addr = - svia_scr_addr(pci_resource_start(pdev, 5), 1); - - pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); - printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n", - pci_name(pdev), - (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); - - /* make sure SATA channels are enabled */ - pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); - if ((tmp8 & ENAB_ALL) != ENAB_ALL) { - printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n", - pci_name(pdev), (int) tmp8); - tmp8 |= ENAB_ALL; - pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); - } - - /* make sure interrupts for each channel sent to us */ - pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); - if ((tmp8 & INT_GATE_ALL) != INT_GATE_ALL) { - printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n", - pci_name(pdev), (int) tmp8); - tmp8 |= INT_GATE_ALL; - pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); - } - - /* make sure native mode is enabled */ - pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); - if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { - printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n", - pci_name(pdev), (int) tmp8); - tmp8 |= NATIVE_MODE_ALL; - pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); - } + svia_configure(pdev); pci_set_master(pdev); @@ -262,7 +362,8 @@ static int svia_init_one (struct pci_dev err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sata_vsc.c linux-2.4.30-rc1/drivers/scsi/sata_vsc.c --- linux-2.4.29/drivers/scsi/sata_vsc.c 2005-01-19 14:10:03.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sata_vsc.c 2005-03-18 18:07:39.192845192 +0000 @@ -155,7 +155,8 @@ static void vsc_sata_tf_read(struct ata_ * * Read the interrupt register and process for the devices that have them pending. */ -irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host_set *host_set = dev_instance; unsigned int i; @@ -218,6 +219,8 @@ static struct ata_port_operations vsc_sa .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, @@ -256,6 +259,7 @@ static int __devinit vsc_sata_init_one ( static int printed_version; struct ata_probe_ent *probe_ent = NULL; unsigned long base; + int pci_dev_busy = 0; void *mmio_base; int rc; @@ -275,13 +279,15 @@ static int __devinit vsc_sata_init_one ( } rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } /* * Use 32 bit DMA mask, because 64 bit address support is poor. */ - rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL); + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (rc) goto err_out_regions; @@ -348,7 +354,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sd.c linux-2.4.30-rc1/drivers/scsi/sd.c --- linux-2.4.29/drivers/scsi/sd.c 2003-08-25 11:44:42.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sd.c 2005-03-18 18:07:59.699727672 +0000 @@ -1220,7 +1220,7 @@ static int sd_init() goto cleanup_gendisks_part; memset(sd_gendisks[i].part, 0, (SCSI_DISKS_PER_MAJOR << 4) * sizeof(struct hd_struct)); sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4); - sd_gendisks[i].nr_real = 0; + sd_gendisks[i].nr_real = SCSI_DISKS_PER_MAJOR; sd_gendisks[i].real_devices = (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR); } @@ -1333,7 +1333,6 @@ static int sd_attach(Scsi_Device * SDp) rscsi_disks[i].device = SDp; rscsi_disks[i].has_part_table = 0; sd_template.nr_dev++; - SD_GENDISK(i).nr_real++; devnum = i % SCSI_DISKS_PER_MAJOR; SD_GENDISK(i).de_arr[devnum] = SDp->de; if (SDp->removable) @@ -1447,7 +1446,6 @@ static void sd_detach(Scsi_Device * SDp) SDp->attached--; sd_template.dev_noticed--; sd_template.nr_dev--; - SD_GENDISK(i).nr_real--; return; } return; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/st.c linux-2.4.30-rc1/drivers/scsi/st.c --- linux-2.4.29/drivers/scsi/st.c 2005-01-19 14:10:04.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/st.c 2005-03-18 18:07:47.570571584 +0000 @@ -1641,7 +1641,7 @@ static long read_tape(Scsi_Tape *STp, lo if (STps->drv_block >= 0) STps->drv_block += 1; (STp->buffer)->buffer_bytes = 0; - return (-EIO); + return (-ENOMEM); } (STp->buffer)->buffer_bytes = bytes - transfer; } else { @@ -3778,7 +3778,6 @@ static struct file_operations st_fops = read: st_read, write: st_write, ioctl: st_ioctl, - llseek: no_llseek, open: st_open, flush: st_flush, release: st_release, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/scsi/sym53c8xx.c linux-2.4.30-rc1/drivers/scsi/sym53c8xx.c --- linux-2.4.29/drivers/scsi/sym53c8xx.c 2004-04-14 13:05:32.000000000 +0000 +++ linux-2.4.30-rc1/drivers/scsi/sym53c8xx.c 2005-03-18 18:07:51.767933488 +0000 @@ -13182,7 +13182,7 @@ sym53c8xx_pci_init(Scsi_Host_Template *t ** descriptors. */ if (chip && (chip->features & FE_DAC)) { - if (pci_set_dma_mask(pdev, (u64) 0xffffffffff)) + if (pci_set_dma_mask(pdev, (u64) 0xffffffffffULL)) chip->features &= ~FE_DAC_IN_USE; else chip->features |= FE_DAC_IN_USE; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/devio.c linux-2.4.30-rc1/drivers/usb/devio.c --- linux-2.4.29/drivers/usb/devio.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/devio.c 2005-03-18 18:07:28.295501840 +0000 @@ -1132,6 +1132,8 @@ static int proc_ioctl (struct dev_state /* ifno might usefully be passed ... */ retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf); /* size = min_t(int, size, retval)? */ + if (retval == -ENOIOCTLCMD) + retval = -ENOTTY; } } @@ -1146,24 +1148,10 @@ static int proc_ioctl (struct dev_state return retval; } -static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int usbdev_ioctl_exclusive(struct dev_state *ps, struct inode *inode, + unsigned int cmd, unsigned long arg) { - struct dev_state *ps = (struct dev_state *)file->private_data; - int ret = -ENOIOCTLCMD; - - if (!(file->f_mode & FMODE_WRITE)) - return -EPERM; - down_read(&ps->devsem); - if (!ps->dev) { - up_read(&ps->devsem); - return -ENODEV; - } - - /* - * grab device's exclusive_access mutex to prevent its driver from - * using this device while it is being accessed by us. - */ - down(&ps->dev->exclusive_access); + int ret; switch (cmd) { case USBDEVFS_CONTROL: @@ -1194,14 +1182,6 @@ static int usbdev_ioctl(struct inode *in inode->i_mtime = CURRENT_TIME; break; - case USBDEVFS_GETDRIVER: - ret = proc_getdriver(ps, (void *)arg); - break; - - case USBDEVFS_CONNECTINFO: - ret = proc_connectinfo(ps, (void *)arg); - break; - case USBDEVFS_SETINTERFACE: ret = proc_setintf(ps, (void *)arg); break; @@ -1220,6 +1200,53 @@ static int usbdev_ioctl(struct inode *in ret = proc_unlinkurb(ps, (void *)arg); break; + case USBDEVFS_CLAIMINTERFACE: + ret = proc_claiminterface(ps, (void *)arg); + break; + + case USBDEVFS_RELEASEINTERFACE: + ret = proc_releaseinterface(ps, (void *)arg); + break; + + case USBDEVFS_IOCTL: + ret = proc_ioctl(ps, (void *) arg); + break; + + default: + ret = -ENOTTY; + } + return ret; +} + +static int usbdev_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct dev_state *ps = file->private_data; + int ret; + + if (!(file->f_mode & FMODE_WRITE)) + return -EPERM; + down_read(&ps->devsem); + if (!ps->dev) { + up_read(&ps->devsem); + return -ENODEV; + } + + /* + * Some ioctls don't touch the device and can be called without + * grabbing its exclusive_access mutex; they are handled in this + * switch. Other ioctls which need exclusive_access are handled in + * usbdev_ioctl_exclusive(). + */ + switch (cmd) { + case USBDEVFS_GETDRIVER: + ret = proc_getdriver(ps, (void *)arg); + break; + + case USBDEVFS_CONNECTINFO: + ret = proc_connectinfo(ps, (void *)arg); + break; + case USBDEVFS_REAPURB: ret = proc_reapurb(ps, (void *)arg); break; @@ -1232,19 +1259,28 @@ static int usbdev_ioctl(struct inode *in ret = proc_disconnectsignal(ps, (void *)arg); break; + case USBDEVFS_CONTROL: + case USBDEVFS_BULK: + case USBDEVFS_RESETEP: + case USBDEVFS_RESET: + case USBDEVFS_CLEAR_HALT: + case USBDEVFS_SETINTERFACE: + case USBDEVFS_SETCONFIGURATION: + case USBDEVFS_SUBMITURB: + case USBDEVFS_DISCARDURB: case USBDEVFS_CLAIMINTERFACE: - ret = proc_claiminterface(ps, (void *)arg); - break; - case USBDEVFS_RELEASEINTERFACE: - ret = proc_releaseinterface(ps, (void *)arg); - break; - case USBDEVFS_IOCTL: - ret = proc_ioctl(ps, (void *) arg); + ret = -ERESTARTSYS; + if (down_interruptible(&ps->dev->exclusive_access) == 0) { + ret = usbdev_ioctl_exclusive(ps, inode, cmd, arg); + up(&ps->dev->exclusive_access); + } break; + + default: + ret = -ENOTTY; } - up(&ps->dev->exclusive_access); up_read(&ps->devsem); if (ret >= 0) inode->i_atime = CURRENT_TIME; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/hid-core.c linux-2.4.30-rc1/drivers/usb/hid-core.c --- linux-2.4.29/drivers/usb/hid-core.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/hid-core.c 2005-03-18 18:07:39.210842456 +0000 @@ -1064,18 +1064,31 @@ static int hid_submit_out(struct hid_dev static void hid_ctrl(struct urb *urb) { struct hid_device *hid = urb->context; + unsigned long flags; if (urb->status) warn("ctrl urb status %d received", urb->status); + spin_lock_irqsave(&hid->outlock, flags); + hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - if (hid->outhead != hid->outtail) - hid_submit_out(hid); + if (hid->outhead != hid->outtail) { + if (hid_submit_out(hid)) { + clear_bit(HID_OUT_RUNNING, &hid->iofl); + } + spin_unlock_irqrestore(&hid->outlock, flags); + return; + } + + clear_bit(HID_OUT_RUNNING, &hid->iofl); + spin_unlock_irqrestore(&hid->outlock, flags); } void hid_write_report(struct hid_device *hid, struct hid_report *report) { + unsigned long flags; + if (hid->report_enum[report->type].numbered) { hid->out[hid->outhead].buffer[0] = report->id; hid_output_report(report, hid->out[hid->outhead].buffer + 1); @@ -1087,13 +1100,18 @@ void hid_write_report(struct hid_device hid->out[hid->outhead].dr.wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); + spin_lock_irqsave(&hid->outlock, flags); + hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1); if (hid->outhead == hid->outtail) hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - if (hid->urbout.status != -EINPROGRESS) - hid_submit_out(hid); + if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) + if (hid_submit_out(hid)) + clear_bit(HID_OUT_RUNNING, &hid->iofl); + + spin_unlock_irqrestore(&hid->outlock, flags); } int hid_open(struct hid_device *hid) @@ -1333,6 +1351,8 @@ static struct hid_device *usb_hid_config return NULL; } + spin_lock_init(&hid->outlock); + hid->version = hdesc->bcdHID; hid->country = hdesc->bCountryCode; hid->dev = dev; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/hid.h linux-2.4.30-rc1/drivers/usb/hid.h --- linux-2.4.29/drivers/usb/hid.h 2003-08-25 11:44:42.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/hid.h 2005-03-18 18:06:12.715991672 +0000 @@ -302,6 +302,8 @@ struct hid_control_fifo { #define HID_CLAIMED_INPUT 1 #define HID_CLAIMED_HIDDEV 2 +#define HID_OUT_RUNNING 2 + struct hid_input { struct list_head list; struct hid_report *report; @@ -322,12 +324,15 @@ struct hid_device { /* device repo struct usb_device *dev; /* USB device */ int ifnum; /* USB interface number */ + unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ + struct urb urb; /* USB URB structure */ char buffer[HID_BUFFER_SIZE]; /* Rx buffer */ struct urb urbout; /* Output URB */ struct hid_control_fifo out[HID_CONTROL_FIFO_SIZE]; /* Transmit buffer */ unsigned char outhead, outtail; /* Tx buffer head & tail */ + spinlock_t outlock; /* Output fifo spinlock */ unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/hiddev.c linux-2.4.30-rc1/drivers/usb/hiddev.c --- linux-2.4.29/drivers/usb/hiddev.c 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/hiddev.c 2005-03-18 18:07:15.174496536 +0000 @@ -328,6 +328,7 @@ static ssize_t hiddev_read(struct file * } schedule(); + set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/serial/ftdi_sio.c linux-2.4.30-rc1/drivers/usb/serial/ftdi_sio.c --- linux-2.4.29/drivers/usb/serial/ftdi_sio.c 2005-01-19 14:10:07.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/serial/ftdi_sio.c 2005-03-18 18:08:05.333871152 +0000 @@ -737,8 +737,6 @@ static struct usb_serial_device_type ftd }; - - static struct usb_serial_device_type ftdi_userdev_device = { .owner = THIS_MODULE, .name = "FTDI SIO compatible", @@ -1240,15 +1238,6 @@ static int ftdi_HE_TIRA1_startup (struct } /* ftdi_HE_TIRA1_startup */ -/* ftdi_shutdown is called from usbserial:usb_serial_disconnect - * it is called when the usb device is disconnected - * - * usbserial:usb_serial_disconnect - * calls __serial_close for each open of the port - * shutdown is called then (ie ftdi_shutdown) - */ - - /* Startup for the 8U232AM chip */ static int ftdi_userdev_startup (struct usb_serial *serial) { @@ -1273,6 +1262,14 @@ static int ftdi_userdev_startup (struct } +/* ftdi_shutdown is called from usbserial:usb_serial_disconnect + * it is called when the usb device is disconnected + * + * usbserial:usb_serial_disconnect + * calls __serial_close for each open of the port + * shutdown is called then (ie ftdi_shutdown) + */ + static void ftdi_shutdown (struct usb_serial *serial) { /* ftdi_shutdown */ @@ -1382,6 +1379,7 @@ static void ftdi_close (struct usb_seria struct usb_serial *serial; unsigned int c_cflag = port->tty->termios->c_cflag; char buf[1]; + int err; dbg("%s", __FUNCTION__); @@ -1412,8 +1410,9 @@ static void ftdi_close (struct usb_seria /* shutdown our bulk read */ if (port->read_urb) { - if(usb_unlink_urb (port->read_urb)<0) - err("Error unlinking urb"); + err = usb_unlink_urb (port->read_urb); + if (err < 0 && err != -ENODEV) + err("Error unlinking urb (%d)", err); } /* unlink the running write urbs */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/serial/mct_u232.c linux-2.4.30-rc1/drivers/usb/serial/mct_u232.c --- linux-2.4.29/drivers/usb/serial/mct_u232.c 2005-01-19 14:10:08.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/serial/mct_u232.c 2005-03-18 18:07:50.052194320 +0000 @@ -86,26 +86,14 @@ #include "usb-serial.h" #include "mct_u232.h" - /* * Version Information */ -#define DRIVER_VERSION "v1.2" +#define DRIVER_VERSION "z2.0" /* Linux in-kernel version */ #define DRIVER_AUTHOR "Wolfgang Grandegger " #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" /* - * Some not properly written applications do not handle the return code of - * write() correctly. This can result in character losses. A work-a-round - * can be compiled in with the following definition. This work-a-round - * should _NOT_ be part of an 'official' kernel release, of course! - */ -#undef FIX_WRITE_RETURN_CODE_PROBLEM -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM -static int write_blocking; /* disabled by default */ -#endif - -/* * Function prototypes */ static int mct_u232_startup (struct usb_serial *serial); @@ -114,13 +102,6 @@ static int mct_u232_open (stru struct file *filp); static void mct_u232_close (struct usb_serial_port *port, struct file *filp); -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM -static int mct_u232_write (struct usb_serial_port *port, - int from_user, - const unsigned char *buf, - int count); -static void mct_u232_write_bulk_callback (struct urb *urb); -#endif static void mct_u232_read_int_callback (struct urb *urb); static void mct_u232_set_termios (struct usb_serial_port *port, struct termios * old); @@ -147,7 +128,7 @@ MODULE_DEVICE_TABLE (usb, id_table_combi static struct usb_serial_device_type mct_u232_device = { .owner = THIS_MODULE, - .name = "Magic Control Technology USB-RS232", + .name = "MCT U232", .id_table = id_table_combined, .num_interrupt_in = 2, .num_bulk_in = 0, @@ -155,10 +136,6 @@ static struct usb_serial_device_type mct .num_ports = 1, .open = mct_u232_open, .close = mct_u232_close, -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM - .write = mct_u232_write, - .write_bulk_callback = mct_u232_write_bulk_callback, -#endif .read_int_callback = mct_u232_read_int_callback, .ioctl = mct_u232_ioctl, .set_termios = mct_u232_set_termios, @@ -167,9 +144,14 @@ static struct usb_serial_device_type mct .shutdown = mct_u232_shutdown, }; +struct mct_u232_interval_kludge { + int ecnt; /* Error counter */ + int ibase; /* Initial interval value */ +}; struct mct_u232_private { spinlock_t lock; + struct mct_u232_interval_kludge ik[2]; unsigned int control_state; /* Modem Line Setting (TIOCM) */ unsigned char last_lcr; /* Line Control Register */ unsigned char last_lsr; /* Line Status Register */ @@ -359,17 +341,13 @@ static int mct_u232_startup (struct usb_ struct mct_u232_private *priv; struct usb_serial_port *port, *rport; - /* allocate the private data structure */ priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL); if (!priv) return -ENOMEM; - /* set initial values for control structures */ + memset(priv, 0, sizeof(struct mct_u232_private)); spin_lock_init(&priv->lock); - priv->control_state = 0; - priv->last_lsr = 0; - priv->last_msr = 0; serial->port->private = priv; - + init_waitqueue_head(&serial->port->write_wait); /* Puh, that's dirty */ @@ -383,20 +361,27 @@ static int mct_u232_startup (struct usb_ rport->interrupt_in_urb = NULL; port->read_urb->context = port; + priv->ik[0].ibase = port->read_urb->interval; + priv->ik[1].ibase = port->interrupt_in_urb->interval; + return (0); } /* mct_u232_startup */ static void mct_u232_shutdown (struct usb_serial *serial) { + struct mct_u232_private *priv; int i; dbg("%s", __FUNCTION__); for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ - if (serial->port[i].private) - kfree(serial->port[i].private); + priv = serial->port[i].private; + if (priv) { + serial->port[i].private = NULL; + kfree(priv); + } } } /* mct_u232_shutdown */ @@ -448,16 +433,20 @@ static int mct_u232_open (struct usb_se spin_unlock_irqrestore(&priv->lock, flags); port->read_urb->dev = port->serial->dev; + port->read_urb->interval = priv->ik[0].ibase; retval = usb_submit_urb(port->read_urb); if (retval) { - err("usb_submit_urb(read bulk) failed"); + err("usb_submit_urb(read bulk) failed pipe 0x%x err %d", + port->read_urb->pipe, retval); goto exit; } port->interrupt_in_urb->dev = port->serial->dev; + port->interrupt_in_urb->interval = priv->ik[1].ibase; retval = usb_submit_urb(port->interrupt_in_urb); if (retval) - err(" usb_submit_urb(read int) failed"); + err(" usb_submit_urb(read int) failed pipe 0x%x err %d", + port->interrupt_in_urb->pipe, retval); exit: return 0; @@ -476,109 +465,22 @@ static void mct_u232_close (struct usb_s } } /* mct_u232_close */ - -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM -/* The generic routines work fine otherwise */ - -static int mct_u232_write (struct usb_serial_port *port, int from_user, - const unsigned char *buf, int count) +static void mct_u232_error_step (struct urb *urb, + struct mct_u232_private *priv, int n) { - struct usb_serial *serial = port->serial; - int result, bytes_sent, size; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); - return (0); - } - - /* only do something if we have a bulk out endpoint */ - if (!serial->num_bulk_out) - return(0);; - - /* another write is still pending? */ - if (port->write_urb->status == -EINPROGRESS) { - dbg("%s - already writing", __FUNCTION__); - return (0); - } - - bytes_sent = 0; - while (count > 0) { - size = (count > port->bulk_out_size) ? port->bulk_out_size : count; - - usb_serial_debug_data (__FILE__, __FUNCTION__, size, buf); - - if (from_user) { - if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) { - return -EFAULT; - } - } - else { - memcpy (port->write_urb->transfer_buffer, buf, size); - } - - /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, size, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - mct_u232_write_bulk_callback), - port); - - /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb); - if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); - return result; - } - - bytes_sent += size; - if (write_blocking) - interruptible_sleep_on(&port->write_wait); - else - break; - - buf += size; - count -= size; - } - - return bytes_sent; -} /* mct_u232_write */ - -static void mct_u232_write_bulk_callback (struct urb *urb) -{ - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct usb_serial *serial = port->serial; - struct tty_struct *tty = port->tty; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if (!serial) { - dbg("%s - bad serial pointer, exiting", __FUNCTION__); - return; - } + struct mct_u232_interval_kludge *ikp = &priv->ik[n]; - if (urb->status) { - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, - urb->status); - return; - } - - if (write_blocking) { - wake_up_interruptible(&port->write_wait); - tty_wakeup(tty); + if (ikp->ecnt >= 2) { + if (urb->interval) + err("%s - too many errors: " + "status %d pipe 0x%x interval %d", + __FUNCTION__, + urb->status, urb->pipe, urb->interval); + urb->interval = 0; } else { - /* from generic_write_bulk_callback */ - queue_task(&port->tqueue, &tq_immediate); - mark_bh(IMMEDIATE_BH); + ++ikp->ecnt; } - - return; -} /* mct_u232_write_bulk_callback */ -#endif +} static void mct_u232_read_int_callback (struct urb *urb) { @@ -589,21 +491,37 @@ static void mct_u232_read_int_callback ( unsigned char *data = urb->transfer_buffer; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); - /* The urb might have been killed. */ if (urb->status) { - dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, - urb->status); + dbg("%s - nonzero status %d, pipe 0x%x flags 0x%x interval %d", + __FUNCTION__, + urb->status, urb->pipe, urb->transfer_flags, urb->interval); + /* + * The bad stuff happens when a device is disconnected. + * This can cause us to spin while trying to resubmit. + * Unfortunately, in kernel 2.4 error codes are wildly + * different between controllers, so the status is useless. + * Instead we just refuse to spin too much. + */ + if (urb == port->read_urb) + mct_u232_error_step(urb, priv, 0); + if (urb == port->interrupt_in_urb) + mct_u232_error_step(urb, priv, 1); return; } if (!serial) { dbg("%s - bad serial pointer, exiting", __FUNCTION__); return; } - + + dbg("%s - port %d", __FUNCTION__, port->number); usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data); + if (urb == port->read_urb) + priv->ik[0].ecnt = 0; + if (urb == port->interrupt_in_urb) + priv->ik[1].ecnt = 0; + /* * Work-a-round: handle the 'usual' bulk-in pipe here */ @@ -660,7 +578,6 @@ static void mct_u232_read_int_callback ( /* INT urbs are automatically re-submitted */ } /* mct_u232_read_int_callback */ - static void mct_u232_set_termios (struct usb_serial_port *port, struct termios *old_termios) { @@ -781,6 +698,21 @@ static void mct_u232_break_ctl( struct u } /* mct_u232_break_ctl */ +static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file) +{ + struct mct_u232_private *priv = (struct mct_u232_private *)port->private; + unsigned int control_state; + unsigned long flags; + + dbg("%s", __FUNCTION__); + + spin_lock_irqsave(&priv->lock, flags); + control_state = priv->control_state; + spin_unlock_irqrestore(&priv->lock, flags); + + return control_state; +} + static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) { @@ -794,8 +726,8 @@ static int mct_u232_ioctl (struct usb_se /* Based on code from acm.c and others */ switch (cmd) { case TIOCMGET: - return put_user(priv->control_state, (unsigned long *) arg); - break; + mask = mct_u232_tiocmget(port, file); + return put_user(mask, (unsigned long *) arg); case TIOCMSET: /* Turns on and off the lines as specified by the mask */ case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */ @@ -865,12 +797,5 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); -#ifdef FIX_WRITE_RETURN_CODE_PROBLEM -MODULE_PARM(write_blocking, "i"); -MODULE_PARM_DESC(write_blocking, - "The write function will block to write out all data"); -#endif - MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/storage/transport.c linux-2.4.30-rc1/drivers/usb/storage/transport.c --- linux-2.4.29/drivers/usb/storage/transport.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/storage/transport.c 2005-03-18 18:07:11.209099368 +0000 @@ -1181,6 +1181,13 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *s /* if the command transfered well, then we go to the data stage */ if (result == 0) { + + /* Genesys Logic interface chips need a 100us delay between + * the command phase and the data phase. Some systems need + * even more, probably because of clock rate inaccuracies. */ + if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS) + udelay(110); + /* send/receive data payload, if there is any */ if (bcb->DataTransferLength) { usb_stor_transfer(srb, us); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/storage/usb.c linux-2.4.30-rc1/drivers/usb/storage/usb.c --- linux-2.4.29/drivers/usb/storage/usb.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/storage/usb.c 2005-03-18 18:06:47.319731104 +0000 @@ -996,6 +996,15 @@ static void * storage_probe(struct usb_d */ ss->htmplt.proc_dir = (void *)ss; + /* According to the technical support people at Genesys Logic, + * devices using their chips have problems transferring more + * than 32 KB at a time. In practice people have found that + * 64 KB works okay and that's what Windows does. But we'll + * be conservative. + */ + if (ss->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS) + ss->htmplt.max_sectors = 64; + /* Just before we start our control thread, initialize * the device if it needs initialization */ if (unusual_dev && unusual_dev->initFunction) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/drivers/usb/storage/usb.h linux-2.4.30-rc1/drivers/usb/storage/usb.h --- linux-2.4.29/drivers/usb/storage/usb.h 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/drivers/usb/storage/usb.h 2005-03-18 18:07:48.101490872 +0000 @@ -193,4 +193,7 @@ extern struct usb_driver usb_storage_dri /* Function to fill an inquiry response. See usb.c for details */ extern void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len); + +/* Vendor ID list for devices that require special handling */ +#define USB_VENDOR_ID_GENESYS 0x05e3 /* Genesys Logic */ #endif diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/ext3/fsync.c linux-2.4.30-rc1/fs/ext3/fsync.c --- linux-2.4.29/fs/ext3/fsync.c 2002-11-28 23:53:15.000000000 +0000 +++ linux-2.4.30-rc1/fs/ext3/fsync.c 2005-03-18 18:08:26.919589624 +0000 @@ -69,7 +69,7 @@ int ext3_sync_file(struct file * file, s if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) ret |= fsync_inode_data_buffers(inode); - ext3_force_commit(inode->i_sb); + ret |= ext3_force_commit(inode->i_sb); return ret; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/ext3/super.c linux-2.4.30-rc1/fs/ext3/super.c --- linux-2.4.29/fs/ext3/super.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/fs/ext3/super.c 2005-03-18 18:08:17.034092448 +0000 @@ -1608,12 +1608,13 @@ void ext3_write_super (struct super_bloc static int ext3_sync_fs(struct super_block *sb) { + int err; tid_t target; sb->s_dirt = 0; target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - log_wait_commit(EXT3_SB(sb)->s_journal, target); - return 0; + err = log_wait_commit(EXT3_SB(sb)->s_journal, target); + return err; } /* diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/file_table.c linux-2.4.30-rc1/fs/file_table.c --- linux-2.4.29/fs/file_table.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/fs/file_table.c 2005-03-18 18:06:22.988430024 +0000 @@ -46,6 +46,7 @@ struct file * get_empty_filp(void) f->f_version = ++event; f->f_uid = current->fsuid; f->f_gid = current->fsgid; + f->f_maxcount = INT_MAX; list_add(&f->f_list, &anon_list); file_list_unlock(); return f; @@ -91,6 +92,8 @@ int init_private_file(struct file *filp, filp->f_uid = current->fsuid; filp->f_gid = current->fsgid; filp->f_op = dentry->d_inode->i_fop; + filp->f_maxcount = INT_MAX; + if (filp->f_op->open) return filp->f_op->open(dentry->d_inode, filp); else diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jbd/commit.c linux-2.4.30-rc1/fs/jbd/commit.c --- linux-2.4.29/fs/jbd/commit.c 2004-02-18 13:36:31.000000000 +0000 +++ linux-2.4.30-rc1/fs/jbd/commit.c 2005-03-18 18:08:14.268512880 +0000 @@ -92,7 +92,7 @@ void journal_commit_transaction(journal_ struct buffer_head *wbuf[64]; int bufs; int flags; - int err; + int err = 0; unsigned long blocknr; char *tagp = NULL; journal_header_t *header; @@ -299,6 +299,8 @@ write_out_data_locked: spin_unlock(&journal_datalist_lock); unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; /* the journal_head may have been removed now */ lock_journal(journal); goto write_out_data; @@ -326,6 +328,8 @@ sync_datalist_empty: spin_unlock(&journal_datalist_lock); unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; lock_journal(journal); spin_lock(&journal_datalist_lock); continue; /* List may have changed */ @@ -351,6 +355,9 @@ sync_datalist_empty: } spin_unlock(&journal_datalist_lock); + if (err) + __journal_abort_hard(journal); + /* * If we found any dirty or locked buffers, then we should have * looped back up to the write_out_data label. If there weren't @@ -541,6 +548,8 @@ start_journal_io: if (buffer_locked(bh)) { unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; lock_journal(journal); goto wait_for_iobuf; } @@ -602,6 +611,8 @@ start_journal_io: if (buffer_locked(bh)) { unlock_journal(journal); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; lock_journal(journal); goto wait_for_ctlbuf; } @@ -650,6 +661,8 @@ start_journal_io: bh->b_end_io = journal_end_buffer_io_sync; submit_bh(WRITE, bh); wait_on_buffer(bh); + if (unlikely(!buffer_uptodate(bh))) + err = -EIO; put_bh(bh); /* One for getblk() */ journal_unlock_journal_head(descriptor); } @@ -661,6 +674,9 @@ start_journal_io: skip_commit: /* The journal should be unlocked by now. */ + if (err) + __journal_abort_hard(journal); + /* Call any callbacks that had been registered for handles in this * transaction. It is up to the callback to free any allocated * memory. diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jbd/journal.c linux-2.4.30-rc1/fs/jbd/journal.c --- linux-2.4.29/fs/jbd/journal.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/fs/jbd/journal.c 2005-03-18 18:06:36.940309016 +0000 @@ -582,8 +582,10 @@ out: * Wait for a specified commit to complete. * The caller may not hold the journal lock. */ -void log_wait_commit (journal_t *journal, tid_t tid) +int log_wait_commit (journal_t *journal, tid_t tid) { + int err = 0; + lock_kernel(); #ifdef CONFIG_JBD_DEBUG lock_journal(journal); @@ -600,6 +602,12 @@ void log_wait_commit (journal_t *journal sleep_on(&journal->j_wait_done_commit); } unlock_kernel(); + + if (unlikely(is_journal_aborted(journal))) { + printk(KERN_EMERG "journal commit I/O error\n"); + err = -EIO; + } + return err; } /* @@ -1326,7 +1334,7 @@ int journal_flush (journal_t *journal) /* Wait for the log commit to complete... */ if (transaction) - log_wait_commit(journal, transaction->t_tid); + err = log_wait_commit(journal, transaction->t_tid); /* ...and flush everything in the log out to disk. */ lock_journal(journal); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jbd/transaction.c linux-2.4.30-rc1/fs/jbd/transaction.c --- linux-2.4.29/fs/jbd/transaction.c 2004-08-07 23:26:05.000000000 +0000 +++ linux-2.4.30-rc1/fs/jbd/transaction.c 2005-03-18 18:06:59.966808456 +0000 @@ -1484,7 +1484,7 @@ int journal_stop(handle_t *handle) * to wait for the commit to complete. */ if (handle->h_sync && !(current->flags & PF_MEMALLOC)) - log_wait_commit(journal, tid); + err = log_wait_commit(journal, tid); } kfree(handle); return err; @@ -1509,7 +1509,7 @@ int journal_force_commit(journal_t *jour goto out; } handle->h_sync = 1; - journal_stop(handle); + ret = journal_stop(handle); out: unlock_kernel(); return ret; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/jfs_defragfs.h linux-2.4.30-rc1/fs/jfs/jfs_defragfs.h --- linux-2.4.29/fs/jfs/jfs_defragfs.h 2002-11-28 23:53:15.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/jfs_defragfs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2000-2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _H_JFS_DEFRAGFS -#define _H_JFS_DEFRAGFS - -/* - * defragfs parameter list - */ -struct defragfs { - uint flag; /* 4: */ - u8 dev; /* 1: */ - u8 pad[3]; /* 3: */ - s32 fileset; /* 4: */ - u32 inostamp; /* 4: */ - u32 ino; /* 4: */ - u32 gen; /* 4: */ - s64 xoff; /* 8: */ - s64 old_xaddr; /* 8: */ - s64 new_xaddr; /* 8: */ - s32 xlen; /* 4: */ -}; - -/* plist flag */ -#define DEFRAGFS_SYNC 0x80000000 -#define DEFRAGFS_COMMIT 0x40000000 -#define DEFRAGFS_RELOCATE 0x10000000 - -#define INODE_TYPE 0x0000F000 /* IFREG or IFDIR */ - -#define EXTENT_TYPE 0x000000ff -#define DTPAGE 0x00000001 -#define XTPAGE 0x00000002 -#define DATAEXT 0x00000004 -#define EAEXT 0x00000008 - -#endif /* _H_JFS_DEFRAGFS */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/jfs_imap.c linux-2.4.30-rc1/fs/jfs/jfs_imap.c --- linux-2.4.29/fs/jfs/jfs_imap.c 2005-01-19 14:10:10.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/jfs_imap.c 2005-03-18 18:07:23.951162280 +0000 @@ -486,7 +486,6 @@ struct inode *diReadSpecial(struct super /* read the page of fixed disk inode (AIT) in raw mode */ mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); if (mp == NULL) { - ip->i_sb = NULL; ip->i_nlink = 1; /* Don't want iput() deleting it */ iput(ip); return (NULL); @@ -499,7 +498,6 @@ struct inode *diReadSpecial(struct super /* copy on-disk inode to in-memory inode */ if ((copy_from_dinode(dp, ip)) != 0) { /* handle bad return by returning NULL for ip */ - ip->i_sb = NULL; ip->i_nlink = 1; /* Don't want iput() deleting it */ iput(ip); /* release the page */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/jfs_metapage.c linux-2.4.30-rc1/fs/jfs/jfs_metapage.c --- linux-2.4.29/fs/jfs/jfs_metapage.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/jfs_metapage.c 2005-03-18 18:07:54.873461376 +0000 @@ -298,14 +298,14 @@ again: mp = search_hash(hash_ptr, mapping, lblock); if (mp) { page_found: - mp->count++; - lock_metapage(mp); - spin_unlock(&meta_lock); if (test_bit(META_stale, &mp->flag)) { - release_metapage(mp); - yield(); /* Let other waiters release it, too */ + spin_unlock(&meta_lock); + yield(); goto again; } + mp->count++; + lock_metapage(mp); + spin_unlock(&meta_lock); if (test_bit(META_discard, &mp->flag)) { if (!new) { jfs_error(inode->i_sb, @@ -518,7 +518,6 @@ void release_metapage(struct metapage * } if (mp->page) { - /* Releasing spinlock, we have to check mp->count later */ set_bit(META_stale, &mp->flag); spin_unlock(&meta_lock); kunmap(mp->page); @@ -555,12 +554,6 @@ void release_metapage(struct metapage * list_del(&mp->synclist); LOGSYNC_UNLOCK(log); } - if (mp->count) { - /* Someone else is trying to get this metpage */ - unlock_metapage(mp); - spin_unlock(&meta_lock); - return; - } remove_from_hash(mp, meta_hash(mp->mapping, mp->index)); spin_unlock(&meta_lock); @@ -589,12 +582,8 @@ again: mp = search_hash(hash_ptr, mapping, lblock); if (mp) { if (test_bit(META_stale, &mp->flag)) { - /* Racing with release_metapage */ - mp->count++; - lock_metapage(mp); spin_unlock(&meta_lock); - /* racing release_metapage should be done now */ - release_metapage(mp); + yield(); goto again; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/jfs_unicode.c linux-2.4.30-rc1/fs/jfs/jfs_unicode.c --- linux-2.4.29/fs/jfs/jfs_unicode.c 2004-04-14 13:05:40.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/jfs_unicode.c 2005-03-18 18:07:48.865374744 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 + * Copyright (C) International Business Machines Corp., 2000-2005 * * 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 @@ -18,7 +18,7 @@ #include #include -#include "jfs_types.h" +#include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_unicode.h" #include "jfs_debug.h" @@ -34,17 +34,40 @@ int jfs_strfromUCS_le(char *to, const wc { int i; int outlen = 0; + static int warn_again = 5; /* Only warn up to 5 times total */ + int warn = !!warn_again; /* once per string */ - for (i = 0; (i < len) && from[i]; i++) { - int charlen; - charlen = - codepage->uni2char(le16_to_cpu(from[i]), &to[outlen], - NLS_MAX_CHARSET_SIZE); - if (charlen > 0) { - outlen += charlen; - } else { - to[outlen++] = '?'; + if (codepage) { + for (i = 0; (i < len) && from[i]; i++) { + int charlen; + charlen = + codepage->uni2char(le16_to_cpu(from[i]), + &to[outlen], + NLS_MAX_CHARSET_SIZE); + if (charlen > 0) + outlen += charlen; + else + to[outlen++] = '?'; } + } else { + for (i = 0; (i < len) && from[i]; i++) { + if (le16_to_cpu(from[i]) & 0xff00) { + if (warn) { + warn--; + warn_again--; + printk(KERN_ERR + "non-latin1 character 0x%x found in JFS file name\n", + le16_to_cpu(from[i])); + printk(KERN_ERR + "mount with iocharset=utf8 to access\n"); + } + to[i] = '?'; + } + else + to[i] = (char) (le16_to_cpu(from[i])); + } + outlen = i; + } to[outlen] = 0; return outlen; @@ -56,20 +79,27 @@ int jfs_strfromUCS_le(char *to, const wc * FUNCTION: Convert character string to unicode string * */ -static int jfs_strtoUCS(wchar_t * to, const char *from, int len, +static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len, struct nls_table *codepage) { int charlen; int i; - for (i = 0; len && *from; i++, from += charlen, len -= charlen) { - charlen = codepage->char2uni(from, len, &to[i]); - if (charlen < 1) { - jfs_err("jfs_strtoUCS: char2uni returned %d.", charlen); - jfs_err("charset = %s, char = 0x%x", - codepage->charset, (unsigned char) *from); - return charlen; + if (codepage) { + for (i = 0; len && *from; i++, from += charlen, len -= charlen) + { + charlen = codepage->char2uni(from, len, &to[i]); + if (charlen < 1) { + jfs_err("jfs_strtoUCS: char2uni returned %d.", + charlen); + jfs_err("charset = %s, char = 0x%x", + codepage->charset, *from); + return charlen; + } } + } else { + for (i = 0; (i < len) && from[i]; i++) + to[i] = (wchar_t) from[i]; } to[i] = 0; @@ -82,9 +112,9 @@ static int jfs_strtoUCS(wchar_t * to, co * FUNCTION: Allocate and translate to unicode string * */ -int get_UCSname(struct component_name * uniName, struct dentry *dentry, - struct nls_table *nls_tab) +int get_UCSname(struct component_name * uniName, struct dentry *dentry) { + struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab; int length = dentry->d_name.len; if (length > JFS_NAME_MAX) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/jfs_unicode.h linux-2.4.30-rc1/fs/jfs/jfs_unicode.h --- linux-2.4.29/fs/jfs/jfs_unicode.h 2002-11-28 23:53:15.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/jfs_unicode.h 2005-03-18 18:07:49.230319264 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * 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 @@ -30,8 +30,7 @@ typedef struct { extern signed char UniUpperTable[512]; extern UNICASERANGE UniUpperRange[]; -extern int get_UCSname(struct component_name *, struct dentry *, - struct nls_table *); +extern int get_UCSname(struct component_name *, struct dentry *); extern int jfs_strfromUCS_le(char *, const wchar_t *, int, struct nls_table *); #define free_UCSname(COMP) kfree((COMP)->name) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/namei.c linux-2.4.30-rc1/fs/jfs/namei.c --- linux-2.4.29/fs/jfs/namei.c 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/namei.c 2005-03-18 18:06:36.444384408 +0000 @@ -74,7 +74,7 @@ static int jfs_create(struct inode *dip, * search parent directory for entry/freespace * (dtSearch() returns parent directory page pinned) */ - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out1; /* @@ -195,7 +195,7 @@ static int jfs_mkdir(struct inode *dip, * search parent directory for entry/freespace * (dtSearch() returns parent directory page pinned) */ - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out1; /* @@ -318,9 +318,8 @@ static int jfs_rmdir(struct inode *dip, goto out; } - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) { + if ((rc = get_UCSname(&dname, dentry))) goto out; - } tid = txBegin(dip->i_sb, 0); @@ -437,7 +436,7 @@ static int jfs_unlink(struct inode *dip, jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out; IWRITE_LOCK(ip); @@ -780,7 +779,7 @@ static int jfs_link(struct dentry *old_d /* * scan parent directory for entry/freespace */ - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(ip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out; if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) @@ -865,7 +864,7 @@ static int jfs_symlink(struct inode *dip * (dtSearch() returns parent directory page pinned) */ - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out1; /* @@ -1044,12 +1043,10 @@ static int jfs_rename(struct inode *old_ old_ip = old_dentry->d_inode; new_ip = new_dentry->d_inode; - if ((rc = get_UCSname(&old_dname, old_dentry, - JFS_SBI(old_dir->i_sb)->nls_tab))) + if ((rc = get_UCSname(&old_dname, old_dentry))) goto out1; - if ((rc = get_UCSname(&new_dname, new_dentry, - JFS_SBI(old_dir->i_sb)->nls_tab))) + if ((rc = get_UCSname(&new_dname, new_dentry))) goto out2; /* @@ -1301,7 +1298,7 @@ static int jfs_mknod(struct inode *dir, jfs_info("jfs_mknod: %s", dentry->d_name.name); - if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) + if ((rc = get_UCSname(&dname, dentry))) goto out; ip = ialloc(dir, mode); @@ -1376,8 +1373,7 @@ static struct dentry *jfs_lookup(struct else if (strcmp(name, "..") == 0) inum = PARENT(dip); else { - if ((rc = - get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab))) + if ((rc = get_UCSname(&key, dentry))) return ERR_PTR(rc); rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP); free_UCSname(&key); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/jfs/super.c linux-2.4.30-rc1/fs/jfs/super.c --- linux-2.4.29/fs/jfs/super.c 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/fs/jfs/super.c 2005-03-18 18:08:35.043354624 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) International Business Machines Corp., 2000-2003 + * Copyright (C) International Business Machines Corp., 2000-2005 * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * This program is free software; you can redistribute it and/or modify @@ -155,8 +155,10 @@ static void jfs_put_super(struct super_b rc = jfs_umount(sb); if (rc) jfs_err("jfs_umount failed with return code %d", rc); - unload_nls(sbi->nls_tab); - sbi->nls_tab = NULL; + if (sbi->nls_tab) { + unload_nls(sbi->nls_tab); + sbi->nls_tab = NULL; + } kfree(sbi); } @@ -182,7 +184,7 @@ s64 jfs_get_volume_size(struct super_blo static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, int *flag) { - void *nls_map = NULL; + void *nls_map = (void *)-1; /* -1: no change; NULL: none */ char *this_char; char *value; struct jfs_sb_info *sbi = JFS_SBI(sb); @@ -222,13 +224,12 @@ static int parse_options(char *options, } else if (!strcmp(this_char, "iocharset")) { if (!value || !*value) goto needs_arg; - if (nls_map) /* specified iocharset twice! */ + if (nls_map && nls_map != (void *) -1) unload_nls(nls_map); - nls_map = load_nls(value); - if (!nls_map) { - printk(KERN_ERR "JFS: charset not found\n"); - goto cleanup; - } + if (!strcmp(value, "none")) + nls_map = NULL; + else + nls_map = load_nls(value); } else if (!strcmp(this_char, "resize")) { if (!value || !*value) { *newLVSize = jfs_get_volume_size(sb); @@ -250,9 +251,9 @@ static int parse_options(char *options, goto cleanup; } } - if (nls_map) { + if (nls_map != (void *) -1) { /* Discard old (if remount) */ - if (sbi->nls_tab) + if (sbi->nls_tab && sbi->nls_tab != (void *) -1) unload_nls(sbi->nls_tab); sbi->nls_tab = nls_map; } @@ -260,7 +261,7 @@ static int parse_options(char *options, needs_arg: printk(KERN_ERR "JFS: %s needs an argument\n", this_char); cleanup: - if (nls_map) + if (nls_map && nls_map != (void *) -1) unload_nls(nls_map); return 0; } @@ -328,6 +329,8 @@ static struct super_block *jfs_read_supe /* initialize the mount flag and determine the default error handler */ flag = JFS_ERR_REMOUNT_RO; + /* nls_tab will be set to NULL if no character mapping is requested */ + sbi->nls_tab = (void *) -1; if (!parse_options((char *) data, sb, &newLVSize, &flag)) { kfree(sbi); return NULL; @@ -378,7 +381,7 @@ static struct super_block *jfs_read_supe if (!sb->s_root) goto out_no_root; - if (!sbi->nls_tab) + if (sbi->nls_tab == (void *) -1) sbi->nls_tab = load_nls_default(); /* logical blocks are represented by 40 bits in pxd_t, etc. */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/nfsd/vfs.c linux-2.4.30-rc1/fs/nfsd/vfs.c --- linux-2.4.29/fs/nfsd/vfs.c 2004-11-17 11:54:21.000000000 +0000 +++ linux-2.4.30-rc1/fs/nfsd/vfs.c 2005-03-18 18:07:11.707023672 +0000 @@ -466,6 +466,8 @@ nfsd_open(struct svc_rqst *rqstp, struct atomic_set(&filp->f_count, 1); filp->f_dentry = dentry; filp->f_vfsmnt = fhp->fh_export->ex_mnt; + filp->f_maxcount = INT_MAX; + if (access & MAY_WRITE) { filp->f_flags = O_WRONLY|O_LARGEFILE; filp->f_mode = FMODE_WRITE; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/proc/kcore.c linux-2.4.30-rc1/fs/proc/kcore.c --- linux-2.4.29/fs/proc/kcore.c 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/fs/proc/kcore.c 2005-03-18 18:07:34.735522808 +0000 @@ -136,7 +136,10 @@ static unsigned long get_kcore_size(int } *elf_buflen = sizeof(struct elfhdr) + (*num_vma + 2)*sizeof(struct elf_phdr) + - 3 * sizeof(struct memelfnote); + 3 * (sizeof(struct elf_note) + 4) + + sizeof(struct elf_prstatus) + + sizeof(struct elf_prpsinfo) + + sizeof(struct task_struct); *elf_buflen = PAGE_ALIGN(*elf_buflen); return (size - PAGE_OFFSET + *elf_buflen); } @@ -279,7 +282,7 @@ static void elf_kcore_store_hdr(char *bu memset(&prstatus, 0, sizeof(struct elf_prstatus)); - nhdr->p_filesz = notesize(¬es[0]); + nhdr->p_filesz += notesize(¬es[0]); bufp = storenote(¬es[0], bufp); /* set up the process info */ @@ -296,7 +299,7 @@ static void elf_kcore_store_hdr(char *bu strcpy(prpsinfo.pr_fname, "vmlinux"); strncpy(prpsinfo.pr_psargs, saved_command_line, ELF_PRARGSZ); - nhdr->p_filesz = notesize(¬es[1]); + nhdr->p_filesz += notesize(¬es[1]); bufp = storenote(¬es[1], bufp); /* set up the task structure */ @@ -305,7 +308,7 @@ static void elf_kcore_store_hdr(char *bu notes[2].datasz = sizeof(struct task_struct); notes[2].data = current; - nhdr->p_filesz = notesize(¬es[2]); + nhdr->p_filesz += notesize(¬es[2]); bufp = storenote(¬es[2], bufp); } /* end elf_kcore_store_hdr() */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/proc/proc_tty.c linux-2.4.30-rc1/fs/proc/proc_tty.c --- linux-2.4.29/fs/proc/proc_tty.c 2005-01-19 14:10:11.000000000 +0000 +++ linux-2.4.30-rc1/fs/proc/proc_tty.c 2005-03-18 18:07:08.712478912 +0000 @@ -129,7 +129,7 @@ static int tty_ldiscs_read_proc(char *pa } /* - * Thsi function is called by register_tty_driver() to handle + * This function is called by tty_register_driver() to handle * registering the driver's /proc handler into /proc/tty/driver/ */ void proc_tty_register_driver(struct tty_driver *driver) @@ -152,7 +152,7 @@ void proc_tty_register_driver(struct tty } /* - * This function is called by unregister_tty_driver() + * This function is called by tty_unregister_driver() */ void proc_tty_unregister_driver(struct tty_driver *driver) { diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/fs/read_write.c linux-2.4.30-rc1/fs/read_write.c --- linux-2.4.29/fs/read_write.c 2003-08-25 11:44:43.000000000 +0000 +++ linux-2.4.30-rc1/fs/read_write.c 2005-03-18 18:07:44.945970584 +0000 @@ -40,6 +40,28 @@ ssize_t generic_read_dir(struct file *fi return -EISDIR; } +int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) +{ + struct inode *inode; + loff_t pos; + + if (unlikely(count > file->f_maxcount)) + goto Einval; + + pos = *ppos; + + if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) + goto Einval; + + inode = file->f_dentry->d_inode; + if (inode->i_flock && MANDATORY_LOCK(inode)) + return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, *ppos, count); + return 0; + +Einval: + return -EINVAL; +} + loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) { long long retval; @@ -168,8 +190,8 @@ asmlinkage ssize_t sys_read(unsigned int file = fget(fd); if (file) { if (file->f_mode & FMODE_READ) { - ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, - file, file->f_pos, count); + ret = rw_verify_area(READ, file, &file->f_pos, count); + if (!ret) { ssize_t (*read)(struct file *, char *, size_t, loff_t *); ret = -EINVAL; @@ -193,9 +215,7 @@ asmlinkage ssize_t sys_write(unsigned in file = fget(fd); if (file) { if (file->f_mode & FMODE_WRITE) { - struct inode *inode = file->f_dentry->d_inode; - ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, - file->f_pos, count); + ret = rw_verify_area(WRITE, file, &file->f_pos, count); if (!ret) { ssize_t (*write)(struct file *, const char *, size_t, loff_t *); ret = -EINVAL; @@ -224,7 +244,6 @@ static ssize_t do_readv_writev(int type, ssize_t ret, i; io_fn_t fn; iov_fn_t fnv; - struct inode *inode; /* * First get the "struct iovec" from user memory and @@ -275,12 +294,11 @@ static ssize_t do_readv_writev(int type, goto out; } - inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ - ret = locks_verify_area((type == VERIFY_WRITE - ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), - inode, file, file->f_pos, tot_len); - if (ret) goto out; + ret = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), + file, &file->f_pos, tot_len); + if (ret) + goto out; fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev); if (fnv) { @@ -383,8 +401,8 @@ asmlinkage ssize_t sys_pread(unsigned in goto bad_file; if (!(file->f_mode & FMODE_READ)) goto out; - ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, - file, pos, count); + ret = rw_verify_area(READ, file, &pos, count); + if (ret) goto out; ret = -EINVAL; @@ -414,8 +432,8 @@ asmlinkage ssize_t sys_pwrite(unsigned i goto bad_file; if (!(file->f_mode & FMODE_WRITE)) goto out; - ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode, - file, pos, count); + ret = rw_verify_area(WRITE, file, &pos, count); + if (ret) goto out; ret = -EINVAL; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-i386/acpi.h linux-2.4.30-rc1/include/asm-i386/acpi.h --- linux-2.4.29/include/asm-i386/acpi.h 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-i386/acpi.h 2005-03-18 18:06:25.626029048 +0000 @@ -28,6 +28,8 @@ #ifdef __KERNEL__ +#include + #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -121,6 +123,8 @@ extern int acpi_ioapic; extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; +extern int acpi_skip_timer_override; +void __init check_acpi_pci(void); static inline void disable_acpi(void) { acpi_disabled = 1; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-i386/pci-direct.h linux-2.4.30-rc1/include/asm-i386/pci-direct.h --- linux-2.4.29/include/asm-i386/pci-direct.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-i386/pci-direct.h 2005-03-18 18:07:32.059929560 +0000 @@ -0,0 +1 @@ +#include "asm-x86_64/pci-direct.h" diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-ppc/processor.h linux-2.4.30-rc1/include/asm-ppc/processor.h --- linux-2.4.29/include/asm-ppc/processor.h 2004-04-14 13:05:40.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-ppc/processor.h 2005-03-18 18:06:14.301750600 +0000 @@ -678,7 +678,7 @@ #define PVR_440GP_RC2 0x40200481 #define PVR_440GX_RA 0x51b21850 #define PVR_440GX_RB 0x51b21851 -#define PVR_440GX_RB1 0x51b21852 +#define PVR_440GX_RC 0x51b21892 #define PVR_601 0x00010000 #define PVR_602 0x00050000 #define PVR_603 0x00030000 diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc/asi.h linux-2.4.30-rc1/include/asm-sparc/asi.h --- linux-2.4.29/include/asm-sparc/asi.h 1998-04-15 00:44:23.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc/asi.h 2005-03-18 18:07:21.722501088 +0000 @@ -104,7 +104,8 @@ #define ASI_M_DCDR 0x39 /* Data Cache Diagnostics Register rw, ss */ #define ASI_M_VIKING_TMP1 0x40 /* Emulation temporary 1 on Viking */ -#define ASI_M_VIKING_TMP2 0x41 /* Emulation temporary 2 on Viking */ +/* only available on SuperSparc I */ +/* #define ASI_M_VIKING_TMP2 0x41 */ /* Emulation temporary 2 on Viking */ #define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc/oplib.h linux-2.4.30-rc1/include/asm-sparc/oplib.h --- linux-2.4.29/include/asm-sparc/oplib.h 2004-02-18 13:36:32.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc/oplib.h 2005-03-18 18:08:24.215000784 +0000 @@ -296,6 +296,9 @@ extern int prom_inst2pkg(int); /* Dorking with Bus ranges... */ +extern void prom_adjust_ranges(struct linux_prom_ranges *, int, + struct linux_prom_ranges *, int); + /* Apply promlib probes OBIO ranges to registers. */ extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc/system.h linux-2.4.30-rc1/include/asm-sparc/system.h --- linux-2.4.29/include/asm-sparc/system.h 2004-02-18 13:36:32.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc/system.h 2005-03-18 18:07:53.908608056 +0000 @@ -295,11 +295,11 @@ extern void __global_restore_flags(unsig #define wmb() mb() #define set_mb(__var, __value) do { __var = __value; mb(); } while(0) #define set_wmb(__var, __value) set_mb(__var, __value) -#define smp_mb() __asm__ __volatile__("":::"memory"); -#define smp_rmb() __asm__ __volatile__("":::"memory"); -#define smp_wmb() __asm__ __volatile__("":::"memory"); +#define smp_mb() __asm__ __volatile__("":::"memory") +#define smp_rmb() __asm__ __volatile__("":::"memory") +#define smp_wmb() __asm__ __volatile__("":::"memory") -#define nop() __asm__ __volatile__ ("nop"); +#define nop() __asm__ __volatile__ ("nop") /* This has special calling conventions */ #ifndef CONFIG_SMP diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc/winmacro.h linux-2.4.30-rc1/include/asm-sparc/winmacro.h --- linux-2.4.29/include/asm-sparc/winmacro.h 2003-06-13 14:51:38.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc/winmacro.h 2005-03-18 18:07:13.403765728 +0000 @@ -113,9 +113,12 @@ and %idreg, 0xc, %idreg; \ ld [%idreg + %dest_reg], %dest_reg; -/* Sliiick. We have a Linux current register :) -jj */ -#define LOAD_CURRENT4D(dest_reg) \ - lda [%g0] ASI_M_VIKING_TMP2, %dest_reg; +#define LOAD_CURRENT4D(dest_reg, idreg) \ + lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ + sethi %hi(C_LABEL(current_set)), %dest_reg; \ + sll %idreg, 2, %idreg; \ + or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ + ld [%idreg + %dest_reg], %dest_reg; /* Blackbox - take care with this... - check smp4m and smp4d before changing this. */ #define LOAD_CURRENT(dest_reg, idreg) \ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc64/atomic.h linux-2.4.30-rc1/include/asm-sparc64/atomic.h --- linux-2.4.29/include/asm-sparc64/atomic.h 2001-07-20 01:11:13.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc64/atomic.h 2005-03-18 18:08:20.009640096 +0000 @@ -8,31 +8,59 @@ #ifndef __ARCH_SPARC64_ATOMIC__ #define __ARCH_SPARC64_ATOMIC__ +#include + typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } #define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) -extern int __atomic_add(int, atomic_t *); -extern int __atomic_sub(int, atomic_t *); +extern void atomic_add(int, atomic_t *); +extern void atomic_sub(int, atomic_t *); + +extern int atomic_add_ret(int, atomic_t *); +extern int atomic_sub_ret(int, atomic_t *); + +#define atomic_dec_return(v) atomic_sub_ret(1, v) + +#define atomic_inc_return(v) atomic_add_ret(1, v) + +#define atomic_sub_return(i, v) atomic_sub_ret(i, v) + +#define atomic_add_return(i, v) atomic_add_ret(i, v) + +/* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) + +#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0) -#define atomic_add(i, v) ((void)__atomic_add(i, v)) -#define atomic_sub(i, v) ((void)__atomic_sub(i, v)) +#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0) -#define atomic_dec_return(v) __atomic_sub(1, v) -#define atomic_inc_return(v) __atomic_add(1, v) +#define atomic_inc(v) atomic_add(1, v) -#define atomic_sub_and_test(i, v) (__atomic_sub(i, v) == 0) -#define atomic_dec_and_test(v) (__atomic_sub(1, v) == 0) +#define atomic_dec(v) atomic_sub(1, v) -#define atomic_inc(v) ((void)__atomic_add(1, v)) -#define atomic_dec(v) ((void)__atomic_sub(1, v)) +#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0) /* Atomic operations are already serializing */ +#ifdef CONFIG_SMP +#define smp_mb__before_atomic_dec() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_atomic_dec() membar("#StoreLoad | #StoreStore") +#define smp_mb__before_atomic_inc() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_atomic_inc() membar("#StoreLoad | #StoreStore") +#else #define smp_mb__before_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier() #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() +#endif #endif /* !(__ARCH_SPARC64_ATOMIC__) */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc64/bitops.h linux-2.4.30-rc1/include/asm-sparc64/bitops.h --- linux-2.4.29/include/asm-sparc64/bitops.h 2001-12-21 17:42:03.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc64/bitops.h 2005-03-18 18:06:36.457382432 +0000 @@ -1,4 +1,4 @@ -/* $Id: bitops.h,v 1.38 2001/11/19 18:36:34 davem Exp $ +/* $Id: bitops.h,v 1.39 2002/01/30 01:40:00 davem Exp $ * bitops.h: Bit string operations on the V9. * * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -7,114 +7,126 @@ #ifndef _SPARC64_BITOPS_H #define _SPARC64_BITOPS_H +#include +#include #include -extern long ___test_and_set_bit(unsigned long nr, volatile void *addr); -extern long ___test_and_clear_bit(unsigned long nr, volatile void *addr); -extern long ___test_and_change_bit(unsigned long nr, volatile void *addr); - -#define test_and_set_bit(nr,addr) ({___test_and_set_bit(nr,addr)!=0;}) -#define test_and_clear_bit(nr,addr) ({___test_and_clear_bit(nr,addr)!=0;}) -#define test_and_change_bit(nr,addr) ({___test_and_change_bit(nr,addr)!=0;}) -#define set_bit(nr,addr) ((void)___test_and_set_bit(nr,addr)) -#define clear_bit(nr,addr) ((void)___test_and_clear_bit(nr,addr)) -#define change_bit(nr,addr) ((void)___test_and_change_bit(nr,addr)) +extern int test_and_set_bit(unsigned long nr, volatile void *addr); +extern int test_and_clear_bit(unsigned long nr, volatile void *addr); +extern int test_and_change_bit(unsigned long nr, volatile void *addr); +extern void set_bit(unsigned long nr, volatile void *addr); +extern void clear_bit(unsigned long nr, volatile void *addr); +extern void change_bit(unsigned long nr, volatile void *addr); /* "non-atomic" versions... */ -#define __set_bit(X,Y) \ -do { unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - *__m |= (1UL << (__nr & 63)); \ -} while (0) -#define __clear_bit(X,Y) \ -do { unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - *__m &= ~(1UL << (__nr & 63)); \ -} while (0) -#define __change_bit(X,Y) \ -do { unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - *__m ^= (1UL << (__nr & 63)); \ -} while (0) -#define __test_and_set_bit(X,Y) \ -({ unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - long __old = *__m; \ - long __mask = (1UL << (__nr & 63)); \ - *__m = (__old | __mask); \ - ((__old & __mask) != 0); \ -}) -#define __test_and_clear_bit(X,Y) \ -({ unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - long __old = *__m; \ - long __mask = (1UL << (__nr & 63)); \ - *__m = (__old & ~__mask); \ - ((__old & __mask) != 0); \ -}) -#define __test_and_change_bit(X,Y) \ -({ unsigned long __nr = (X); \ - long *__m = ((long *) (Y)) + (__nr >> 6); \ - long __old = *__m; \ - long __mask = (1UL << (__nr & 63)); \ - *__m = (__old ^ __mask); \ - ((__old & __mask) != 0); \ -}) -#define smp_mb__before_clear_bit() do { } while(0) -#define smp_mb__after_clear_bit() do { } while(0) +static __inline__ void __set_bit(int nr, volatile void *addr) +{ + unsigned long *m; + + m = ((unsigned long *)addr) + (nr >> 6); + *m |= (1UL << (nr & 63)); +} + +static __inline__ void __clear_bit(int nr, volatile void *addr) +{ + unsigned long *m; + + m = ((unsigned long *)addr) + (nr >> 6); + *m &= ~(1UL << (nr & 63)); +} -extern __inline__ int test_bit(int nr, __const__ void *addr) +static __inline__ void __change_bit(int nr, volatile void *addr) { - return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63))) != 0UL; + unsigned long *m; + + m = ((unsigned long *)addr) + (nr >> 6); + *m ^= (1UL << (nr & 63)); +} + +static __inline__ int __test_and_set_bit(int nr, volatile void *addr) +{ + unsigned long *m = ((unsigned long *)addr) + (nr >> 6); + unsigned long old = *m; + unsigned long mask = (1UL << (nr & 63)); + + *m = (old | mask); + return ((old & mask) != 0); +} + +static __inline__ int __test_and_clear_bit(int nr, volatile void *addr) +{ + unsigned long *m = ((unsigned long *)addr) + (nr >> 6); + unsigned long old = *m; + unsigned long mask = (1UL << (nr & 63)); + + *m = (old & ~mask); + return ((old & mask) != 0); +} + +static __inline__ int __test_and_change_bit(int nr, volatile void *addr) +{ + unsigned long *m = ((unsigned long *)addr) + (nr >> 6); + unsigned long old = *m; + unsigned long mask = (1UL << (nr & 63)); + + *m = (old ^ mask); + return ((old & mask) != 0); +} + +#ifdef CONFIG_SMP +#define smp_mb__before_clear_bit() membar("#StoreLoad | #LoadLoad") +#define smp_mb__after_clear_bit() membar("#StoreLoad | #StoreStore") +#else +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() +#endif + +static __inline__ int test_bit(int nr, __const__ volatile void *_addr) +{ + __const__ unsigned long *addr; + + addr = (__const__ unsigned long *) _addr; + + return (1UL & ((addr)[nr >> 6] >> (nr & 63))) != 0UL; } /* The easy/cheese version for now. */ -extern __inline__ unsigned long ffz(unsigned long word) +static __inline__ unsigned long ffz(unsigned long word) { unsigned long result; -#ifdef ULTRA_HAS_POPULATION_COUNT /* Thanks for nothing Sun... */ - __asm__ __volatile__( -" brz,pn %0, 1f\n" -" neg %0, %%g1\n" -" xnor %0, %%g1, %%g2\n" -" popc %%g2, %0\n" -"1: " : "=&r" (result) - : "0" (word) - : "g1", "g2"); -#else -#if 1 /* def EASY_CHEESE_VERSION */ result = 0; while(word & 1) { result++; word >>= 1; } -#else - unsigned long tmp; + return result; +} - result = 0; - tmp = ~word & -~word; - if (!(unsigned)tmp) { - tmp >>= 32; - result = 32; - } - if (!(unsigned short)tmp) { - tmp >>= 16; - result += 16; - } - if (!(unsigned char)tmp) { - tmp >>= 8; - result += 8; +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static __inline__ unsigned long __ffs(unsigned long word) +{ + unsigned long result = 0; + + while (!(word & 1UL)) { + result++; + word >>= 1; } - if (tmp & 0xf0) result += 4; - if (tmp & 0xcc) result += 2; - if (tmp & 0xaa) result ++; -#endif -#endif return result; } +/* + * fls: find last bit set. + */ + +#define fls(x) generic_fls(x) + #ifdef __KERNEL__ /* @@ -122,8 +134,12 @@ extern __inline__ unsigned long ffz(unsi * the libc and compiler builtin ffs routines, therefore * differs in spirit from the above ffz (man ffs). */ - -#define ffs(x) generic_ffs(x) +static __inline__ int ffs(int x) +{ + if (!x) + return 0; + return __ffs((unsigned long)x) + 1; +} /* * hweightN: returns the hamming weight (i.e. the number @@ -132,7 +148,15 @@ extern __inline__ unsigned long ffz(unsi #ifdef ULTRA_HAS_POPULATION_COUNT -extern __inline__ unsigned int hweight32(unsigned int w) +static __inline__ unsigned int hweight64(unsigned long w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); + return res; +} + +static __inline__ unsigned int hweight32(unsigned int w) { unsigned int res; @@ -140,7 +164,7 @@ extern __inline__ unsigned int hweight32 return res; } -extern __inline__ unsigned int hweight16(unsigned int w) +static __inline__ unsigned int hweight16(unsigned int w) { unsigned int res; @@ -148,7 +172,7 @@ extern __inline__ unsigned int hweight16 return res; } -extern __inline__ unsigned int hweight8(unsigned int w) +static __inline__ unsigned int hweight8(unsigned int w) { unsigned int res; @@ -158,6 +182,7 @@ extern __inline__ unsigned int hweight8( #else +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) @@ -170,7 +195,7 @@ extern __inline__ unsigned int hweight8( * on Linus's ALPHA routines, which are pretty portable BTW. */ -extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +static __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) { unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long result = offset & ~63UL; @@ -211,15 +236,12 @@ found_middle: #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) -extern long ___test_and_set_le_bit(int nr, volatile void *addr); -extern long ___test_and_clear_le_bit(int nr, volatile void *addr); - -#define test_and_set_le_bit(nr,addr) ({___test_and_set_le_bit(nr,addr)!=0;}) -#define test_and_clear_le_bit(nr,addr) ({___test_and_clear_le_bit(nr,addr)!=0;}) -#define set_le_bit(nr,addr) ((void)___test_and_set_le_bit(nr,addr)) -#define clear_le_bit(nr,addr) ((void)___test_and_clear_le_bit(nr,addr)) +#define test_and_set_le_bit(nr,addr) \ + test_and_set_bit((nr) ^ 0x38, (addr)) +#define test_and_clear_le_bit(nr,addr) \ + test_and_clear_bit((nr) ^ 0x38, (addr)) -extern __inline__ int test_le_bit(int nr, __const__ void * addr) +static __inline__ int test_le_bit(int nr, __const__ void *addr) { int mask; __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; @@ -232,7 +254,7 @@ extern __inline__ int test_le_bit(int nr #define find_first_zero_le_bit(addr, size) \ find_next_zero_le_bit((addr), (size), 0) -extern __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long size, unsigned long offset) +static __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long size, unsigned long offset) { unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long result = offset & ~63UL; @@ -271,18 +293,41 @@ found_middle: #ifdef __KERNEL__ -#define ext2_set_bit test_and_set_le_bit -#define ext2_clear_bit test_and_clear_le_bit -#define ext2_test_bit test_le_bit -#define ext2_find_first_zero_bit find_first_zero_le_bit -#define ext2_find_next_zero_bit find_next_zero_le_bit +#define __set_le_bit(nr, addr) \ + __set_bit((nr) ^ 0x38, (addr)) +#define __clear_le_bit(nr, addr) \ + __clear_bit((nr) ^ 0x38, (addr)) +#define __test_and_clear_le_bit(nr, addr) \ + __test_and_clear_bit((nr) ^ 0x38, (addr)) +#define __test_and_set_le_bit(nr, addr) \ + __test_and_set_bit((nr) ^ 0x38, (addr)) + +#define ext2_set_bit(nr,addr) \ + __test_and_set_le_bit((nr),(unsigned long *)(addr)) +#define ext2_set_bit_atomic(lock,nr,addr) \ + test_and_set_le_bit((nr),(unsigned long *)(addr)) +#define ext2_clear_bit(nr,addr) \ + __test_and_clear_le_bit((nr),(unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock,nr,addr) \ + test_and_clear_le_bit((nr),(unsigned long *)(addr)) +#define ext2_test_bit(nr,addr) \ + test_le_bit((nr),(unsigned long *)(addr)) +#define ext2_find_first_zero_bit(addr, size) \ + find_first_zero_le_bit((unsigned long *)(addr), (size)) +#define ext2_find_next_zero_bit(addr, size, off) \ + find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) /* Bitmap functions for the minix filesystem. */ -#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) -#define minix_set_bit(nr,addr) set_bit(nr,addr) -#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) -#define minix_test_bit(nr,addr) test_bit(nr,addr) -#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) +#define minix_test_and_set_bit(nr,addr) \ + test_and_set_bit((nr),(unsigned long *)(addr)) +#define minix_set_bit(nr,addr) \ + set_bit((nr),(unsigned long *)(addr)) +#define minix_test_and_clear_bit(nr,addr) \ + test_and_clear_bit((nr),(unsigned long *)(addr)) +#define minix_test_bit(nr,addr) \ + test_bit((nr),(unsigned long *)(addr)) +#define minix_find_first_zero_bit(addr,size) \ + find_first_zero_bit((unsigned long *)(addr),(size)) #endif /* __KERNEL__ */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-sparc64/system.h linux-2.4.30-rc1/include/asm-sparc64/system.h --- linux-2.4.29/include/asm-sparc64/system.h 2003-06-13 14:51:38.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-sparc64/system.h 2005-03-18 18:06:14.292751968 +0000 @@ -106,9 +106,9 @@ extern void __global_restore_flags(unsig #define nop() __asm__ __volatile__ ("nop") -#define membar(type) __asm__ __volatile__ ("membar " type : : : "memory"); +#define membar(type) __asm__ __volatile__ ("membar " type : : : "memory") #define mb() \ - membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad"); + membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad") #define rmb() membar("#LoadLoad") #define wmb() membar("#StoreStore") #define set_mb(__var, __value) \ @@ -121,9 +121,9 @@ extern void __global_restore_flags(unsig #define smp_rmb() rmb() #define smp_wmb() wmb() #else -#define smp_mb() __asm__ __volatile__("":::"memory"); -#define smp_rmb() __asm__ __volatile__("":::"memory"); -#define smp_wmb() __asm__ __volatile__("":::"memory"); +#define smp_mb() __asm__ __volatile__("":::"memory") +#define smp_rmb() __asm__ __volatile__("":::"memory") +#define smp_wmb() __asm__ __volatile__("":::"memory") #endif #define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") @@ -246,6 +246,7 @@ do { CHECK_LOCKS(prev); \ extern __inline__ unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) { __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" " mov %0, %%g5\n" "1: lduw [%2], %%g7\n" " cas [%2], %%g7, %0\n" @@ -262,6 +263,7 @@ extern __inline__ unsigned long xchg32(_ extern __inline__ unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val) { __asm__ __volatile__( +" membar #StoreLoad | #LoadLoad\n" " mov %0, %%g5\n" "1: ldx [%2], %%g7\n" " casx [%2], %%g7, %0\n" @@ -306,7 +308,8 @@ extern void die_if_kernel(char *str, str extern __inline__ unsigned long __cmpxchg_u32(volatile int *m, int old, int new) { - __asm__ __volatile__("cas [%2], %3, %0\n\t" + __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" + "cas [%2], %3, %0\n\t" "membar #StoreLoad | #StoreStore" : "=&r" (new) : "0" (new), "r" (m), "r" (old) @@ -318,7 +321,8 @@ __cmpxchg_u32(volatile int *m, int old, extern __inline__ unsigned long __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) { - __asm__ __volatile__("casx [%2], %3, %0\n\t" + __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" + "casx [%2], %3, %0\n\t" "membar #StoreLoad | #StoreStore" : "=&r" (new) : "0" (new), "r" (m), "r" (old) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/asm-x86_64/acpi.h linux-2.4.30-rc1/include/asm-x86_64/acpi.h --- linux-2.4.29/include/asm-x86_64/acpi.h 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/include/asm-x86_64/acpi.h 2005-03-18 18:07:49.808231408 +0000 @@ -118,6 +118,7 @@ extern int acpi_ioapic; extern int acpi_strict; extern int acpi_disabled; extern int acpi_ht; +extern int acpi_skip_timer_override; static inline void disable_acpi(void) { acpi_disabled = 1; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/agp_backend.h linux-2.4.30-rc1/include/linux/agp_backend.h --- linux-2.4.29/include/linux/agp_backend.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/agp_backend.h 2005-03-18 18:08:07.413554992 +0000 @@ -56,6 +56,7 @@ enum chipset_type { INTEL_I860, INTEL_I865_G, INTEL_I915_G, + INTEL_I915_GM, INTEL_I7205, INTEL_I7505, INTEL_460GX, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/ata.h linux-2.4.30-rc1/include/linux/ata.h --- linux-2.4.29/include/linux/ata.h 2005-01-19 14:10:12.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/ata.h 2005-03-18 18:06:36.466381064 +0000 @@ -123,6 +123,8 @@ enum { ATA_CMD_PIO_WRITE_EXT = 0x34, ATA_CMD_SET_FEATURES = 0xEF, ATA_CMD_PACKET = 0xA0, + ATA_CMD_VERIFY = 0x40, + ATA_CMD_VERIFY_EXT = 0x42, /* SETFEATURES stuff */ SETFEATURES_XFER = 0x03, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/brlock.h linux-2.4.30-rc1/include/linux/brlock.h --- linux-2.4.29/include/linux/brlock.h 2002-11-28 23:53:15.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/brlock.h 2005-03-18 18:07:07.947595192 +0000 @@ -18,16 +18,6 @@ * Registry idea and naming [ crutial! :-) ] by: * * David S. Miller - * - * David has an implementation that doesn't use atomic operations in - * the read branch via memory ordering tricks - i guess we need to - * split this up into a per-arch thing? The atomicity issue is a - * secondary item in profiles, at least on x86 platforms. - * - * The atomic op version overhead is indeed a big deal on - * load-locked/store-conditional cpus (ALPHA/MIPS/PPC) and - * compare-and-swap cpus (Sparc64). So we control which - * implementation to use with a __BRLOCK_USE_ATOMICS define. -DaveM */ /* Register bigreader lock indices here. */ @@ -45,17 +35,7 @@ enum brlock_indices { #include #include -#if defined(__i386__) || defined(__ia64__) || defined(__x86_64__) -#define __BRLOCK_USE_ATOMICS -#else -#undef __BRLOCK_USE_ATOMICS -#endif - -#ifdef __BRLOCK_USE_ATOMICS -typedef rwlock_t brlock_read_lock_t; -#else typedef unsigned int brlock_read_lock_t; -#endif /* * align last allocated index to the next cacheline: @@ -65,39 +45,14 @@ typedef unsigned int brlock_read_lock_t; extern brlock_read_lock_t __brlock_array[NR_CPUS][__BR_IDX_MAX]; -#ifndef __BRLOCK_USE_ATOMICS struct br_wrlock { spinlock_t lock; } __attribute__ ((__aligned__(SMP_CACHE_BYTES))); extern struct br_wrlock __br_write_locks[__BR_IDX_MAX]; -#endif extern void __br_lock_usage_bug (void); -#ifdef __BRLOCK_USE_ATOMICS - -static inline void br_read_lock (enum brlock_indices idx) -{ - /* - * This causes a link-time bug message if an - * invalid index is used: - */ - if (idx >= __BR_END) - __br_lock_usage_bug(); - - read_lock(&__brlock_array[smp_processor_id()][idx]); -} - -static inline void br_read_unlock (enum brlock_indices idx) -{ - if (idx >= __BR_END) - __br_lock_usage_bug(); - - read_unlock(&__brlock_array[smp_processor_id()][idx]); -} - -#else /* ! __BRLOCK_USE_ATOMICS */ static inline void br_read_lock (enum brlock_indices idx) { unsigned int *ctr; @@ -149,7 +104,6 @@ static inline void br_read_unlock (enum wmb(); (*ctr)--; } -#endif /* __BRLOCK_USE_ATOMICS */ /* write path not inlined - it's rare and larger */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/fs.h linux-2.4.30-rc1/include/linux/fs.h --- linux-2.4.29/include/linux/fs.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/fs.h 2005-03-18 18:06:47.300733992 +0000 @@ -576,6 +576,7 @@ struct file { unsigned int f_uid, f_gid; int f_error; + size_t f_maxcount; unsigned long f_version; /* needed for tty driver, and maybe others */ @@ -1056,14 +1057,7 @@ static inline int locks_verify_locked(st return 0; } -static inline int locks_verify_area(int read_write, struct inode *inode, - struct file *filp, loff_t offset, - size_t count) -{ - if (inode->i_flock && MANDATORY_LOCK(inode)) - return locks_mandatory_area(read_write, inode, filp, offset, count); - return 0; -} +extern int rw_verify_area(int, struct file *, loff_t *, size_t); static inline int locks_verify_truncate(struct inode *inode, struct file *filp, diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/jbd.h linux-2.4.30-rc1/include/linux/jbd.h --- linux-2.4.29/include/linux/jbd.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/jbd.h 2005-03-18 18:08:08.575378368 +0000 @@ -848,7 +848,7 @@ extern void journal_brelse_array(stru extern int log_space_left (journal_t *); /* Called with journal locked */ extern tid_t log_start_commit (journal_t *, transaction_t *); -extern void log_wait_commit (journal_t *, tid_t); +extern int log_wait_commit (journal_t *, tid_t); extern int log_do_checkpoint (journal_t *, int); extern void log_wait_for_space(journal_t *, int nblocks); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/kernel.h linux-2.4.30-rc1/include/linux/kernel.h --- linux-2.4.29/include/linux/kernel.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/kernel.h 2005-03-18 18:06:11.236216632 +0000 @@ -73,14 +73,17 @@ extern unsigned long long simple_strtoul extern long long simple_strtoll(const char *,char **,unsigned int); extern int sprintf(char * buf, const char * fmt, ...) __attribute__ ((format (printf, 2, 3))); -extern int vsprintf(char *buf, const char *, va_list); +extern int vsprintf(char *buf, const char *, va_list) + __attribute__ ((format (printf, 2, 0))); extern int snprintf(char * buf, size_t size, const char * fmt, ...) __attribute__ ((format (printf, 3, 4))); -extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))); extern int sscanf(const char *, const char *, ...) - __attribute__ ((format (scanf,2,3))); -extern int vsscanf(const char *, const char *, va_list); + __attribute__ ((format (scanf, 2, 3))); +extern int vsscanf(const char *, const char *, va_list) + __attribute__ ((format (scanf, 2, 0))); extern int get_option(char **str, int *pint); extern char *get_options(char *str, int nints, int *ints); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/libata-compat.h linux-2.4.30-rc1/include/linux/libata-compat.h --- linux-2.4.29/include/linux/libata-compat.h 2005-01-19 14:10:12.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/libata-compat.h 2005-03-18 18:07:22.557374168 +0000 @@ -1,8 +1,16 @@ #ifndef __LIBATA_COMPAT_H__ #define __LIBATA_COMPAT_H__ +#include #include #include +#include + +typedef u32 __le32; +typedef u64 __le64; + +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#define DMA_32BIT_MASK 0x00000000ffffffffULL #define MODULE_VERSION(ver_str) @@ -10,11 +18,6 @@ struct device { struct pci_dev pdev; }; -static inline void libata_msleep(unsigned long msecs) -{ - msleep(msecs); -} - static inline struct pci_dev *to_pci_dev(struct device *dev) { return (struct pci_dev *) dev; @@ -47,4 +50,13 @@ static inline struct pci_dev *to_pci_dev #define dev_set_drvdata(dev,ptr) \ pci_set_drvdata(to_pci_dev(dev),(ptr)) +static inline void *kcalloc(size_t nmemb, size_t size, int flags) +{ + size_t total = nmemb * size; + void *mem = kmalloc(total, flags); + if (mem) + memset(mem, 0, total); + return mem; +} + #endif /* __LIBATA_COMPAT_H__ */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/libata.h linux-2.4.30-rc1/include/linux/libata.h --- linux-2.4.29/include/linux/libata.h 2005-01-19 14:10:12.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/libata.h 2005-03-18 18:08:02.632281856 +0000 @@ -335,6 +335,8 @@ struct ata_port_operations { void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); u8 (*check_status)(struct ata_port *ap); + u8 (*check_altstatus)(struct ata_port *ap); + u8 (*check_err)(struct ata_port *ap); void (*dev_select)(struct ata_port *ap, unsigned int device); void (*phy_reset) (struct ata_port *ap); @@ -361,6 +363,9 @@ struct ata_port_operations { void (*port_stop) (struct ata_port *ap); void (*host_stop) (struct ata_host_set *host_set); + + void (*bmdma_stop) (struct ata_port *ap); + u8 (*bmdma_status) (struct ata_port *ap); }; struct ata_port_info { @@ -401,6 +406,8 @@ extern void ata_tf_from_fis(u8 *fis, str extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); +extern u8 ata_altstatus(struct ata_port *ap); +extern u8 ata_chk_err(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); @@ -416,6 +423,8 @@ extern void ata_dev_id_string(u16 *id, u unsigned int ofs, unsigned int len); extern void ata_bmdma_setup (struct ata_queued_cmd *qc); extern void ata_bmdma_start (struct ata_queued_cmd *qc); +extern void ata_bmdma_stop(struct ata_port *ap); +extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); extern void ata_eng_timeout(struct ata_port *ap); @@ -435,8 +444,6 @@ struct pci_bits { extern struct ata_probe_ent * ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port); -extern struct ata_probe_ent * -ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port); extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); #endif /* CONFIG_PCI */ @@ -453,26 +460,11 @@ static inline unsigned int ata_dev_prese (dev->class == ATA_DEV_ATAPI)); } -static inline u8 ata_chk_err(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) { - return readb((void __iomem *) ap->ioaddr.error_addr); - } - return inb(ap->ioaddr.error_addr); -} - static inline u8 ata_chk_status(struct ata_port *ap) { return ap->ops->check_status(ap); } -static inline u8 ata_altstatus(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) - return readb((void __iomem *)ap->ioaddr.altstatus_addr); - return inb(ap->ioaddr.altstatus_addr); -} - static inline void ata_pause(struct ata_port *ap) { ata_altstatus(ap); @@ -596,46 +588,6 @@ static inline unsigned int sata_dev_pres return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; } -static inline void ata_bmdma_stop(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - - /* clear start/stop bit */ - writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, - mmio + ATA_DMA_CMD); - } else { - /* clear start/stop bit */ - outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - } - - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ -} - -static inline void ata_bmdma_ack_irq(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; - writeb(readb(mmio), mmio); - } else { - unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; - outb(inb(addr), addr); - } -} - -static inline u8 ata_bmdma_status(struct ata_port *ap) -{ - u8 host_stat; - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - host_stat = readb(mmio + ATA_DMA_STATUS); - } else - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - return host_stat; -} - static inline int ata_try_flush_cache(struct ata_device *dev) { return ata_id_wcache_enabled(dev->id) || diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.30-rc1/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.4.29/include/linux/netfilter_ipv4/ip_conntrack.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2005-03-18 18:08:20.020638424 +0000 @@ -249,10 +249,9 @@ extern void ip_ct_refresh(struct ip_conn /* Call me when a conntrack is destroyed. */ extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack); -extern int ip_ct_no_defrag; /* Returns new sk_buff, or NULL */ struct sk_buff * -ip_ct_gather_frags(struct sk_buff *skb); +ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user); /* Delete all conntracks which match. */ extern void diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/netlink.h linux-2.4.30-rc1/include/linux/netlink.h --- linux-2.4.29/include/linux/netlink.h 2005-01-19 14:10:12.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/netlink.h 2005-03-18 18:08:12.923717320 +0000 @@ -117,10 +117,9 @@ extern int netlink_proto_init(void); /* * skb should fit one page. This choice is good for headerless malloc. - * - * FIXME: What is the best size for SLAB???? --ANK */ -#define NLMSG_GOODSIZE (PAGE_SIZE - ((sizeof(struct sk_buff)+0xF)&~0xF)) +#define NLMSG_GOODORDER 0 +#define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER)) struct netlink_callback diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/pci_ids.h linux-2.4.30-rc1/include/linux/pci_ids.h --- linux-2.4.29/include/linux/pci_ids.h 2005-01-19 14:10:12.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/pci_ids.h 2005-03-18 18:07:13.662726360 +0000 @@ -1937,7 +1937,6 @@ #define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 #define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 #define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7 -#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db #define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd #define PCI_DEVICE_ID_INTEL_ESB_0 0x25a0 diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/skbuff.h linux-2.4.30-rc1/include/linux/skbuff.h --- linux-2.4.29/include/linux/skbuff.h 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/skbuff.h 2005-03-18 18:06:20.516805768 +0000 @@ -290,15 +290,11 @@ static inline struct sk_buff *skb_get(st static inline void kfree_skb(struct sk_buff *skb) { - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - __kfree_skb(skb); -} - -/* Use this if you didn't touch the skb state [for fast switching] */ -static inline void kfree_skb_fast(struct sk_buff *skb) -{ - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - kfree_skbmem(skb); + if (likely(atomic_read(&skb->users) == 1)) + smp_rmb(); + else if (likely(!atomic_dec_and_test(&skb->users))) + return; + __kfree_skb(skb); } /** diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/linux/sysctl.h linux-2.4.30-rc1/include/linux/sysctl.h --- linux-2.4.29/include/linux/sysctl.h 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/include/linux/sysctl.h 2005-03-18 18:06:15.954499344 +0000 @@ -326,6 +326,7 @@ enum NET_TCP_BIC_LOW_WINDOW=104, NET_TCP_DEFAULT_WIN_SCALE=105, NET_TCP_MODERATE_RCVBUF=106, + NET_TCP_BIC_BETA=108, }; enum { diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/net/dst.h linux-2.4.30-rc1/include/net/dst.h --- linux-2.4.29/include/net/dst.h 2003-08-25 11:44:44.000000000 +0000 +++ linux-2.4.30-rc1/include/net/dst.h 2005-03-18 18:08:19.576705912 +0000 @@ -104,8 +104,10 @@ struct dst_entry * dst_clone(struct dst_ static inline void dst_release(struct dst_entry * dst) { - if (dst) + if (dst) { + smp_mb__before_atomic_dec(); atomic_dec(&dst->__refcnt); + } } extern void * dst_alloc(struct dst_ops * ops); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/net/ip.h linux-2.4.30-rc1/include/net/ip.h --- linux-2.4.29/include/net/ip.h 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/include/net/ip.h 2005-03-18 18:07:52.502821768 +0000 @@ -227,9 +227,19 @@ extern int ip_call_ra_chain(struct sk_bu /* * Functions provided by ip_fragment.o */ - -struct sk_buff *ip_defrag(struct sk_buff *skb); -extern void ipfrag_flush(void); + +enum ip_defrag_users +{ + IP_DEFRAG_LOCAL_DELIVER, + IP_DEFRAG_CALL_RA_CHAIN, + IP_DEFRAG_CONNTRACK_IN, + IP_DEFRAG_CONNTRACK_OUT, + IP_DEFRAG_NAT_OUT, + IP_DEFRAG_VS_OUT, + IP_DEFRAG_VS_FWD +}; + +struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user); extern int ip_frag_nqueues; extern atomic_t ip_frag_mem; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/include/net/tcp.h linux-2.4.30-rc1/include/net/tcp.h --- linux-2.4.29/include/net/tcp.h 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/include/net/tcp.h 2005-03-18 18:06:31.297166904 +0000 @@ -395,9 +395,8 @@ static __inline__ int tcp_sk_listen_hash # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) #endif -#define BICTCP_1_OVER_BETA 8 /* - * Fast recovery - * multiplicative decrease factor +#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation + * max_cwnd = snd_cwnd * beta */ #define BICTCP_MAX_INCREMENT 32 /* * Limit on the amount of @@ -491,6 +490,7 @@ extern int sysctl_tcp_nometrics_save; extern int sysctl_tcp_bic; extern int sysctl_tcp_bic_fast_convergence; extern int sysctl_tcp_bic_low_window; +extern int sysctl_tcp_bic_beta; extern int sysctl_tcp_default_win_scale; extern int sysctl_tcp_moderate_rcvbuf; @@ -1132,15 +1132,16 @@ static inline __u32 tcp_recalc_ssthresh( if (tcp_is_bic(tp)) { if (sysctl_tcp_bic_fast_convergence && tp->snd_cwnd < tp->bictcp.last_max_cwnd) - tp->bictcp.last_max_cwnd - = (tp->snd_cwnd * (2*BICTCP_1_OVER_BETA-1)) - / (BICTCP_1_OVER_BETA/2); + tp->bictcp.last_max_cwnd = (tp->snd_cwnd * + (BICTCP_BETA_SCALE + + sysctl_tcp_bic_beta)) + / (2 * BICTCP_BETA_SCALE); else tp->bictcp.last_max_cwnd = tp->snd_cwnd; if (tp->snd_cwnd > sysctl_tcp_bic_low_window) - return max(tp->snd_cwnd - (tp->snd_cwnd/BICTCP_1_OVER_BETA), - 2U); + return max((tp->snd_cwnd * sysctl_tcp_bic_beta) + / BICTCP_BETA_SCALE, 2U); } return max(tp->snd_cwnd >> 1U, 2U); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/lib/brlock.c linux-2.4.30-rc1/lib/brlock.c --- linux-2.4.29/lib/brlock.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/lib/brlock.c 2005-03-18 18:07:53.588656696 +0000 @@ -15,29 +15,6 @@ #include #include -#ifdef __BRLOCK_USE_ATOMICS - -brlock_read_lock_t __brlock_array[NR_CPUS][__BR_IDX_MAX] = - { [0 ... NR_CPUS-1] = { [0 ... __BR_IDX_MAX-1] = RW_LOCK_UNLOCKED } }; - -void fastcall __br_write_lock (enum brlock_indices idx) -{ - int i; - - for (i = 0; i < smp_num_cpus; i++) - write_lock(&__brlock_array[cpu_logical_map(i)][idx]); -} - -void fastcall __br_write_unlock (enum brlock_indices idx) -{ - int i; - - for (i = 0; i < smp_num_cpus; i++) - write_unlock(&__brlock_array[cpu_logical_map(i)][idx]); -} - -#else /* ! __BRLOCK_USE_ATOMICS */ - brlock_read_lock_t __brlock_array[NR_CPUS][__BR_IDX_MAX] = { [0 ... NR_CPUS-1] = { [0 ... __BR_IDX_MAX-1] = 0 } }; @@ -64,6 +41,4 @@ void fastcall __br_write_unlock (enum br spin_unlock(&__br_write_locks[idx].lock); } -#endif /* __BRLOCK_USE_ATOMICS */ - #endif /* CONFIG_SMP */ diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/mm/filemap.c linux-2.4.30-rc1/mm/filemap.c --- linux-2.4.29/mm/filemap.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/mm/filemap.c 2005-03-18 18:07:05.495967896 +0000 @@ -1870,7 +1870,7 @@ static ssize_t common_sendfile(int out_f goto fput_in; if (!in_inode->i_mapping->a_ops->readpage) goto fput_in; - retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, in_file->f_pos, count); + retval = rw_verify_area(READ, in_file, &in_file->f_pos, count); if (retval) goto fput_in; @@ -1887,7 +1887,7 @@ static ssize_t common_sendfile(int out_f if (!out_file->f_op || !out_file->f_op->write) goto fput_out; out_inode = out_file->f_dentry->d_inode; - retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count); + retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); if (retval) goto fput_out; @@ -2589,7 +2589,7 @@ static long madvise_willneed(struct vm_a long error = -EBADF; struct file * file; struct inode * inode; - unsigned long size, rlim_rss; + unsigned long size; /* Doesn't work if there's no mapped file. */ if (!vma->vm_file) @@ -2605,13 +2605,6 @@ static long madvise_willneed(struct vm_a end = vma->vm_end; end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - /* Make sure this doesn't exceed the process's max rss. */ - error = -EIO; - rlim_rss = current->rlim ? current->rlim[RLIMIT_RSS].rlim_cur : - LONG_MAX; /* default: see resource.h */ - if ((vma->vm_mm->rss + (end - start)) > rlim_rss) - return error; - /* round to cluster boundaries if this isn't a "random" area. */ if (!VM_RandomReadHint(vma)) { start = CLUSTER_OFFSET(start); @@ -3268,7 +3261,12 @@ done: status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA); } - err = written ? written : status; + /* + * generic_osync_inode always returns 0 or negative value. + * So 'status < written' is always true, and written should + * be returned if status >= 0. + */ + err = (status < 0) ? status : written; out: return err; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/mm/memory.c linux-2.4.30-rc1/mm/memory.c --- linux-2.4.29/mm/memory.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/mm/memory.c 2005-03-18 18:07:22.519379944 +0000 @@ -499,9 +499,11 @@ int get_user_pages(struct task_struct *t /* FIXME: call the correct function, * depending on the type of the found page */ - if (!pages[i]) - goto bad_page; - page_cache_get(pages[i]); + if (!pages[i] || PageReserved(pages[i])) { + if (pages[i] != ZERO_PAGE(start)) + goto bad_page; + } else + page_cache_get(pages[i]); } if (vmas) vmas[i] = vma; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/mm/page_alloc.c linux-2.4.30-rc1/mm/page_alloc.c --- linux-2.4.29/mm/page_alloc.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/mm/page_alloc.c 2005-03-18 18:06:26.156948336 +0000 @@ -551,7 +551,7 @@ unsigned int nr_free_buffer_pages (void) class_idx = zone_idx(zone); sum += zone->nr_cache_pages; - for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) { + for (; zone; zone = *zonep++) { int free = zone->free_pages - zone->watermarks[class_idx].high; if (free <= 0) continue; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/mm/swapfile.c linux-2.4.30-rc1/mm/swapfile.c --- linux-2.4.29/mm/swapfile.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/mm/swapfile.c 2005-03-18 18:06:41.307645080 +0000 @@ -738,8 +738,10 @@ asmlinkage long sys_swapoff(const char * for (type = swap_list.head; type >= 0; type = swap_info[type].next) { p = swap_info + type; if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { - if (p->swap_file == nd.dentry) - break; + if (p->swap_file == nd.dentry || + (S_ISBLK(nd.dentry->d_inode->i_mode) && + p->swap_device == nd.dentry->d_inode->i_rdev)) + break; } prev = type; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/core/dev.c linux-2.4.30-rc1/net/core/dev.c --- linux-2.4.29/net/core/dev.c 2004-04-14 13:05:41.000000000 +0000 +++ linux-2.4.30-rc1/net/core/dev.c 2005-03-18 18:07:30.184214712 +0000 @@ -2180,10 +2180,26 @@ static int dev_ifsioc(struct ifreq *ifr, case SIOCSIFNAME: if (dev->flags&IFF_UP) return -EBUSY; - if (__dev_get_by_name(ifr->ifr_newname)) - return -EEXIST; - memcpy(dev->name, ifr->ifr_newname, IFNAMSIZ); - dev->name[IFNAMSIZ-1] = 0; + /* Check if name contains a wildcard */ + if (strchr(ifr->ifr_newname, '%')) { + char format[IFNAMSIZ + 1]; + int ret; + memcpy(format, ifr->ifr_newname, IFNAMSIZ); + format[IFNAMSIZ-1] = 0; + /* Find a free name based on format. + * dev_alloc_name() replaces "%d" with at max + * 2 digits, so no name overflow. - Jean II */ + ret = dev_alloc_name(dev, format); + if (ret < 0) + return ret; + /* Copy the new name back to caller. */ + strncpy(ifr->ifr_newname, dev->name, IFNAMSIZ); + } else { + if (__dev_get_by_name(ifr->ifr_newname)) + return -EEXIST; + memcpy(dev->name, ifr->ifr_newname, IFNAMSIZ); + dev->name[IFNAMSIZ-1] = 0; + } notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); return 0; @@ -2316,6 +2332,7 @@ int dev_ioctl(unsigned int cmd, void *ar * - return a value */ + case SIOCSIFNAME: case SIOCGMIIPHY: case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) @@ -2351,7 +2368,6 @@ int dev_ioctl(unsigned int cmd, void *ar case SIOCDELMULTI: case SIOCSIFHWBROADCAST: case SIOCSIFTXQLEN: - case SIOCSIFNAME: case SIOCSMIIREG: case SIOCBONDENSLAVE: case SIOCBONDRELEASE: diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/core/dst.c linux-2.4.30-rc1/net/core/dst.c --- linux-2.4.29/net/core/dst.c 2003-08-25 11:44:44.000000000 +0000 +++ linux-2.4.30-rc1/net/core/dst.c 2005-03-18 18:07:42.793297840 +0000 @@ -142,8 +142,13 @@ void __dst_free(struct dst_entry * dst) void dst_destroy(struct dst_entry * dst) { - struct neighbour *neigh = dst->neighbour; - struct hh_cache *hh = dst->hh; + struct neighbour *neigh; + struct hh_cache *hh; + + smp_rmb(); + + neigh = dst->neighbour; + hh = dst->hh; dst->hh = NULL; if (hh && atomic_dec_and_test(&hh->hh_refcnt)) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/core/neighbour.c linux-2.4.30-rc1/net/core/neighbour.c --- linux-2.4.29/net/core/neighbour.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/core/neighbour.c 2005-03-18 18:06:23.539346272 +0000 @@ -111,7 +111,7 @@ static int neigh_blackhole(struct sk_buf unsigned long neigh_rand_reach_time(unsigned long base) { - return (net_random() % base) + (base>>1); + return (base ? (net_random() % base) + (base >> 1) : 0); } @@ -1469,6 +1469,7 @@ static int neigh_fill_info(struct sk_buf nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ndm)); ndm = NLMSG_DATA(nlh); + nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0; ndm->ndm_family = n->ops->family; ndm->ndm_flags = n->flags; ndm->ndm_type = n->type; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/ip_fragment.c linux-2.4.30-rc1/net/ipv4/ip_fragment.c --- linux-2.4.29/net/ipv4/ip_fragment.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/ip_fragment.c 2005-03-18 18:06:51.746058200 +0000 @@ -72,6 +72,7 @@ struct ipfrag_skb_cb struct ipq { struct ipq *next; /* linked list pointers */ struct list_head lru_list; /* lru list member */ + u32 user; u32 saddr; u32 daddr; u16 id; @@ -242,13 +243,13 @@ static __inline__ void ipq_kill(struct i /* Memory limiting on fragments. Evictor trashes the oldest * fragment queue until we are back under the threshold. */ -static void __ip_evictor(int threshold) +static void ip_evictor(void) { struct ipq *qp; struct list_head *tmp; int work; - work = atomic_read(&ip_frag_mem) - threshold; + work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh; if (work <= 0) return; @@ -273,11 +274,6 @@ static void __ip_evictor(int threshold) } } -static inline void ip_evictor(void) -{ - __ip_evictor(sysctl_ipfrag_low_thresh); -} - /* * Oops, a fragment queue timed out. Kill it and send an ICMP reply. */ @@ -324,7 +320,8 @@ static struct ipq *ip_frag_intern(unsign if(qp->id == qp_in->id && qp->saddr == qp_in->saddr && qp->daddr == qp_in->daddr && - qp->protocol == qp_in->protocol) { + qp->protocol == qp_in->protocol && + qp->user == qp_in->user) { atomic_inc(&qp->refcnt); write_unlock(&ipfrag_lock); qp_in->last_in |= COMPLETE; @@ -351,7 +348,7 @@ static struct ipq *ip_frag_intern(unsign } /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ -static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) +static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) { struct ipq *qp; @@ -363,6 +360,7 @@ static struct ipq *ip_frag_create(unsign qp->id = iph->id; qp->saddr = iph->saddr; qp->daddr = iph->daddr; + qp->user = user; qp->len = 0; qp->meat = 0; qp->fragments = NULL; @@ -385,7 +383,7 @@ out_nomem: /* Find the correct entry in the "incomplete datagrams" queue for * this IP datagram, and create new one, if nothing is found. */ -static inline struct ipq *ip_find(struct iphdr *iph) +static inline struct ipq *ip_find(struct iphdr *iph, u32 user) { __u16 id = iph->id; __u32 saddr = iph->saddr; @@ -399,7 +397,8 @@ static inline struct ipq *ip_find(struct if(qp->id == id && qp->saddr == saddr && qp->daddr == daddr && - qp->protocol == protocol) { + qp->protocol == protocol && + qp->user == user) { atomic_inc(&qp->refcnt); read_unlock(&ipfrag_lock); return qp; @@ -407,7 +406,7 @@ static inline struct ipq *ip_find(struct } read_unlock(&ipfrag_lock); - return ip_frag_create(hash, iph); + return ip_frag_create(hash, iph, user); } /* Add new segment to existing queue. */ @@ -641,7 +640,7 @@ out_fail: } /* Process an incoming IP datagram fragment. */ -struct sk_buff *ip_defrag(struct sk_buff *skb) +struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user) { struct iphdr *iph = skb->nh.iph; struct ipq *qp; @@ -656,7 +655,7 @@ struct sk_buff *ip_defrag(struct sk_buff dev = skb->dev; /* Lookup (or create) queue header */ - if ((qp = ip_find(iph)) != NULL) { + if ((qp = ip_find(iph, user)) != NULL) { struct sk_buff *ret = NULL; spin_lock(&qp->lock); @@ -687,8 +686,3 @@ void ipfrag_init(void) ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval; add_timer(&ipfrag_secret_timer); } - -void ipfrag_flush(void) -{ - __ip_evictor(0); -} diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/ip_input.c linux-2.4.30-rc1/net/ipv4/ip_input.c --- linux-2.4.29/net/ipv4/ip_input.c 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/ip_input.c 2005-03-18 18:06:25.184096232 +0000 @@ -170,7 +170,7 @@ int ip_call_ra_chain(struct sk_buff *skb && ((sk->bound_dev_if == 0) || (sk->bound_dev_if == skb->dev->ifindex))) { if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN); if (skb == NULL) { read_unlock(&ip_ra_lock); return 1; @@ -291,7 +291,7 @@ int ip_local_deliver(struct sk_buff *skb */ if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER); if (!skb) return 0; } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/ipconfig.c linux-2.4.30-rc1/net/ipv4/ipconfig.c --- linux-2.4.29/net/ipv4/ipconfig.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/ipconfig.c 2005-03-18 18:06:23.567342016 +0000 @@ -1162,7 +1162,7 @@ u32 __init root_nfs_parse_addr(char *nam if (*cp == ':') *cp++ = '\0'; addr = in_aton(name); - strcpy(name, cp); + memmove(name, cp, strlen(cp) + 1); } else addr = INADDR_NONE; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/ipvs/ip_vs_core.c linux-2.4.30-rc1/net/ipv4/ipvs/ip_vs_core.c --- linux-2.4.29/net/ipv4/ipvs/ip_vs_core.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/ipvs/ip_vs_core.c 2005-03-18 18:06:35.907466032 +0000 @@ -506,7 +506,7 @@ static int ip_vs_out_icmp(struct sk_buff /* reassemble IP fragments, but will it happen in ICMP packets?? */ if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_VS_OUT); if (!skb) return NF_STOLEN; *skb_p = skb; @@ -658,7 +658,7 @@ static unsigned int ip_vs_out(unsigned i /* reassemble IP fragments */ if (iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_VS_OUT); if (!skb) return NF_STOLEN; iph = skb->nh.iph; @@ -1164,7 +1164,7 @@ static unsigned int ip_vs_forward_icmp(u return NF_ACCEPT; if (iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_VS_FWD); if (!skb) return NF_STOLEN; *skb_p = skb; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.30-rc1/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_core.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/netfilter/ip_conntrack_core.c 2005-03-18 18:06:10.504327896 +0000 @@ -834,7 +834,10 @@ unsigned int ip_conntrack_in(unsigned in /* Gather fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); + *pskb = ip_ct_gather_frags(*pskb, + hooknum == NF_IP_PRE_ROUTING ? + IP_DEFRAG_CONNTRACK_IN : + IP_DEFRAG_CONNTRACK_OUT); if (!*pskb) return NF_STOLEN; } @@ -1183,29 +1186,22 @@ void ip_ct_refresh(struct ip_conntrack * WRITE_UNLOCK(&ip_conntrack_lock); } -int ip_ct_no_defrag; - /* Returns new sk_buff, or NULL */ struct sk_buff * -ip_ct_gather_frags(struct sk_buff *skb) +ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) { struct sock *sk = skb->sk; #ifdef CONFIG_NETFILTER_DEBUG unsigned int olddebug = skb->nf_debug; #endif - if (unlikely(ip_ct_no_defrag)) { - kfree_skb(skb); - return NULL; - } - if (sk) { sock_hold(sk); skb_orphan(skb); } local_bh_disable(); - skb = ip_defrag(skb); + skb = ip_defrag(skb, user); local_bh_enable(); if (!skb) { diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.30-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.4.29/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-03-18 18:07:20.246725440 +0000 @@ -393,13 +393,6 @@ static int init_or_cleanup(int init) cleanup_inandlocalops: nf_unregister_hook(&ip_conntrack_local_out_ops); cleanup_inops: - /* Frag queues may hold fragments with skb->dst == NULL */ - ip_ct_no_defrag = 1; - local_bh_disable(); - br_write_lock(BR_NETPROTO_LOCK); - br_write_unlock(BR_NETPROTO_LOCK); - ipfrag_flush(); - local_bh_enable(); nf_unregister_hook(&ip_conntrack_in_ops); cleanup_proc: proc_net_remove("ip_conntrack"); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/netfilter/ip_fw_compat.c linux-2.4.30-rc1/net/ipv4/netfilter/ip_fw_compat.c --- linux-2.4.29/net/ipv4/netfilter/ip_fw_compat.c 2003-11-28 18:26:21.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/netfilter/ip_fw_compat.c 2005-03-18 18:07:11.187102712 +0000 @@ -108,7 +108,7 @@ fw_in(unsigned int hooknum, (*pskb)->nh.raw, &redirpt, pskb); if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); + *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_CONNTRACK_IN); if (!*pskb) return NF_STOLEN; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/netfilter/ip_nat_standalone.c linux-2.4.30-rc1/net/ipv4/netfilter/ip_nat_standalone.c --- linux-2.4.29/net/ipv4/netfilter/ip_nat_standalone.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/netfilter/ip_nat_standalone.c 2005-03-18 18:08:05.357867504 +0000 @@ -201,7 +201,7 @@ ip_nat_out(unsigned int hooknum, I'm starting to have nightmares about fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); + *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT); if (!*pskb) return NF_STOLEN; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/sysctl_net_ipv4.c linux-2.4.30-rc1/net/ipv4/sysctl_net_ipv4.c --- linux-2.4.29/net/ipv4/sysctl_net_ipv4.c 2004-08-07 23:26:06.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/sysctl_net_ipv4.c 2005-03-18 18:07:58.315938040 +0000 @@ -268,6 +268,9 @@ ctl_table ipv4_table[] = { {NET_TCP_MODERATE_RCVBUF, "tcp_moderate_rcvbuf", &sysctl_tcp_moderate_rcvbuf, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_TCP_BIC_BETA, "tcp_bic_beta", + &sysctl_tcp_bic_beta, sizeof(int), 0644, NULL, + &proc_dointvec}, {0} }; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/ipv4/tcp_input.c linux-2.4.30-rc1/net/ipv4/tcp_input.c --- linux-2.4.29/net/ipv4/tcp_input.c 2005-01-19 14:10:13.000000000 +0000 +++ linux-2.4.30-rc1/net/ipv4/tcp_input.c 2005-03-18 18:06:41.695586104 +0000 @@ -107,6 +107,7 @@ int sysctl_tcp_vegas_gamma = 1<prior_ssthresh) { - tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); + if (tcp_is_bic(tp)) + tp->snd_cwnd = max(tp->snd_cwnd, tp->bictcp.last_max_cwnd); + else + tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); if (undo && tp->prior_ssthresh > tp->snd_ssthresh) { tp->snd_ssthresh = tp->prior_ssthresh; @@ -3647,8 +3651,7 @@ tcp_collapse(struct sock *sk, struct sk_ while (before(start, end)) { struct sk_buff *nskb; int header = skb_headroom(skb); - int copy = (PAGE_SIZE - sizeof(struct sk_buff) - - sizeof(struct skb_shared_info) - header - 31)&~15; + int copy = SKB_MAX_ORDER(header, 0); /* Too big header? This can happen with IPv6. */ if (copy < 0) diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/netlink/af_netlink.c linux-2.4.30-rc1/net/netlink/af_netlink.c --- linux-2.4.29/net/netlink/af_netlink.c 2005-01-19 14:10:14.000000000 +0000 +++ linux-2.4.30-rc1/net/netlink/af_netlink.c 2005-03-18 18:07:29.805272320 +0000 @@ -327,10 +327,11 @@ static void netlink_remove(struct sock * struct sock **skp; struct netlink_table *table = &nl_table[sk->protocol]; struct nl_pid_hash *hash = &table->hash; + u32 pid = nlk_sk(sk)->pid; netlink_table_grab(); hash->entries--; - for (skp = hash->table; *skp; skp = &((*skp)->next)) { + for (skp = nl_pid_hashfn(hash, pid); *skp; skp = &((*skp)->next)) { if (*skp == sk) { *skp = sk->next; __sock_put(sk); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/netsyms.c linux-2.4.30-rc1/net/netsyms.c --- linux-2.4.29/net/netsyms.c 2005-01-19 14:10:14.000000000 +0000 +++ linux-2.4.30-rc1/net/netsyms.c 2005-03-18 18:07:13.419763296 +0000 @@ -287,7 +287,6 @@ EXPORT_SYMBOL(ip_dev_find); EXPORT_SYMBOL(inetdev_by_index); EXPORT_SYMBOL(in_dev_finish_destroy); EXPORT_SYMBOL(ip_defrag); -EXPORT_SYMBOL(ipfrag_flush); /* Route manipulation */ EXPORT_SYMBOL(ip_rt_ioctl); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/sched/cls_u32.c linux-2.4.30-rc1/net/sched/cls_u32.c --- linux-2.4.29/net/sched/cls_u32.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/net/sched/cls_u32.c 2005-03-18 18:06:51.712063368 +0000 @@ -70,6 +70,7 @@ struct tc_u_hnode { struct tc_u_hnode *next; u32 handle; + u32 prio; struct tc_u_common *tp_c; int refcnt; unsigned divisor; @@ -271,6 +272,7 @@ static int u32_init(struct tcf_proto *tp root_ht->divisor = 0; root_ht->refcnt++; root_ht->handle = tp_c ? gen_new_htid(tp_c) : 0x80000000; + root_ht->prio = tp->prio; if (tp_c == NULL) { tp_c = kmalloc(sizeof(*tp_c), GFP_KERNEL); @@ -534,6 +536,7 @@ static int u32_change(struct tcf_proto * ht->refcnt = 0; ht->divisor = divisor; ht->handle = handle; + ht->prio = tp->prio; ht->next = tp_c->hlist; tp_c->hlist = ht; *arg = (unsigned long)ht; @@ -606,6 +609,8 @@ static void u32_walk(struct tcf_proto *t return; for (ht = tp_c->hlist; ht; ht = ht->next) { + if (ht->prio != tp->prio) + continue; if (arg->count >= arg->skip) { if (arg->fn(tp, (unsigned long)ht, arg) < 0) { arg->stop = 1; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/sched/sch_ingress.c linux-2.4.30-rc1/net/sched/sch_ingress.c --- linux-2.4.29/net/sched/sch_ingress.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/net/sched/sch_ingress.c 2005-03-18 18:08:04.927932864 +0000 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -241,6 +242,15 @@ static struct nf_hook_ops ing_ops = NF_IP_PRI_FILTER + 1 }; +static struct nf_hook_ops ing6_ops = +{ + { NULL, NULL}, + ing_hook, + PF_INET6, + NF_IP6_PRE_ROUTING, + NF_IP6_PRI_FILTER + 1 +}; + int ingress_init(struct Qdisc *sch,struct rtattr *opt) { struct ingress_qdisc_data *p = PRIV(sch); @@ -249,8 +259,13 @@ int ingress_init(struct Qdisc *sch,struc if (nf_register_hook(&ing_ops) < 0) { printk("ingress qdisc registration error \n"); goto error; - } + } nf_registered++; + if (nf_register_hook(&ing6_ops) < 0) { + printk("IPv6 ingress qdisc registration error, " \ + "disabling IPv6 support.\n"); + } else + nf_registered++; } DPRINTK("ingress_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt); @@ -374,8 +389,11 @@ int init_module(void) void cleanup_module(void) { unregister_qdisc(&ingress_qdisc_ops); - if (nf_registered) + if (nf_registered) { nf_unregister_hook(&ing_ops); + if (nf_registered > 1) + nf_unregister_hook(&ing6_ops); + } } #endif MODULE_LICENSE("GPL"); diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/sched/sch_netem.c linux-2.4.30-rc1/net/sched/sch_netem.c --- linux-2.4.29/net/sched/sch_netem.c 2005-01-19 14:10:14.000000000 +0000 +++ linux-2.4.30-rc1/net/sched/sch_netem.c 2005-03-18 18:07:27.308651864 +0000 @@ -180,6 +180,7 @@ static int netem_enqueue(struct sk_buff if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { pr_debug("netem_enqueue: random loss\n"); sch->stats.drops++; + kfree_skb(skb); return 0; /* lie about loss so TCP doesn't know */ } diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/net/unix/af_unix.c linux-2.4.30-rc1/net/unix/af_unix.c --- linux-2.4.29/net/unix/af_unix.c 2004-11-17 11:54:22.000000000 +0000 +++ linux-2.4.30-rc1/net/unix/af_unix.c 2005-03-18 18:07:44.936971952 +0000 @@ -1686,8 +1686,13 @@ static int unix_ioctl(struct socket *soc } spin_lock(&sk->receive_queue.lock); - if((skb=skb_peek(&sk->receive_queue))!=NULL) - amount=skb->len; + if (sk->type == SOCK_STREAM) { + skb_queue_walk(&sk->receive_queue, skb) + amount += skb->len; + } else { + if((skb=skb_peek(&sk->receive_queue))!=NULL) + amount=skb->len; + } spin_unlock(&sk->receive_queue.lock); err = put_user(amount, (int *)arg); break; diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.29/scripts/Configure linux-2.4.30-rc1/scripts/Configure --- linux-2.4.29/scripts/Configure 2003-06-13 14:51:39.000000000 +0000 +++ linux-2.4.30-rc1/scripts/Configure 2005-03-18 18:06:38.945004256 +0000 @@ -378,15 +378,18 @@ function define_hex () { function hex () { old=$(eval echo "\${$2}") def=${old:-$3} - def=${def#*[x,X]} while :; do readln "$1 ($2) [$def] " "$def" "$old" - ans=${ans#*[x,X]} - if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then + if expr "$ans" : '0x[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then define_hex "$2" "$ans" break else - help "$2" + if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then + define_hex "$2" "0x$ans" + break + else + help "$2" + fi fi done }