]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.4.0-test9 2.4.0-test9
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:39:18 +0000 (15:39 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:39:18 +0000 (15:39 -0500)
    - USB: ohci controller update, round-robin device numbering
    - ksymoops moved: document
    - sparc updates
    - sg.c: get rid of more #ifdef MODULE code

34 files changed:
Documentation/oops-tracing.txt
Documentation/usb/URB.txt
README
arch/sparc/kernel/pcic.c
arch/sparc64/boot/piggyback.c
arch/sparc64/kernel/auxio.c
arch/sparc64/kernel/central.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/starfire.c
arch/sparc64/kernel/time.c
arch/sparc64/mm/init.c
drivers/scsi/sg.c
drivers/usb/dabusb.h
drivers/usb/usb-ohci.c
drivers/usb/usb-ohci.h
drivers/usb/usb-uhci.c
drivers/usb/usb.c
include/asm-alpha/bitops.h
include/asm-sh/atomic.h
include/asm-sparc/atomic.h
include/asm-sparc/bitops.h
include/asm-sparc/system.h
include/asm-sparc64/atomic.h
include/asm-sparc64/bitops.h
include/asm-sparc64/smp.h
include/asm-sparc64/starfire.h [new file with mode: 0644]
include/asm-sparc64/system.h
include/linux/major.h
net/ipv4/arp.c
scripts/ksymoops/README

index 5510e53496adc7e09f20d1cf6e2653dba40e0563..21ffe7b06bd4d1fd62d717302ebd7a73c5dc6c1a 100644 (file)
@@ -1,7 +1,8 @@
 Quick Summary
 -------------
 
-Install ksymoops from ftp://ftp.ocs.com.au/pub/ksymoops
+Install ksymoops from
+ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops
 Read the ksymoops man page.
 ksymoops < the_oops.txt
 
index 3fc29d1f29aafda4d700a3a0c4af6e6c4bc4fb1f..7d99567adcdd753ad7fdf98d0c50057dd71e7d5a 100644 (file)
@@ -44,7 +44,7 @@ typedef struct urb
 
 // status after each completion
        int status;                     // returned status
-       unsigned int transfer_flags;    // ASAP, SP_OK, EARLY_COMPLETE
+       unsigned int transfer_flags;    // ASAP, SP_OK, etc.
 
 // for data stage (CTRL), BULK, INT and ISO
        void *transfer_buffer;          // associated data buffer
@@ -105,10 +105,9 @@ For ASAP set USB_ISO_ASAP in transfer_flags.
 If short packets should NOT be tolerated, set USB_DISABLE_SPD in 
 transfer_flags.
 
-Usually, (to reduce restart time) the completion handler is called
-AFTER the URB re-submission. You can get the other way by setting
-USB_URB_EARLY_COMPLETE in transfer_flags. This is implicit for
-INT transfers.
+Usually, to reduce restart time, the completion handler is called
+AFTER the URB re-submission.  However, it is called BEFORE URB
+re-submission for INT transfers that are being continued.
 
 
 1.5. How to submit an URB?
@@ -172,10 +171,12 @@ In the completion handler, you should have a look at urb->status to
 detect any USB errors. Since the context parameter is included in the URB,
 you can pass information to the completion handler. 
 
-Avoid using the urb->dev field in your completion handler; it's cleared
+NOTE:  ***** WARNING *****
+AVOID using the urb->dev field in your completion handler; it's cleared
 as part of URB unlinking.  Instead, use urb->context to hold all the
 data your driver needs.
 
+NOTE:  ***** WARNING *****
 Also, NEVER SLEEP IN A COMPLETION HANDLER.  These are normally called
 during hardware interrupt processing.  If you can, defer substantial
 work to a tasklet (bottom half) to keep system latencies low.  You'll
diff --git a/README b/README
index d77afd45ef76242321720cee8061f8cea85df772..fa9492f80d01c4a3d6b160c3bdb252401339db59 100644 (file)
--- a/README
+++ b/README
@@ -270,7 +270,8 @@ IF SOMETHING GOES WRONG:
    on making sense of the dump is in Documentation/oops-tracing.txt
 
  - You can use the "ksymoops" program to make sense of the dump.  This
-   utility can be downloaded from ftp://ftp.ocs.com.au/pub/ksymoops .
+   utility can be downloaded from
+   ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops.
    Alternately you can do the dump lookup by hand:
 
  - In debugging dumps like the above, it helps enormously if you can
index 293cf43f9598f81b84d772b1a1cf74a742bc38f2..02861268758592484d907abbddc1a4a515c90e35 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pcic.c,v 1.17 2000/09/05 06:49:44 anton Exp $
+/* $Id: pcic.c,v 1.18 2000/09/25 06:09:12 anton Exp $
  * pcic.c: Sparc/PCI controller support
  *
  * Copyright (C) 1998 V. Roganov and G. Raiko
 
 #ifndef CONFIG_PCI
 
-int pcibios_present(void)
-{
-       return 0;
-}
-
 asmlinkage int sys_pciconfig_read(unsigned long bus,
                                  unsigned long dfn,
                                  unsigned long off,
@@ -976,7 +971,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
        if(!suser())
                return -EPERM;
 
-       lock_kernel();
        switch(len) {
        case 1:
                err = get_user(ubyte, (unsigned char *)buf);
@@ -1004,7 +998,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
                break;
 
        };
-       unlock_kernel();
 
        return err;
 }                         
index 503b366db695b609630e0cd2593a4eef039def63..36f907408c601ae1bf5cb6859f5a85d70e8452f4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: piggyback.c,v 1.1 1997/07/11 11:05:26 jj Exp $
+/* $Id: piggyback.c,v 1.2 2000/09/19 14:34:39 anton Exp $
    Simple utility to make a single-image install kernel with initial ramdisk
    for Sparc64 tftpbooting without need to set up nfs.
    
@@ -50,9 +50,9 @@ int main(int argc,char **argv)
        map = fopen (argv[2], "r");
        if (!map) die(argv[2]);
        while (fgets (buffer, 1024, map)) {
-               if (!strcmp (buffer + 19, "start\n"))
+               if (!strcmp (buffer + 19, "_start\n"))
                start = strtoul (buffer + 8, NULL, 16);
-               else if (!strcmp (buffer + 19, "end\n"))
+               else if (!strcmp (buffer + 19, "_end\n"))
                end = strtoul (buffer + 8, NULL, 16);
        }
        fclose (map);
index 9be09c3b01e99434412b662dd2d7f9db1b319c6e..cc26817b40f6895d5096892add86d104a3d733cd 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/sbus.h>
 #include <asm/ebus.h>
 #include <asm/fhc.h>
+#include <asm/starfire.h>
 
 /* Probe and map in the Auxiliary I/O register */
 unsigned long auxio_register = 0;
@@ -55,7 +56,7 @@ found_sdev:
                        return;
                }
 #endif
-               if(central_bus) {
+               if(central_bus || this_is_starfire) {
                        auxio_register = 0UL;
                        return;
                }
index 2c4fb1355fda05d3fcb1c76390b4a6a55efc68f8..dba732a6d9e52ef75e4da7d3c7640adf876e75ad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: central.c,v 1.13 1999/12/01 10:44:43 davem Exp $
+/* $Id: central.c,v 1.14 2000/09/21 06:25:14 anton Exp $
  * central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
  *
  * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
@@ -15,6 +15,7 @@
 
 #include <asm/page.h>
 #include <asm/fhc.h>
+#include <asm/starfire.h>
 
 struct linux_central *central_bus = NULL;
 struct linux_fhc *fhc_list = NULL;
@@ -254,9 +255,8 @@ void central_probe(void)
 
        cnode = prom_finddevice("/central");
        if(cnode == 0 || cnode == -1) {
-               extern void starfire_check(void);
-
-               starfire_check();
+               if (this_is_starfire)
+                       starfire_cpu_setup();
                return;
        }
 
index daefe6d4386f0b3003a989ba134ed46aa00e0392..92bd3ed88a981bb24ee0f970a7f257d8811b18b7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.93 2000/08/31 10:00:39 anton Exp $
+/* $Id: irq.c,v 1.94 2000/09/21 06:27:10 anton Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
@@ -31,6 +31,7 @@
 #include <asm/smp.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
+#include <asm/starfire.h>
 
 /* Internal flag, should not be visible elsewhere at all. */
 #define SA_IMAP_MASKED         0x100
@@ -123,7 +124,6 @@ int get_irq_list(char *buf)
 /* Now these are always passed a true fully specified sun4u INO. */
 void enable_irq(unsigned int irq)
 {
-       extern int this_is_starfire;
        struct ino_bucket *bucket = __bucket(irq);
        unsigned long imap;
        unsigned long tid;
@@ -139,9 +139,6 @@ void enable_irq(unsigned int irq)
                                     : "i" (ASI_UPA_CONFIG));
                tid = ((tid & UPA_CONFIG_MID) << 9);
        } else {
-               extern unsigned int starfire_translate(unsigned long imap,
-                                                      unsigned int upaid);
-
                tid = (starfire_translate(imap, current->processor) << 26);
        }
 
@@ -715,7 +712,6 @@ void handler_irq(int irq, struct pt_regs *regs)
        struct ino_bucket *bp, *nbp;
        int cpu = smp_processor_id();
 #ifdef CONFIG_SMP
-       extern int this_is_starfire;
        int should_forward = (this_is_starfire == 0     &&
                              irq < 10                  &&
                              current->pid != 0);
@@ -1029,7 +1025,6 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
 #ifdef CONFIG_SMP
 static int retarget_one_irq(struct irqaction *p, int goal_cpu)
 {
-       extern int this_is_starfire;
        struct ino_bucket *bucket = __bucket(p->mask);
        unsigned long imap = bucket->imap;
        unsigned int tid;
@@ -1041,9 +1036,6 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
        if(this_is_starfire == 0) {
                tid = __cpu_logical_map[goal_cpu] << 26;
        } else {
-               extern unsigned int starfire_translate(unsigned long imap,
-                                                      unsigned int upaid);
-
                tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26);
        }
        upa_writel(IMAP_VALID | (tid & IMAP_TID), imap);
index 8af0c0f1caf905883ab70c5d8897a3ea76ddaeab..24b1a7217f182bad08bb0738c4460b6905babe6f 100644 (file)
@@ -24,7 +24,6 @@ unsigned long pci_memspace_mask = 0xffffffffUL;
 
 #ifndef CONFIG_PCI
 /* A "nop" PCI implementation. */
-int pcibios_present(void) { return 0; }
 asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
                                  unsigned long off, unsigned long len,
                                  unsigned char *buf)
@@ -316,7 +315,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
                goto out;
        }
 
-       lock_kernel();
        switch(len) {
        case 1:
                err = get_user(byte, (u8 *)buf);
@@ -344,7 +342,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
                break;
 
        };
-       unlock_kernel();
 
 out:
        return err;
index 8d7db0c9bc7aabe7bc5d399244ffda292dfcea38..aff2de59469998a252b40edc64154454bfc4fd37 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.16 2000/04/15 10:06:16 davem Exp $
+/* $Id: pci_psycho.c,v 1.17 2000/09/21 06:25:14 anton Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -15,6 +15,7 @@
 #include <asm/pbm.h>
 #include <asm/iommu.h>
 #include <asm/irq.h>
+#include <asm/starfire.h>
 
 #include "pci_impl.h"
 
@@ -1254,8 +1255,6 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
 
 static void __init psycho_iommu_init(struct pci_controller_info *p)
 {
-       extern int this_is_starfire;
-       extern void *starfire_hookup(int);
        unsigned long tsbbase, i;
        u64 control;
 
index 602ee9ca2b3ce7e8330449af527d93109e337162..7baebc89e86dbaff71031b4c897192c5ad93851e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $
+/* $Id: sbus.c,v 1.12 2000/09/21 06:25:14 anton Exp $
  * sbus.c: UltraSparc SBUS controller support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -18,6 +18,7 @@
 #include <asm/cache.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
+#include <asm/starfire.h>
 
 #include "iommu_common.h"
 
@@ -1151,15 +1152,10 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus)
        upa_writeq(control, iommu->sbus_control_reg);
 
        /* Now some Xfire specific grot... */
-       {
-               extern void *starfire_hookup(int);
-               extern int this_is_starfire;
-
-               if (this_is_starfire)
-                       sbus->starfire_cookie = starfire_hookup(sbus->portid);
-               else
-                       sbus->starfire_cookie = NULL;
-       }
+       if (this_is_starfire)
+               sbus->starfire_cookie = starfire_hookup(sbus->portid);
+       else
+               sbus->starfire_cookie = NULL;
 
        sysio_register_error_handlers(sbus);
 }
index 486254fb9543491b4f67bef2c0fcb1145f2c1c91..84cc201fd49ec3bee5396f597dbe4b1444160d91 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.55 2000/07/24 14:13:13 anton Exp $
+/*  $Id: setup.c,v 1.56 2000/09/21 06:29:01 anton Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -37,6 +37,7 @@
 #include <asm/pgtable.h>
 #include <asm/idprom.h>
 #include <asm/head.h>
+#include <asm/starfire.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
@@ -479,6 +480,9 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &prom_con;
 #endif
 
+       /* Work out if we are starfire early on */
+       check_if_starfire();
+
        boot_flags_init(*cmdline_p);
 
        idprom_init();
index 8ff7ea4d2435f06c71ac32b163fe8186962f68fe..dc8f96b7a6b0ec4db5fb3a522db00d4bfdcea531 100644 (file)
@@ -1,7 +1,8 @@
-/* $Id: starfire.c,v 1.5 2000/01/31 04:59:12 davem Exp $
+/* $Id: starfire.c,v 1.7 2000/09/22 23:02:13 davem Exp $
  * starfire.c: Starfire/E10000 support.
  *
  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
  */
 
 #include <linux/kernel.h>
 #include <asm/oplib.h>
 #include <asm/smp.h>
 #include <asm/upa.h>
+#include <asm/starfire.h>
 
-/* A few places around the kernel check this to see if
+/*
+ * A few places around the kernel check this to see if
  * they need to call us to do things in a Starfire specific
  * way.
  */
 int this_is_starfire = 0;
 
-void starfire_check(void)
+void check_if_starfire(void)
 {
        int ssnode = prom_finddevice("/ssp-serial");
+       if(ssnode != 0 && ssnode != -1)
+               this_is_starfire = 1;
+}
 
-       if(ssnode != 0 && ssnode != -1) {
+void starfire_cpu_setup(void)
+{
+       if (this_is_starfire) {
+/* We do this in starfire_translate - Anton */
+#if 0
                int i;
 
-               this_is_starfire = 1;
-
-               /* Now must fixup cpu MIDs.  OBP gave us a logical
+               /*
+                * Now must fixup cpu MIDs.  OBP gave us a logical
                 * linear cpuid number, not the real upaid.
                 */
                for(i = 0; i < linux_num_cpus; i++) {
@@ -39,6 +48,7 @@ void starfire_check(void)
 
                        linux_cpus[i].mid = mid;
                }
+#endif
        }
 }
 
@@ -47,7 +57,8 @@ int starfire_hard_smp_processor_id(void)
        return upa_readl(0x1fff40000d0UL);
 }
 
-/* Each Starfire board has 32 registers which perform translation
+/*
+ * Each Starfire board has 32 registers which perform translation
  * and delivery of traditional interrupt packets into the extended
  * Starfire hardware format.  Essentially UPAID's now have 2 more
  * bits than in all previous Sun5 systems.
@@ -82,6 +93,9 @@ void *starfire_hookup(int upaid)
        for(i = 0; i < 32; i++) {
                p->imap_slots[i] = 0UL;
                p->tregs[i] = treg_base + (i * 0x10UL);
+               /* Lets play it safe and not overwrite existing mappings */
+               if (upa_readl(p->tregs[i]) != 0)
+                       p->imap_slots[i] = 0xdeadbeaf;
        }
        p->upaid = upaid;
        p->next = sflist;
@@ -116,6 +130,12 @@ unsigned int starfire_translate(unsigned long imap,
                panic("Lucy in the sky....");
        }
        p->imap_slots[i] = imap;
+
+       /* map to real upaid */
+       upaid = (((upaid & 0x3c) << 1) |
+              ((upaid & 0x40) >> 4) |
+              (upaid & 0x3));
+
        upa_writel(upaid, p->tregs[i]);
 
        return i;
index 3c989847743a001d73c903967c753ed59770bd16..0264f94189a74dd8688127f44f5c03a0d007d8a1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.29 2000/09/16 07:33:45 davem Exp $
+/* $Id: time.c,v 1.32 2000/09/22 23:02:13 davem Exp $
  * time.c: UltraSparc timer and TOD clock support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -30,6 +30,7 @@
 #include <asm/fhc.h>
 #include <asm/pbm.h>
 #include <asm/ebus.h>
+#include <asm/starfire.h>
 
 extern rwlock_t xtime_lock;
 
@@ -305,6 +306,20 @@ void __init clock_probe(void)
        struct linux_ebus *ebus = NULL;
 #endif
 
+
+       if (this_is_starfire) {
+               /* davem suggests we keep this within the 4M locked kernel image */
+               static char obp_gettod[256];
+               static u32 unix_tod;
+
+               sprintf(obp_gettod, "h# %08x unix-gettod",
+                       (unsigned int) (long) &unix_tod);
+               prom_feval(obp_gettod);
+               xtime.tv_sec = unix_tod;
+               xtime.tv_usec = 0;
+               return;
+       }
+
        __save_and_cli(flags);
 
        if(central_bus != NULL) {
@@ -473,6 +488,9 @@ static __inline__ unsigned long do_gettimeoffset(void)
 
 void do_settimeofday(struct timeval *tv)
 {
+       if (this_is_starfire)
+               return;
+
        write_lock_irq(&xtime_lock);
 
        tv->tv_usec -= do_gettimeoffset();
@@ -496,7 +514,10 @@ static int set_rtc_mmss(unsigned long nowtime)
        unsigned long regs = mstk48t02_regs;
        u8 tmp;
 
-       /* Not having a register set can lead to trouble. */
+       /* 
+        * Not having a register set can lead to trouble.
+        * Also starfire doesnt have a tod clock.
+        */
        if (!regs) 
                return -1;
 
index d00faa92231eb732a4a9a922a0804ade70e367a4..d694e40f9c3fdb2c0b12c9014e65cf59cebda3e8 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.155 2000/09/09 00:02:19 davem Exp $
+/*  $Id: init.c,v 1.156 2000/09/21 06:34:48 anton Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -29,6 +29,7 @@
 #include <asm/mmu_context.h>
 #include <asm/vaddrs.h>
 #include <asm/dma.h>
+#include <asm/starfire.h>
 
 extern void device_scan(void);
 
@@ -200,7 +201,7 @@ static void inherit_prom_mappings(void)
 
        for (i = 0; i < n; i++) {
                unsigned long vaddr;
-               
+
                if (trans[i].virt >= 0xf0000000 && trans[i].virt < 0x100000000) {
                        for (vaddr = trans[i].virt;
                             vaddr < trans[i].virt + trans[i].size;
@@ -808,7 +809,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
        unsigned long bootmap_pfn, bytes_avail, size;
        int i;
 
-
        bytes_avail = 0UL;
        for (i = 0; sp_banks[i].num_bytes != 0; i++) {
                end_of_phys_memory = sp_banks[i].base_addr +
@@ -999,12 +999,7 @@ void __init paging_init(void)
         */
        {
                extern void setup_tba(int);
-               int is_starfire = prom_finddevice("/ssp-serial");
-               if (is_starfire != 0 && is_starfire != -1)
-                       is_starfire = 1;
-               else
-                       is_starfire = 0;
-               setup_tba(is_starfire);
+               setup_tba(this_is_starfire);
        }
 
        inherit_locked_prom_mappings(1);
index 2e512345b503ac94d794c407a748de95e2119401..6d5b92f1fbef0bb19d0f03ba6f59d9562f46fcd0 100644 (file)
@@ -19,7 +19,7 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char * sg_version_str = "Version: 3.1.17 (20000921)";
+ static char * sg_version_str = "Version: 3.1.17 (20001002)";
 #endif
  static int sg_version_num = 30117; /* 2 digits for each component */
 /*
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 static int sg_proc_init(void);
-#ifdef MODULE
 static void sg_proc_cleanup(void);
 #endif
-#endif
 
 #ifndef LINUX_VERSION_CODE
 #include <linux/version.h>
@@ -271,7 +269,8 @@ static int sg_open(struct inode * inode, struct file * filp)
      * else try and use this device.  Also, if error recovery fails, it
      * may try and take the device offline, in which case all further
      * access to the device is prohibited.  */
-    if(! scsi_block_when_processing_errors(sdp->device))
+    if (! ((flags & O_NONBLOCK) || 
+          scsi_block_when_processing_errors(sdp->device)))
         return -ENXIO;
 
     SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
@@ -279,7 +278,7 @@ static int sg_open(struct inode * inode, struct file * filp)
     if (flags & O_EXCL) {
         if (O_RDONLY == (flags & O_ACCMODE))
             return -EACCES;   /* Can't lock it with read only access */
-        if (sdp->headfp && (filp->f_flags & O_NONBLOCK))
+        if (sdp->headfp && (flags & O_NONBLOCK))
             return -EBUSY;
         res = 0;  /* following is a macro that beats race condition */
        __wait_event_interruptible(sdp->o_excl_wait,
@@ -289,7 +288,7 @@ static int sg_open(struct inode * inode, struct file * filp)
             return res; /* -ERESTARTSYS because signal hit process */
     }
     else if (sdp->exclude) { /* some other fd has an exclusive lock on dev */
-        if (filp->f_flags & O_NONBLOCK)
+        if (flags & O_NONBLOCK)
             return -EBUSY;
         res = 0;  /* following is a macro that beats race condition */
         __wait_event_interruptible(sdp->o_excl_wait, (! sdp->exclude), res);
@@ -353,9 +352,6 @@ static ssize_t sg_read(struct file * filp, char * buf,
         return -ENXIO;
     SCSI_LOG_TIMEOUT(3, printk("sg_read: dev=%d, count=%d\n",
                                MINOR(sdp->i_rdev), (int)count));
-
-    if(! scsi_block_when_processing_errors(sdp->device))
-        return -ENXIO;
     if (ppos != &filp->f_pos)
         ; /* FIXME: Hmm.  Seek to the right place, or fail?  */
     if ((k = verify_area(VERIFY_WRITE, buf, count)))
@@ -451,15 +447,11 @@ static ssize_t sg_read(struct file * filp, char * buf,
 static ssize_t sg_new_read(Sg_fd * sfp, char * buf, size_t count,
                           Sg_request * srp)
 {
-    Sg_device           * sdp = sfp->parentdp;
     sg_io_hdr_t         * hp = &srp->header;
     int                   k, len;
 
-    if(! scsi_block_when_processing_errors(sdp->device) )
-       return -ENXIO;
     if (count < size_sg_io_hdr)
        return -EINVAL;
-
     hp->sb_len_wr = 0;
     if ((hp->mx_sb_len > 0) && hp->sbp) {
        if ((CHECK_CONDITION & hp->masked_status) ||
@@ -503,7 +495,8 @@ static ssize_t sg_write(struct file * filp, const char * buf,
     SCSI_LOG_TIMEOUT(3, printk("sg_write: dev=%d, count=%d\n",
                                MINOR(sdp->i_rdev), (int)count));
 
-    if(! scsi_block_when_processing_errors(sdp->device) )
+    if (! ((filp->f_flags & O_NONBLOCK) ||
+           scsi_block_when_processing_errors(sdp->device)))
         return -ENXIO;
     if (ppos != &filp->f_pos)
         ; /* FIXME: Hmm.  Seek to the right place, or fail?  */
@@ -712,8 +705,6 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
         return -ENXIO;
     SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: dev=%d, cmd=0x%x\n",
                                MINOR(sdp->i_rdev), (int)cmd_in));
-    if(! scsi_block_when_processing_errors(sdp->device) )
-        return -ENXIO;
     read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
 
     switch(cmd_in)
@@ -885,7 +876,11 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
     case SG_EMULATED_HOST:
         return put_user(sdp->device->host->hostt->emulated, (int *)arg);
     case SG_SCSI_RESET:
-        if (! scsi_block_when_processing_errors(sdp->device))
+        if (filp->f_flags & O_NONBLOCK) {
+           if (sdp->device->host->in_recovery)
+               return -EBUSY;
+       }
+       else if (! scsi_block_when_processing_errors(sdp->device))
             return -EBUSY;
         result = get_user(val, (int *)arg);
         if (result) return result;
@@ -1301,16 +1296,14 @@ static void sg_detach(Scsi_Device * scsidp)
     return;
 }
 
-#ifdef MODULE
+MODULE_AUTHOR("Douglas Gilbert");
+MODULE_DESCRIPTION("SCSI generic (sg) driver");
 MODULE_PARM(def_reserved_size, "i");
 MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
-#endif /* MODULE */
 
 static int __init init_sg(void) {
-#ifdef MODULE
     if (def_reserved_size >= 0)
        sg_big_buff = def_reserved_size;
-#endif /* MODULE */
     sg_template.module = THIS_MODULE;
     return scsi_register_module(MODULE_SCSI_DEV, &sg_template);
 }
@@ -2551,7 +2544,6 @@ static int sg_proc_init()
     return 0;
 }
 
-#ifdef MODULE
 static void sg_proc_cleanup()
 {
     int k;
@@ -2563,7 +2555,6 @@ static void sg_proc_cleanup()
        remove_proc_entry(sg_proc_leaf_names[k], sg_proc_sgp);
     remove_proc_entry(sg_proc_sg_dirname, proc_scsi);
 }
-#endif
 
 static int sg_proc_dressz_read(char * buffer, char ** start, off_t offset,
                               int size, int * eof, void * data)
index 82877003c00874d274699cea527adcab2d810aee..ddb4d8971573fc32e01c19912b0bf88b72933dfa 100644 (file)
@@ -23,7 +23,7 @@ typedef struct
        wait_queue_head_t wait;
        wait_queue_head_t remove_ok;
        spinlock_t lock;
-       volatile atomic_t pending_io;
+       atomic_t pending_io;
        driver_state_t state;
        int remove_pending;
        int got_mem;
index 339b93965e75dd0450c346639f6f0e8fe41aedf6..4fb391a8b9bbfba2bbb8c4bb3590f5024f5eda04 100644 (file)
  * 
  * History:
  * 
+ * 2000/09/26 fixed races in removing the private portion of the urb
+ * 2000/09/07 disable bulk and control lists when unlinking the last
+ *     endpoint descriptor in order to avoid unrecoverable errors on
+ *     the Lucent chips.
  * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
  *     urb unlink probs, indentation fixes
  * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
@@ -78,8 +82,9 @@
 
 /* For initializing controller (mask in an HCFS mode too) */
 #define        OHCI_CONTROL_INIT \
-       (OHCI_CTRL_CBSR & 0x3) \
-       | OHCI_CTRL_BLE | OHCI_CTRL_CLE | OHCI_CTRL_IE | OHCI_CTRL_PLE
+       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define OHCI_UNLINK_TIMEOUT    (HZ / 10)
 
 static LIST_HEAD (ohci_hcd_list);
 static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
@@ -89,36 +94,54 @@ static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
  *-------------------------------------------------------------------------*/ 
  
 /* free HCD-private data associated with this URB */
-static void urb_rm_priv (urb_t * urb) 
+
+static void urb_free_priv (urb_priv_t * urb_priv)
 {
-       urb_priv_t * urb_priv = urb->hcpriv;
        int i;
-       
-       /* Release int/iso bandwidth for Interrupt or Isoc. transfers */
-       if (urb->bandwidth) {
-               switch (usb_pipetype(urb->pipe)) {
-               case PIPE_INTERRUPT:
-                       usb_release_bandwidth (urb->dev, urb, 0);
-                       break;
-               case PIPE_ISOCHRONOUS:
-                       usb_release_bandwidth (urb->dev, urb, 1);
-                       break;
-               default:
-                       break;
-               }
-       }
 
-       if (!urb_priv)
-               return;
        for (i = 0; i < urb_priv->length; i++) {
                if (urb_priv->td [i]) {
                        OHCI_FREE (urb_priv->td [i]);
                }
        }
-       kfree (urb->hcpriv);
-       urb->hcpriv = NULL;
 
+       kfree (urb_priv);
+}
+static void urb_rm_priv_locked (urb_t * urb) 
+{
+       urb_priv_t * urb_priv = urb->hcpriv;
+       
+       if (urb_priv) {
+               urb->hcpriv = NULL;
+
+               /* Release int/iso bandwidth */
+               if (urb->bandwidth) {
+                       switch (usb_pipetype(urb->pipe)) {
+                       case PIPE_INTERRUPT:
+                               usb_release_bandwidth (urb->dev, urb, 0);
+                               break;
+                       case PIPE_ISOCHRONOUS:
+                               usb_release_bandwidth (urb->dev, urb, 1);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               urb_free_priv (urb_priv);
+               usb_dec_dev_use (urb->dev);
+               urb->dev = NULL;
+       }
+}
+
+static void urb_rm_priv (urb_t * urb)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave (&usb_ed_lock, flags);
+       urb_rm_priv_locked (urb);
+       spin_unlock_irqrestore (&usb_ed_lock, flags);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -366,15 +389,15 @@ static int sohci_return_urb (urb_t * urb)
        unsigned long flags;
        int i;
        
+       if (!urb_priv)
+               return -1; /* urb already unlinked */
+
        /* just to be sure */
        if (!urb->complete) {
                urb_rm_priv (urb);
-               usb_dec_dev_use (urb->dev);
                return -1;
        }
        
-       if (!urb_priv) return -1; /* urb already unlinked */
-       
 #ifdef DEBUG
        urb_print (urb, "RET", usb_pipeout (urb->pipe));
 #endif
@@ -408,7 +431,6 @@ static int sohci_return_urb (urb_t * urb)
                                
                        } else { /* unlink URB, call complete */
                                urb_rm_priv (urb);
-                               usb_dec_dev_use (urb->dev);
                                urb->complete (urb);    
                        }               
                        break;
@@ -416,7 +438,6 @@ static int sohci_return_urb (urb_t * urb)
                case PIPE_BULK:
                case PIPE_CONTROL: /* unlink URB, call complete */
                        urb_rm_priv (urb);
-                       usb_dec_dev_use (urb->dev);
                        urb->complete (urb);    
                        break;
        }
@@ -438,7 +459,7 @@ static int sohci_submit_urb (urb_t * urb)
        int bustime = 0;
        
        if (!urb->dev || !urb->dev->bus)
-               return -EINVAL;
+               return -ENODEV;
        
        if (urb->hcpriv)                        /* urb already in use */
                return -EINVAL;
@@ -453,7 +474,7 @@ static int sohci_submit_urb (urb_t * urb)
        urb_print (urb, "SUB", usb_pipein (pipe));
 #endif
        
-       /* a request to the virtual root hub */
+       /* handle a request to the virtual root hub */
        if (usb_pipedevice (pipe) == ohci->rh.devnum) 
                return rh_submit_urb (urb);
        
@@ -505,26 +526,22 @@ static int sohci_submit_urb (urb_t * urb)
        memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
        
        /* fill the private part of the URB */
-       urb->hcpriv = urb_priv;
        urb_priv->length = size;
-       urb_priv->td_cnt = 0;
-       urb_priv->state = 0;
        urb_priv->ed = ed;      
 
        /* allocate the TDs */
        for (i = 0; i < size; i++) { 
                OHCI_ALLOC (urb_priv->td[i], sizeof (td_t));
                if (!urb_priv->td[i]) {
-                       urb_rm_priv (urb);
+                       urb_free_priv (urb_priv);
                        usb_dec_dev_use (urb->dev);     
                        return -ENOMEM;
                }
        }       
-       spin_lock_irqsave (&usb_ed_lock, flags);        
+
        if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
-               urb_rm_priv(urb);
+               urb_free_priv (urb_priv);
                usb_dec_dev_use (urb->dev);     
-               spin_unlock_irqrestore(&usb_ed_lock, flags);
                return -EINVAL;
        }
        
@@ -544,23 +561,24 @@ static int sohci_submit_urb (urb_t * urb)
                                bustime = usb_check_bandwidth (urb->dev, urb);
                        }
                        if (bustime < 0) {
-                               urb_rm_priv (urb);
+                               urb_free_priv (urb_priv);
                                usb_dec_dev_use (urb->dev);     
-                               spin_unlock_irqrestore (&usb_ed_lock, flags);
                                return bustime;
                        }
                        usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
        }
-       
-       urb->status = USB_ST_URB_PENDING;
+
+       spin_lock_irqsave (&usb_ed_lock, flags);
        urb->actual_length = 0;
-       
-       if (ed->state != ED_OPER)  /* link the ed into a chain if is not already */
+       urb->hcpriv = urb_priv;
+       urb->status = USB_ST_URB_PENDING;
+
+       /* link the ed into a chain if is not already */
+       if (ed->state != ED_OPER)
                ep_link (ohci, ed);
-       
-       urb->status = USB_ST_URB_PENDING; 
-       td_submit_urb (urb); /* fill the TDs and link it to the ed */
 
+       /* fill the TDs and link it to the ed */
+       td_submit_urb (urb);
        spin_unlock_irqrestore (&usb_ed_lock, flags);
 
        return 0;       
@@ -570,7 +588,7 @@ static int sohci_submit_urb (urb_t * urb)
 
 /* deactivate all TDs and remove the private part of the URB */
 /* interrupt callers must use async unlink mode */
+
 static int sohci_unlink_urb (urb_t * urb)
 {
        unsigned long flags;
@@ -587,16 +605,14 @@ static int sohci_unlink_urb (urb_t * urb)
 #ifdef DEBUG
        urb_print (urb, "UNLINK", 1);
 #endif           
-       
-       if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) {
-               usb_dec_dev_use(urb->dev);
-               return rh_unlink_urb (urb); /* a request to the virtual root hub */
-       }
 
-       if (urb->hcpriv) { 
-               /* URB active? */
-               if (urb->status == USB_ST_URB_PENDING && !ohci->disabled) {
-                       urb_priv_t  * urb_priv = urb->hcpriv;
+       /* handle a request to the virtual root hub */
+       if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
+               return rh_unlink_urb (urb);
+
+       if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) { 
+               if (!ohci->disabled) {
+                       urb_priv_t  * urb_priv;
 
                        /* interrupt code may not sleep; it must use
                         * async status return to unlink pending urbs.
@@ -608,44 +624,50 @@ static int sohci_unlink_urb (urb_t * urb)
                                return -EWOULDBLOCK;
                        }
 
-
                        /* flag the urb and its TDs for deletion in some
                         * upcoming SF interrupt delete list processing
                         */
-                       urb_priv->state = URB_DEL; 
-                       
                        spin_lock_irqsave (&usb_ed_lock, flags);
+                       urb_priv = urb->hcpriv;
 
-                       if (urb_priv->ed->state == ED_OPER)
-                               ep_unlink(ohci, urb_priv->ed);
-
+                       if (!urb_priv || (urb_priv->state == URB_DEL)) {
+                               spin_unlock_irqrestore (&usb_ed_lock, flags);
+                               return 0;
+                       }
+                               
+                       urb_priv->state = URB_DEL; 
                        ep_rm_ed (urb->dev, urb_priv->ed);
                        urb_priv->ed->state |= ED_URB_DEL;
-                       spin_unlock_irqrestore (&usb_ed_lock, flags);
 
                        if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
                                DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
                                DECLARE_WAITQUEUE (wait, current);
+                               int timeout = OHCI_UNLINK_TIMEOUT;
 
-                               usb_dec_dev_use (urb->dev);     
-                               /* wait until all TDs are deleted */
                                add_wait_queue (&unlink_wakeup, &wait);
                                urb_priv->wait = &unlink_wakeup;
-                               current->state = TASK_UNINTERRUPTIBLE;
-                               schedule ();
+                               spin_unlock_irqrestore (&usb_ed_lock, flags);
+
+                               /* wait until all TDs are deleted */
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               while (timeout && (urb->status == USB_ST_URB_PENDING))
+                                       timeout = schedule_timeout (timeout);
                                remove_wait_queue (&unlink_wakeup, &wait); 
-                               urb->status = -ENOENT;
-                               urb_priv->wait = 0;
+                               if (urb->status == USB_ST_URB_PENDING) {
+                                       err ("unlink URB timeout");
+                                       return -ETIMEDOUT;
+                               }
                        } else {
                                /* usb_dec_dev_use done in dl_del_list() */
                                urb->status = -EINPROGRESS;
+                               spin_unlock_irqrestore (&usb_ed_lock, flags);
                        }
                } else {
                        urb_rm_priv (urb);
-                       usb_dec_dev_use (urb->dev);     
-                       if (urb->complete && (urb->transfer_flags & USB_ASYNC_UNLINK)) {
-                               urb->complete (urb); 
-                               urb->status = 0;        
+                       if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+                               urb->status = -ECONNRESET;
+                               if (urb->complete)
+                                       urb->complete (urb); 
                        } else 
                                urb->status = -ENOENT;
                }       
@@ -729,14 +751,19 @@ static int sohci_free_dev (struct usb_device * usb_dev)
                        } else if (!in_interrupt ()) {
                                DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup); 
                                DECLARE_WAITQUEUE (wait, current);
+                               int timeout = OHCI_UNLINK_TIMEOUT;
 
                                /* SF interrupt handler calls dl_del_list */
                                add_wait_queue (&freedev_wakeup, &wait);
                                dev->wait = &freedev_wakeup;
-                               current->state = TASK_UNINTERRUPTIBLE;
-                               schedule ();
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               while (timeout && dev->ed_cnt)
+                                       timeout = schedule_timeout (timeout);
                                remove_wait_queue (&freedev_wakeup, &wait);
-
+                               if (dev->ed_cnt) {
+                                       err ("free device %d timeout", usb_dev->devnum);
+                                       return -ETIMEDOUT;
+                               }
                        } else {
                                /* likely some interface's driver has a refcount bug */
                                err ("bus %s devnum %d deletion in interrupt",
@@ -836,7 +863,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
        ed->state = ED_OPER;
        
        switch (ed->type) {
-       case CTRL:
+       case PIPE_CONTROL:
                ed->hwNextED = 0;
                if (ohci->ed_controltail == NULL) {
                        writel (virt_to_bus (ed), &ohci->regs->ed_controlhead);
@@ -844,10 +871,15 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
                        ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
                }
                ed->ed_prev = ohci->ed_controltail;
+               if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+                       !ohci->ed_rm_list[1]) {
+                       ohci->hc_control |= OHCI_CTRL_CLE;
+                       writel (ohci->hc_control, &ohci->regs->control);
+               }
                ohci->ed_controltail = edi;       
                break;
                
-       case BULK:  
+       case PIPE_BULK:
                ed->hwNextED = 0;
                if (ohci->ed_bulktail == NULL) {
                        writel (virt_to_bus (ed), &ohci->regs->ed_bulkhead);
@@ -855,10 +887,15 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
                        ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
                }
                ed->ed_prev = ohci->ed_bulktail;
+               if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+                       !ohci->ed_rm_list[1]) {
+                       ohci->hc_control |= OHCI_CTRL_BLE;
+                       writel (ohci->hc_control, &ohci->regs->control);
+               }
                ohci->ed_bulktail = edi;          
                break;
                
-       case INT:
+       case PIPE_INTERRUPT:
                load = ed->int_load;
                interval = ep_2_n_interval (ed->int_period);
                ed->int_interval = interval;
@@ -879,7 +916,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
 #endif
                break;
                
-       case ISO:
+       case PIPE_ISOCHRONOUS:
                ed->hwNextED = 0;
                ed->int_interval = 1;
                if (ohci->ed_isotail != NULL) {
@@ -923,21 +960,29 @@ static int ep_unlink (ohci_t * ohci, ed_t * ed)
        ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
 
        switch (ed->type) {
-       case CTRL: 
+       case PIPE_CONTROL:
                if (ed->ed_prev == NULL) {
+                       if (!ed->hwNextED) {
+                               ohci->hc_control &= ~OHCI_CTRL_CLE;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                       }
                        writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead);
                } else {
                        ed->ed_prev->hwNextED = ed->hwNextED;
                }
-               if(ohci->ed_controltail == ed) {
+               if (ohci->ed_controltail == ed) {
                        ohci->ed_controltail = ed->ed_prev;
                } else {
                        ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
                }
                break;
       
-       case BULK: 
+       case PIPE_BULK:
                if (ed->ed_prev == NULL) {
+                       if (!ed->hwNextED) {
+                               ohci->hc_control &= ~OHCI_CTRL_BLE;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                       }
                        writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead);
                } else {
                        ed->ed_prev->hwNextED = ed->hwNextED;
@@ -949,7 +994,7 @@ static int ep_unlink (ohci_t * ohci, ed_t * ed)
                }
                break;
       
-       case INT: 
+       case PIPE_INTERRUPT:
                int_branch = ed->int_branch;
                interval = ed->int_interval;
 
@@ -971,7 +1016,7 @@ static int ep_unlink (ohci_t * ohci, ed_t * ed)
 #endif
                break;
                
-       case ISO:
+       case PIPE_ISOCHRONOUS:
                if (ohci->ed_isotail == ed)
                        ohci->ed_isotail = ed->ed_prev;
                if (ed->hwNextED != 0) 
@@ -1054,7 +1099,7 @@ static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int int
                        | usb_pipeslow (pipe) << 13
                        | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16);
   
-       if (ed->type == INT && ed->state == ED_UNLINK) {
+       if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
                ed->int_period = interval;
                ed->int_load = load;
        }
@@ -1081,13 +1126,13 @@ static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
 
        if (!ohci->disabled) {
                switch (ed->type) {
-                       case CTRL: /* stop CTRL list */
-                               writel (ohci->hc_control &= ~OHCI_CTRL_CLE,
-                                        &ohci->regs->control); 
+                       case PIPE_CONTROL: /* stop control list */
+                               ohci->hc_control &= ~OHCI_CTRL_CLE;
+                               writel (ohci->hc_control, &ohci->regs->control); 
                                break;
-                       case BULK: /* stop BULK list */
-                               writel (ohci->hc_control &= ~OHCI_CTRL_BLE,
-                                        &ohci->regs->control); 
+                       case PIPE_BULK: /* stop bulk list */
+                               ohci->hc_control &= ~OHCI_CTRL_BLE;
+                               writel (ohci->hc_control, &ohci->regs->control); 
                                break;
                }
        }
@@ -1128,7 +1173,7 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int i
        td->index = index;
        td->urb = urb; 
        td->hwINFO = cpu_to_le32 (info);
-       if ((td->ed->type & 3) == PIPE_ISOCHRONOUS) {
+       if ((td->ed->type) == PIPE_ISOCHRONOUS) {
                td->hwCBP = cpu_to_le32 (((!data || !len)
                        ? 0
                        : virt_to_bus (data)) & 0xFFFFF000);
@@ -1269,6 +1314,27 @@ static void dl_transfer_length(td_t * td)
        }
 }
 
+/* handle an urb that is being unlinked */
+
+static void dl_del_urb (urb_t * urb)
+{
+       wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait;
+
+       urb_rm_priv_locked (urb);
+
+       if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+               urb->status = -ECONNRESET;
+               if (urb->complete)
+                       urb->complete (urb);
+       } else {
+               urb->status = -ENOENT;
+
+               /* unblock sohci_unlink_urb */
+               if (wait_head)
+                       wake_up (wait_head);
+       }
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* replies to the request have to be on a FIFO basis so
@@ -1330,6 +1396,7 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
        int ctrl = 0, bulk = 0;
 
        spin_lock_irqsave (&usb_ed_lock, flags);
+
        for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) {
 
                tdTailP = bus_to_virt (le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
@@ -1344,22 +1411,13 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
                        td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
                        if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) {
                                tdINFO = le32_to_cpup (&td->hwINFO);
-                               if (TD_CC_GET (tdINFO) < 0xE) dl_transfer_length (td);
+                               if (TD_CC_GET (tdINFO) < 0xE)
+                                       dl_transfer_length (td);
                                *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3));
+
                                /* URB is done; clean up */
-                               if (++(urb_priv->td_cnt) == urb_priv->length) {
-                                       void    *condition = urb_priv->wait; 
-
-                                       urb_rm_priv (urb);
-                                       if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-                                               usb_dec_dev_use (urb->dev);
-                                               urb->status = -ECONNRESET;
-                                               urb->complete (urb); 
-                                       } else if (condition) { 
-                                               /* unblock sohci_unlink_urb */
-                                               wake_up (condition);
-                                       }
-                               }
+                               if (++(urb_priv->td_cnt) == urb_priv->length)
+                                       dl_del_urb (urb);
                        } else {
                                td_p = &td->hwNextTD;
                        }
@@ -1371,31 +1429,54 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
                        ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); 
                        ed->state = ED_NEW; 
                        /* if all eds are removed wake up sohci_free_dev */
-                       if (!--dev->ed_cnt && dev->wait)
-                               wake_up (dev->wait);
-               }
-               else {
+                       if (!--dev->ed_cnt) {
+                               wait_queue_head_t *wait_head = dev->wait;
+
+                               dev->wait = 0;
+                               if (wait_head)
+                                       wake_up (wait_head);
+                       }
+               } else {
                        ed->state &= ~ED_URB_DEL;
-                       ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
+                       tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
+
+                       if (tdHeadP == tdTailP) {
+                               if (ed->state == ED_OPER)
+                                       ep_unlink(ohci, ed);
+                               OHCI_FREE (tdTailP);
+                               ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
+                               ed->state = ED_NEW;
+                               --(usb_to_ohci (ohci->dev[edINFO & 0x7F]))->ed_cnt;
+                       } else
+                               ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
                }
-               
-               if ((ed->type & 3) == CTRL) ctrl |= 1;
-               if ((ed->type & 3) == BULK) bulk |= 1;  
+
+               switch (ed->type) {
+                       case PIPE_CONTROL:
+                               ctrl = 1;
+                               break;
+                       case PIPE_BULK:
+                               bulk = 1;
+                               break;
+               }
        }
        
-       /* maybe reenable CTRL and BULK lists */ 
+       /* maybe reenable control and bulk lists */ 
        if (!ohci->disabled) {
-               if (ctrl)       /* reset CTRL list */
+               if (ctrl)       /* reset control list */
                        writel (0, &ohci->regs->ed_controlcurrent);
-               if (bulk)       /* reset BULK list */
+               if (bulk)       /* reset bulk list */
                        writel (0, &ohci->regs->ed_bulkcurrent);
                if (!ohci->ed_rm_list[!frame]) {
-                       ohci->hc_control |= OHCI_CTRL_CLE | OHCI_CTRL_BLE;
+                       if (ohci->ed_controltail)
+                               ohci->hc_control |= OHCI_CTRL_CLE;
+                       if (ohci->ed_bulktail)
+                               ohci->hc_control |= OHCI_CTRL_BLE;
                        writel (ohci->hc_control, &ohci->regs->control);   
                }
        }
-       ohci->ed_rm_list[frame] = NULL;
 
+       ohci->ed_rm_list[frame] = NULL;
        spin_unlock_irqrestore (&usb_ed_lock, flags);
 }
 
@@ -1439,14 +1520,15 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
                        cc = TD_CC_NOERROR;
 
                if (++(urb_priv->td_cnt) == urb_priv->length) {
-                       if (urb_priv->state != URB_DEL
-                                       && !(ed->state & ED_DEL)
-                                       && ed->state != ED_NEW) { 
+                       if ((ed->state & (ED_OPER | ED_UNLINK))
+                                       && (urb_priv->state != URB_DEL)) {
                                urb->status = cc_to_error[cc];
                                sohci_return_urb (urb);
                        } else {
-                               urb_rm_priv (urb);
-                       }
+                               spin_lock_irqsave (&usb_ed_lock, flags);
+                               dl_del_urb (urb);
+                               spin_unlock_irqrestore (&usb_ed_lock, flags);
+                       }
                }
                
                spin_lock_irqsave (&usb_ed_lock, flags);
@@ -1600,7 +1682,8 @@ static void rh_int_timer_do (unsigned long ptr)
 #ifdef DEBUG
                        urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));
 #endif
-                       if (urb->complete) urb->complete (urb);
+                       if (urb->complete)
+                               urb->complete (urb);
                }
        }
  out:
@@ -1656,7 +1739,6 @@ static int rh_submit_urb (urb_t * urb)
        __u16 wLength;
 
        if (usb_pipeint(pipe)) {
-       
                ohci->rh.urb =  urb;
                ohci->rh.send = 1;
                ohci->rh.interval = urb->interval;
@@ -1827,9 +1909,11 @@ static int rh_submit_urb (urb_t * urb)
        urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe));
 #endif
 
+       urb->hcpriv = NULL;
+       usb_dec_dev_use (usb_dev);
+       urb->dev = NULL;
        if (urb->complete)
                urb->complete (urb);
-       usb_dec_dev_use (urb->dev);
        return 0;
 }
 
@@ -1842,6 +1926,17 @@ static int rh_unlink_urb (urb_t * urb)
        if (ohci->rh.urb == urb) {
                ohci->rh.send = 0;
                del_timer (&ohci->rh.rh_int_timer);
+               ohci->rh.urb = NULL;
+
+               urb->hcpriv = NULL;
+               usb_dec_dev_use(urb->dev);
+               urb->dev = NULL;
+               if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+                       urb->status = -ECONNRESET;
+                       if (urb->complete)
+                               urb->complete (urb);
+               } else
+                       urb->status = -ENOENT;
        }
        return 0;
 }
@@ -2352,6 +2447,12 @@ ohci_pci_resume (struct pci_dev *dev)
 
                ohci->disabled = 0;
                ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+               if (!ohci->ed_rm_list[0] & !ohci->ed_rm_list[1]) {
+                       if (ohci->ed_controltail)
+                               ohci->hc_control |= OHCI_CTRL_CLE;
+                       if (ohci->ed_bulktail)
+                               ohci->hc_control |= OHCI_CTRL_BLE;
+               }
                writel (ohci->hc_control, &ohci->regs->control);
 #ifdef CONFIG_PMAC_PBOOK
                enable_irq (ohci->irq);
@@ -2448,7 +2549,6 @@ static int __init ohci_hcd_init (void)
        return ret;
 }
 
-
 /*-------------------------------------------------------------------------*/
 
 static void __exit ohci_hcd_cleanup (void) 
@@ -2463,6 +2563,5 @@ module_init (ohci_hcd_init);
 module_exit (ohci_hcd_cleanup);
 
 
-
 MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>, David Brownell");
 MODULE_DESCRIPTION ("USB OHCI Host Controller Driver");
index c49f9e91c8462f522d132128c7c885bc094a0246..086db1a12f19cc4414d39001e21571b5c84a5ae7 100644 (file)
@@ -107,7 +107,7 @@ typedef struct td {
        __u32 hwBE;             /* Memory Buffer End Pointer */
        __u16 hwPSW[MAXPSW];
 
-       __u8 type;
+       __u8 unused;
        __u8 index;
        struct ed * ed;
        struct td * next_dl_td;
@@ -115,18 +115,6 @@ typedef struct td {
 } td_t;
 
 
-/* TD types */
-#define BULK           0x03
-#define INT                    0x01
-#define CTRL           0x02
-#define ISO                    0x00
-#define SEND            0x01
-#define ST_ADDR         0x02
-#define ADD_LEN         0x04
-#define DEL             0x08
-
-
 #define OHCI_ED_SKIP   (1 << 14)
 
 /*
@@ -347,7 +335,7 @@ typedef struct
        __u16 length;   // number of tds associated with this request
        __u16 td_cnt;   // number of tds already serviced
        int   state;
-       void * wait;
+       wait_queue_head_t * wait;
        td_t * td[0];   // list pointer to all corresponding TDs associated with this request
 
 } urb_priv_t;
@@ -398,7 +386,7 @@ typedef struct ohci {
 struct ohci_device {
        ed_t    ed[NUM_EDS];
        int ed_cnt;
-       void  * wait;
+       wait_queue_head_t * wait;
 };
 
 // #define ohci_to_usb(ohci)   ((ohci)->usb)
index 881342af6201981bbca94fa6c2efa1d3a6be5d3e..fbed8c1584d3b8b448424cd7e184b7f0872355c2 100644 (file)
@@ -1057,6 +1057,7 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
        uhci_desc_t *qh;
        urb_priv_t *urb_priv;
        unsigned long flags=0;
+       struct usb_device *usb_dev;
 
        spin_lock_irqsave (&s->urb_list_lock, flags);
 
@@ -1103,11 +1104,13 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
 #else
                kfree (urb->hcpriv);
 #endif
+               usb_dev = urb->dev;
                if (urb->complete) {
                        dbg("unlink_urb: calling completion");
+                       urb->dev = NULL;
                        urb->complete ((struct urb *) urb);
                }
-               usb_dec_dev_use (urb->dev);
+               usb_dec_dev_use (usb_dev);
        }
        else {
                if (!in_interrupt())    
@@ -1171,6 +1174,7 @@ _static void uhci_cleanup_unlink(uhci_t *s, int force)
 
                        if (urb->complete) {
                                spin_unlock(&s->urb_list_lock);
+                               urb->dev = NULL;
                                urb->complete ((struct urb *) urb);
                                spin_lock(&s->urb_list_lock);
                        }
@@ -2082,6 +2086,7 @@ _static int rh_submit_urb (urb_t *urb)
 
        urb->actual_length = len;
        urb->status = stat;
+       urb->dev=NULL;
        if (urb->complete)
                urb->complete (urb);
        return 0;
@@ -2484,7 +2489,6 @@ _static int process_urb (uhci_t *s, struct list_head *p)
        int ret = 0;
        urb_t *urb;
 
-
        urb=list_entry (p, urb_t, urb_list);
        //dbg("process_urb: found queued urb: %p", urb);
 
@@ -2508,6 +2512,9 @@ _static int process_urb (uhci_t *s, struct list_head *p)
 
        if (urb->status != -EINPROGRESS) {
                int proceed = 0;
+               struct usb_device *usb_dev;
+               
+               usb_dev=urb->dev;
 
                /* Release bandwidth for Interrupt or Iso transfers */
                if (urb->bandwidth) {
@@ -2549,9 +2556,12 @@ _static int process_urb (uhci_t *s, struct list_head *p)
                        // In case you need the current URB status for your completion handler (before resubmit)
                        if (urb->complete && (!proceed )) {
                                dbg("process_transfer: calling early completion");
+                               urb->dev = NULL;
                                urb->complete ((struct urb *) urb);
-                               if (!proceed && is_ring && (urb->status != -ENOENT))
+                               if (!proceed && is_ring && (urb->status != -ENOENT)) {
+                                       urb->dev=usb_dev;
                                        uhci_submit_urb (urb);
+                               }
                        }
 
                        if (proceed && urb->next) {
@@ -2567,11 +2577,13 @@ _static int process_urb (uhci_t *s, struct list_head *p)
 
                                if (urb->complete) {
                                        dbg("process_transfer: calling completion");
+                                       urb->dev=NULL;
                                        urb->complete ((struct urb *) urb);
                                }
                        }
-
-                       usb_dec_dev_use (urb->dev);
+                       
+                       urb->dev=NULL; // Just in case no completion was called
+                       usb_dec_dev_use (usb_dev);
                        spin_unlock(&urb->lock);                
                        spin_lock(&s->urb_list_lock);
                }
index ececaa03b1f4fdddf91655f886d9b227816a9ba6..df469e7d81ff2fc911d0b856533dbc739152f4ab 100644 (file)
 #endif
 #include <linux/usb.h>
 
+#define DEVNUM_ROUND_ROBIN     /***** OPTION *****/
+#ifdef DEVNUM_ROUND_ROBIN
+static int devnum_next = 1;
+#endif
+
 static const int usb_bandwidth_option =
 #ifdef CONFIG_USB_BANDWIDTH
                                1;
@@ -1470,7 +1475,19 @@ void usb_connect(struct usb_device *dev)
         * which hopefully doesn't run on multiple CPU's simultaneously 8-)
         */
        dev->descriptor.bMaxPacketSize0 = 8;  /* Start off at 8 bytes  */
+#ifndef DEVNUM_ROUND_ROBIN
        devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
+#else  /* round_robin alloc of devnums */
+       /* Try to allocate the next devnum beginning at devnum_next. */
+       devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, devnum_next);
+       if (devnum >= 128)
+               devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
+
+       devnum_next = devnum + 1;
+       if (devnum_next >= 128)
+               devnum_next = 1;
+#endif /* round_robin alloc of devnums */
+
        if (devnum < 128) {
                set_bit(devnum, dev->bus->devmap.devicemap);
                dev->devnum = devnum;
index 89a566312a7347c6641960ed01b889b915638062..649abd02d3519f36cae41713df9205986f9f6751 100644 (file)
@@ -2,6 +2,7 @@
 #define _ALPHA_BITOPS_H
 
 #include <linux/config.h>
+#include <linux/kernel.h>
 
 /*
  * Copyright 1994, Linus Torvalds.
index f9aa875aea98842f6b16042cb5455d3f964bd5a2..6fe7d5194eb3e492295c7c707fb9f923ff96bcd9 100644 (file)
@@ -7,8 +7,6 @@
  *
  */
 
-#include <linux/config.h>
-
 typedef struct { volatile int counter; } atomic_t;
 
 #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
index 9e7f4a5b05a8a82ec03419d4cacf808642433ede..4a55a8929a682b5490ba8f95d956159b52a2ace6 100644 (file)
@@ -8,19 +8,12 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_SMP
-/* This is a temporary measure. -DaveM */
 typedef struct { volatile int counter; } atomic_t;
-#define ATOMIC_INIT(i) { (i << 8) }
-#else
-typedef struct { int counter; } atomic_t;
-#define ATOMIC_INIT(i)  { (i) }
-#endif
 
 #ifdef __KERNEL__
-
 #ifndef CONFIG_SMP
 
+#define ATOMIC_INIT(i)  { (i) }
 #define atomic_read(v)          ((v)->counter)
 #define atomic_set(v, i)        (((v)->counter) = i)
 
@@ -39,6 +32,8 @@ typedef struct { int counter; } atomic_t;
  *      31                          8 7      0
  */
 
+#define ATOMIC_INIT(i) { (i << 8) }
+
 static __inline__ int atomic_read(atomic_t *v)
 {
        int ret = v->counter;
index 8ab8bdaf024c4101fac35f6199bba4aac7541a55..b1085349015af775f4f366303bf466316090559d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.60 2000/08/10 23:49:16 davem Exp $
+/* $Id: bitops.h,v 1.61 2000/09/23 02:11:22 davem Exp $
  * bitops.h: Bit string operations on the Sparc.
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -156,6 +156,9 @@ extern __inline__ void change_bit(unsigned long nr, volatile void *addr)
 
 #endif /* __KERNEL__ */
 
+#define smp_mb__before_clear_bit()     do { } while(0)
+#define smp_mb__after_clear_bit()      do { } while(0)
+
 /* The following routine need not be atomic. */
 extern __inline__ int test_bit(int nr, __const__ void *addr)
 {
index 0a101cacd790c177954e2f51315d13ebbf9f5094..28b07675fa8cf9b7fc2be8a72bcf96675c8611a6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.83 2000/08/04 05:35:55 davem Exp $ */
+/* $Id: system.h,v 1.84 2000/09/23 02:11:22 davem Exp $ */
 #include <linux/config.h>
 
 #ifndef __SPARC_SYSTEM_H
@@ -280,6 +280,9 @@ extern void __global_restore_flags(unsigned long flags);
 #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 nop() __asm__ __volatile__ ("nop");
 
index db3cd58319d95cf569e1b2cc39ad49d15540c74f..2461ec29d435c6144f3cf34ddb36265f62a65adc 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef __ARCH_SPARC64_ATOMIC__
 #define __ARCH_SPARC64_ATOMIC__
 
-typedef struct { int counter; } atomic_t;
+typedef struct { volatile int counter; } atomic_t;
 #define ATOMIC_INIT(i) { (i) }
 
 #define atomic_read(v)         ((v)->counter)
index e297d6f96e88f9414562aee4789ea3b4aef4c1cd..26e3716ccea342adceb45aca916e60d3d6836360 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.30 2000/08/10 23:49:16 davem Exp $
+/* $Id: bitops.h,v 1.31 2000/09/23 02:09:21 davem Exp $
  * bitops.h: Bit string operations on the V9.
  *
  * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -20,6 +20,9 @@ extern long __test_and_change_bit(unsigned long nr, volatile void *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))
 
+#define smp_mb__before_clear_bit()     do { } while(0)
+#define smp_mb__after_clear_bit()      do { } while(0)
+
 extern __inline__ int test_bit(int nr, __const__ void *addr)
 {
        return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63))) != 0UL;
index 0927fe5cc432682b9f3337cc51a4608806edc971..3898efdd2e9fe03e38a26bde6033fea42cecdc6e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/config.h>
 #include <linux/threads.h>
 #include <asm/asi.h>
+#include <asm/starfire.h>
 
 #ifndef __ASSEMBLY__
 /* PROM provided per-processor information we need
@@ -82,11 +83,7 @@ extern __inline__ int cpu_number_map(int cpu)
 
 extern __inline__ int hard_smp_processor_id(void)
 {
-       extern int this_is_starfire;
-
        if(this_is_starfire != 0) {
-               extern int starfire_hard_smp_processor_id(void);
-
                return starfire_hard_smp_processor_id();
        } else {
                unsigned long upaconfig;
diff --git a/include/asm-sparc64/starfire.h b/include/asm-sparc64/starfire.h
new file mode 100644 (file)
index 0000000..d59bda0
--- /dev/null
@@ -0,0 +1,21 @@
+/* $Id: starfire.h,v 1.1 2000/09/21 06:18:53 anton Exp $
+ * starfire.h: Group all starfire specific code together.
+ *
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
+ */
+
+#ifndef _SPARC64_STARFIRE_H
+#define _SPARC64_STARFIRE_H
+
+#ifndef __ASSEMBLY__
+
+extern int this_is_starfire;
+
+extern void check_if_starfire(void);
+extern void starfire_cpu_setup(void);
+extern int starfire_hard_smp_processor_id(void);
+extern void *starfire_hookup(int);
+extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
+
+#endif
+#endif
index 6235edd7c743e4deaeb22c1407603f6f30d8bb3b..3c396eb0073f15e904cd1ebefd5ba5bc6e0f018f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.61 2000/08/04 05:35:55 davem Exp $ */
+/* $Id: system.h,v 1.62 2000/09/23 02:09:21 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
@@ -95,11 +95,11 @@ extern void __global_restore_flags(unsigned long flags);
 
 #endif
 
-#define mb()           __asm__ __volatile__ ("stbar" : : : "memory")
-
 #define nop()          __asm__ __volatile__ ("nop")
 
 #define membar(type)   __asm__ __volatile__ ("membar " type : : : "memory");
+#define mb()           \
+       membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad");
 #define rmb()          membar("#LoadLoad")
 #define wmb()          membar("#StoreStore")
 #define set_mb(__var, __value) \
@@ -107,6 +107,16 @@ extern void __global_restore_flags(unsigned long flags);
 #define set_wmb(__var, __value) \
        do { __var = __value; membar("#StoreStore"); } while(0)
 
+#ifdef CONFIG_SMP
+#define smp_mb()       mb()
+#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");
+#endif
+
 #define flushi(addr)   __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
 
 #define flushw_all()   __asm__ __volatile__("flushw")
index 1a3f0ddb5d52c8143600aab219fe536360351e1f..372e1841a3ac45e61cc419b4dabf55748ca0ef0f 100644 (file)
 #define UNIX98_PTY_MAJOR_COUNT 8
 #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
 
+#define VXVM_MAJOR             199     /* VERITAS volume i/o driver    */
+#define VXSPEC_MAJOR           200     /* VERITAS volume config driver */
+#define VXDMP_MAJOR            201     /* VERITAS volume multipath driver */
+
 #define MSR_MAJOR              202
 #define CPUID_MAJOR            203
 
index bbbefdbf45ba04d2ad841da4fb7e1170abb76150..c173b9eb30f5cfdb455dd51a2857d68ec1a3220d 100644 (file)
@@ -1066,16 +1066,13 @@ static int arp_get_info(char *buffer, char **start, off_t offset, int length)
                        {
                                char tbuf[16];
                                sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->primary_key));
-
-                               size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s",
+                               size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"
+                                                       "     *        %s\n",
                                        tbuf,
                                        hatype,
                                        arp_state_to_flags(n), 
-                                       hbuffer);
-
-                               size += sprintf(buffer+len+size,
-                                        "     %-8s %s\n",
-                                        "*", dev->name);
+                                       hbuffer,
+                                       dev->name);
                        }
 
                        read_unlock(&n->lock);
@@ -1102,15 +1099,14 @@ static int arp_get_info(char *buffer, char **start, off_t offset, int length)
                        {
                                char tbuf[16];
                                sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->key));
-                               size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s",
+                               size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"
+                                                       "     *        %s\n",
                                        tbuf,
                                        hatype,
                                        ATF_PUBL|ATF_PERM,
-                                       "00:00:00:00:00:00");
+                                       "00:00:00:00:00:00",
+                                       dev ? dev->name : "*");
                        }
-                       size += sprintf(buffer+len+size,
-                                "     *        %-16s\n",
-                                dev ? dev->name : "*");
 
                        len += size;
                        pos += size;
index c463b4c7182ea7ee9454b707d7b8cc5e51d8091f..f6cb06e3f30e96e79dfb1dec5e2eb33810a648f8 100644 (file)
@@ -1,7 +1,8 @@
 ksymoops has been removed from the kernel.  It was always meant to be a
 free standing utility, not linked to any particular kernel version.
-The latest version can be found in ftp://ftp.ocs.com.au/pub/ksymoops,
-together with patches to other utilities in order to give more accurate
-Oops debugging.
+The latest version can be found in
+ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together
+with patches to other utilities in order to give more accurate Oops
+debugging.
 
 Keith Owens <kaos@ocs.com.au> Sat Jun 19 10:30:34 EST 1999