]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.44pre2 2.1.44pre2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:24 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:24 +0000 (15:13 -0500)
16 files changed:
Documentation/Configure.help
Makefile
drivers/block/ide.c
drivers/block/ide.h
drivers/block/triton.c
drivers/char/rtc.c
drivers/net/Config.in
drivers/pci/pci.c
fs/dcache.c
fs/namei.c
fs/readdir.c
fs/super.c
include/linux/dalloc.h
include/linux/fs.h
include/linux/pci.h
scripts/ksymoops.cc

index 863c1d3acb2c330e1201cec92f8d46d2775416be..b7d55dd37191d36228689cba7bc7caa497cd628e 100644 (file)
@@ -287,17 +287,19 @@ CONFIG_BLK_DEV_RZ1000
   Linux.  This may slow disk throughput by a few percent, but at least
   things will operate 100% reliably. If unsure, say Y.
 
-Intel 82371 PIIX (Triton I/II) DMA support
+Intel 82371 PIIX (Triton I/II), VIA VP-1 DMA support
 CONFIG_BLK_DEV_TRITON
   If your PCI system uses an IDE harddrive (as opposed to SCSI, say)
   and includes the Intel Triton I/II IDE interface chipset (i82371FB,
-  i82371SB or i82371AB), you will want to enable this option to allow
-  use of bus-mastering DMA data transfers. Read the comments at the
+  i82371SB or i82371AB), or the VIA VP-1 IDE interface chipset 
+  (VT82C586), you will want to enable this option to allow use of 
+  bus-mastering DMA data transfers. Read the comments at the
   beginning of drivers/block/triton.c and Documentation/ide.txt.
   You can get the latest version of the hdparm utility via 
   ftp (user: anonymous) from
   sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/; it is
-  used to tune your harddisk. It is safe to say Y to this question.
+  used to tune your harddisk. 
+  It is safe to say Y to this question.
 
 Other IDE chipset support
 CONFIG_IDE_CHIPSETS
index 82175e671004ed3c982dafeaf36b923589fcf70f..fee9b84877917b0b80442a4a853a6cd933861a89 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 43
+SUBLEVEL = 44
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
index 1b293c5391faf84b8d08e0e6a459d403f26a6f58..b0f3e03da74b404fec069192c99244d24b32a7f5 100644 (file)
@@ -2603,6 +2603,7 @@ __initfunc(static void probe_for_hwifs (void))
                ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
                ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
 #endif /* CONFIG_BLK_DEV_TRITON */
+       ide_probe_pci (PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, &ide_init_triton, 0);
 #ifdef CONFIG_BLK_DEV_OPTI621
                ide_probe_pci (PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, &ide_init_opti621, 0);
 #endif /* CONFIG_BLK_DEV_OPTI621 */
index fddbc455236c6a426a532755bc049eac20d75d60..2f60115a33bf1df1b5edfaa3b2037eb6609c65cd 100644 (file)
@@ -298,7 +298,7 @@ typedef void (ide_selectproc_t) (ide_drive_t *);
 typedef enum { ide_unknown,    ide_generic,    ide_triton,
                ide_cmd640,     ide_dtc2278,    ide_ali14xx,
                ide_qd6580,     ide_umc8672,    ide_ht6560b,
-               ide_promise }
+               ide_promise,    ide_via }
        hwif_chipset_t;
 
 typedef struct hwif_s {
index 7956307c86d07ff335119ac2bc366c4b728b69af..006051af656b251a7ae405cbe6de42b1a4cd8ae5 100644 (file)
@@ -122,15 +122,25 @@ static unsigned int piix_key;
 #define PIIX_FLAGS_PREFETCH    4
 #define PIIX_FLAGS_FAST_DMA    8
 
-typedef struct {
-       unsigned d0_flags       :4;
-       unsigned d1_flags       :4;
-       unsigned recovery       :2;
-       unsigned reserved       :2;
-       unsigned sample         :2;
-       unsigned sidetim_enabled:1;
-       unsigned ports_enabled  :1;
-} piix_timing_t;
+
+union chip_en_reg_u {
+       struct {
+               unsigned d0_flags       :4;
+               unsigned d1_flags       :4;
+               unsigned recovery       :2;
+               unsigned reserved       :2;
+               unsigned sample         :2;
+               unsigned sidetim_enabled:1;
+               unsigned ports_enabled  :1;
+       } piix_s;
+       struct {
+               unsigned sec_en         :1;
+               unsigned pri_en         :1;
+               unsigned reserved       :14;
+       } via_s;
+};
+
+typedef union chip_en_reg_u piix_timing_t;
 
 typedef struct {
        unsigned pri_recovery   :2;
@@ -269,16 +279,16 @@ static int piix_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
                                printk("%s: pcibios read failed\n", HWIF(drive)->name);
                                return 1;
                        }
-                       dflags = drive->select.b.unit ? timing.d1_flags : timing.d0_flags;
+                       dflags = drive->select.b.unit ? timing.piix_s.d1_flags : timing.piix_s.d0_flags;
                        if (dflags & PIIX_FLAGS_FAST_PIO) {
                                if (func == ide_dma_on && drive->media == ide_disk)
                                        dflags |= PIIX_FLAGS_FAST_DMA;
                                else
                                        dflags &= ~PIIX_FLAGS_FAST_DMA;
                                if (drive->select.b.unit == 0)
-                                       timing.d0_flags = dflags;
+                                       timing.piix_s.d0_flags = dflags;
                                else
-                                       timing.d1_flags = dflags;
+                                       timing.piix_s.d1_flags = dflags;
                                if (pcibios_write_config_word(piix_pci_bus, piix_pci_fn, reg, *(short *)&timing)) {
                                        printk("%s: pcibios write failed\n", HWIF(drive)->name);
                                        return 1;
@@ -456,8 +466,14 @@ void ide_init_triton (byte bus, byte fn)
                chipset = "PIIX4";
        else if (devid == PCI_DEVICE_ID_INTEL_82371SB_1)
                chipset = "PIIX3";
-       else
+       else if (devid == PCI_DEVICE_ID_INTEL_82371_1)
                chipset = "PIIX";
+       else if (devid == PCI_DEVICE_ID_VIA_82C586_1)
+               chipset = "VP1";
+       else {
+               printk("Unknown PCI IDE interface 0x%x\n", devid);
+               goto quit;
+       }
 
        printk("%s: bus-master IDE device on PCI bus %d function %d\n", chipset, bus, fn);
 
@@ -470,13 +486,24 @@ void ide_init_triton (byte bus, byte fn)
                printk("%s: IDE ports are not enabled (BIOS)\n", chipset);
                goto quit;
        }
-       if ((rc = pcibios_read_config_word(bus, fn, 0x40, (short *)&timings[0])))
-               goto quit;
-       if ((rc = pcibios_read_config_word(bus, fn, 0x42, (short *)&timings[1])))
-               goto quit;
-       if ((!timings[0].ports_enabled) && (!timings[1].ports_enabled)) {
-               printk("%s: neither IDE port is enabled\n", chipset);
-               goto quit;
+       if (devid == PCI_DEVICE_ID_VIA_82C586_1) {
+               /* pri and sec channel enables are in port 0x40 */
+               if ((rc = pcibios_read_config_word(bus, fn, 0x40, (short *)&timings[0])))
+                       goto quit;
+               if ((!timings[0].via_s.pri_en && (!timings[0].via_s.sec_en))) {
+                       printk("%s: neither IDE port is enabled\n", chipset);
+                       goto quit;
+               }
+       }
+       else {          /* INTEL piix */
+               if ((rc = pcibios_read_config_word(bus, fn, 0x40, (short *)&timings[0])))
+                       goto quit;
+               if ((rc = pcibios_read_config_word(bus, fn, 0x42, (short *)&timings[1])))
+                       goto quit;
+               if ((!timings[0].piix_s.ports_enabled) && (!timings[1].piix_s.ports_enabled)) {
+                       printk("%s: neither IDE port is enabled\n", chipset);
+                       goto quit;
+               }
        }
 
        /*
@@ -526,10 +553,30 @@ void ide_init_triton (byte bus, byte fn)
                        case 0x170:     pri_sec = 1; break;
                        default:        continue;
                }
+
+               if (devid == PCI_DEVICE_ID_VIA_82C586_1) {
+                       timing = timings[0];
+                       switch (h) {
+                               case 0:
+                                       if (!timing.piix_s.ports_enabled) {
+                       printk("port 0 DMA not enabled\n");
+                                               continue;
+                                       }
+                               case 1:
+                                       if (!timing.piix_s.sidetim_enabled) {
+                       printk("port 1 DMA not enabled\n");
+                                               continue;
+                                       }
+                       }
+                       hwif->chipset = ide_via;
+               }
+               else {          /* PIIX */
+
                timing = timings[pri_sec];
-               if (!timing.ports_enabled)      /* interface disabled? */
+               if (!timing.piix_s.ports_enabled)       /* interface disabled? */
                        continue;
                hwif->chipset = ide_triton;
+               }
                if (dma_enabled)
                        init_piix_dma(hwif, bmiba + (pri_sec ? 8 : 0));
 #ifdef DISPLAY_PIIX_TIMINGS
@@ -539,17 +586,32 @@ void ide_init_triton (byte bus, byte fn)
                {
                        const char *slave;
                        piix_sidetim_t sidetim;
-                       byte sample   = 5 - timing.sample;
-                       byte recovery = 4 - timing.recovery;
+                       byte sample   = 5 - timing.piix_s.sample;
+                       byte recovery = 4 - timing.piix_s.recovery;
+                       unsigned int drvtim;
+
+                       if (devid == PCI_DEVICE_ID_VIA_82C586_1) {
+                               pcibios_read_config_dword(bus, fn, 0x48, &drvtim);
+                               if (pri_sec == 0) { 
+                                       printk("    %s master: active_pulse_CLKs=%d, recovery_CLKs=%d\n", hwif->name, 1+(drvtim>>28), 1+((drvtim & 0x0f000000)>>24));
+                                       printk("    %s slave: active_pulse_CLKs=%d, recovery_CLKs=%d\n", hwif->name, 1+((drvtim & 0xf00000)>>20), 1+((drvtim & 0x0f0000)>>16));
+                                       continue;
+                               } else {
+                                       printk("    %s master: active_pulse_CLKs=%d, recovery_CLKs=%d\n", hwif->name, 1+((drvtim & 0xf000)>>12), 1+((drvtim & 0x0f00)>>8));
+                                       printk("    %s slave: active_pulse_CLKs=%d, recovery_CLKs=%d\n", hwif->name, 1+((drvtim & 0xf0)>>4), 1+(drvtim & 0x0f));
+                                       continue;
+                               }
+                       }
+       
                        if ((devid == PCI_DEVICE_ID_INTEL_82371SB_1
                             || devid == PCI_DEVICE_ID_INTEL_82371AB)
-                        && timing.sidetim_enabled
+                        && timing.piix_s.sidetim_enabled
                         && !pcibios_read_config_byte(bus, fn, 0x44, (byte *) &sidetim))
                                slave = "";             /* PIIX3 and later */
                        else
                                slave = "/slave";       /* PIIX, or PIIX3 in compatibility mode */
                        printk("    %s master%s: sample_CLKs=%d, recovery_CLKs=%d\n", hwif->name, slave, sample, recovery);
-                       print_piix_drive_flags ("master:", timing.d0_flags);
+                       print_piix_drive_flags ("master:", timing.piix_s.d0_flags);
                        if (!*slave) {
                                if (pri_sec == 0) {
                                        sample   = 5 - sidetim.pri_sample;
@@ -560,7 +622,7 @@ void ide_init_triton (byte bus, byte fn)
                                }
                                printk("         slave : sample_CLKs=%d, recovery_CLKs=%d\n", sample, recovery);
                        }
-                       print_piix_drive_flags ("slave :", timing.d1_flags);
+                       print_piix_drive_flags ("slave :", timing.piix_s.d1_flags);
                }
 #endif /* DISPLAY_PIIX_TIMINGS */
        }
index a8614999d3a875aa28d3cda21f78b522ae5badae..a4fb2cb175f22323f35000caec24e66367d3e8e2 100644 (file)
@@ -180,7 +180,7 @@ static long rtc_read(struct inode *inode, struct file *file, char *buf,
                data = rtc_irq_data;
                rtc_irq_data = 0;
                restore_flags(flags);
-               retval = put_user(data, (unsigned long *)buf)) ?: sizeof(unsigned long);
+               retval = put_user(data, (unsigned long *)buf) ?: sizeof(unsigned long);
        }
 
        current->state = TASK_RUNNING;
index 289bd534a65a022877cff510635d0cb1a0e7779f..a699a4be26a0efe5762c66b94066e04e187905d4 100644 (file)
@@ -143,12 +143,8 @@ if [ "$CONFIG_NET_RADIO" != "n" ]; then
       bool 'Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
       bool 'Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
       bool 'Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
-      if [ -f drivers/net/soundmodem/sm_afsk2666.c ]; then
-        bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
-      fi
-      if [ -f drivers/net/soundmodem/sm_psk4800.c ]; then
-        bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
-      fi
+      #bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
+      #bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
     fi
   fi
   tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
index 7118164b680277325158dad3e85a7b6b7f05d9ed..16dcfafa0943d3abc71bc6bfb5471375b8df40f4 100644 (file)
@@ -204,7 +204,7 @@ struct pci_dev_info dev_info[] = {
        DEVICE( VIA,            VIA_82C586_1,   "VT 82C586 Apollo VP-1"),
        DEVICE( VIA,            VIA_82C576,     "VT 82C576 3V"),
        DEVICE( VIA,            VIA_82C585,     "VT 82C585VP Apollo VP-1"),
-       DEVICE( VIA,            VIA_82C586_0,   "VT 82C586 Apollo VP-1"),
+       DEVICE( VIA,            VIA_82C586,     "VT 82C586 Apollo VP-1"),
        DEVICE( VIA,            VIA_82C416,     "VT 82C416MV"),
        DEVICE( VORTEX,         VORTEX_GDT60x0, "GDT 60x0"),
        DEVICE( VORTEX,         VORTEX_GDT6000B,"GDT 6000b"),
index 0472487e0f624e74bd320dbd76a5041b8188bc27..dcf4c46a6ec35628003004845e9718179abb73b3 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/fs.h>
 #include <linux/dalloc.h>
 #include <linux/dlists.h>
+#include <linux/malloc.h>
 
 /* this should be removed after the beta phase */
 /* #define DEBUG */
 #define D_RECURSIVE 4
 #define D_NO_FREE   8
 
-/* adjust these constants if you know a probability distribution ... */
-#define D_SMALL 16
-#define D_MEDIUM 64
-#define D_LARGE 256
-#define D_HUGE D_MAXLEN
-
-#define BASE_DHEADER(x) (struct dheader*)((unsigned long)(x) & ~(PAGE_SIZE-1))
-#define BYTE_ADD(x,n) (void*)((char*)(x) + (n))
-#define BYTE_SUB(x,n) (void*)((char*)(x) - (n))
-
-/* This is for global allocation of dentries.  Remove this when
- * converting to SLAB.
- */
-struct dheader {
-       struct dentry * emptylist;
-       short free, maxfree;
-       struct dheader * next;
-       struct dheader * prev;
-};
-
-struct anchors {
-       struct dheader * free; /* each contains at least 1 empty dentry */
-       struct dheader * full; /* all the used up ones */
-       struct dheader * dir_free; 
-       struct dheader * dir_full; 
-};
-
 /* This is only used for directory dentries. Think of it as an extension
  * of the dentry.
  * It is defined as separate struct, so it uses up space only
@@ -133,9 +107,6 @@ struct ddir {
        unsigned short dd_negs; /* # of negative entries */
 };
 
-DEF_INSERT(header,struct dheader,next,prev)
-DEF_REMOVE(header,struct dheader,next,prev)
-
 DEF_INSERT(alias,struct dentry,d_next,d_prev)
 DEF_REMOVE(alias,struct dentry,d_next,d_prev)
 
@@ -145,13 +116,10 @@ DEF_REMOVE(hash,struct dentry,d_hash_next,d_hash_prev)
 DEF_INSERT(basket,struct dentry,d_basket_next,d_basket_prev)
 DEF_REMOVE(basket,struct dentry,d_basket_next,d_basket_prev)
 
-static struct anchors anchors[4];
-
 struct dentry * the_root = NULL;
 
 unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end)
 {
-       memset(anchors, 0, sizeof(anchors));
        return mem_start;
 }
 
@@ -260,7 +228,7 @@ void printpath(struct dentry * entry)
 {
        if(!IS_ROOT(entry))
                printpath(entry->d_parent);
-       printk("/%s", entry->d_name);
+       printk("/%s", entry->d_name.name);
 }
 
 static inline long has_sons(struct ddir * ddir)
@@ -310,82 +278,42 @@ static void d_panic(void)
        panic("VFS: dcache directory corruption");
 }
 
+/*
+ * IF this is a directory, the ddir has been allocated right
+ * after the dentry.
+ */
 static inline struct ddir * d_dir(struct dentry * entry)
 {
-       struct ddir * res = BYTE_SUB(entry, sizeof(struct ddir));
-
        if(!(entry->d_flag & D_DIR))
                d_panic();
-#ifdef DEBUG
-       if(!entry)
-               panic("entry NULL!");
-       if(BASE_DHEADER(res) != BASE_DHEADER(entry))
-               printk("Scheisse!!!\n");
-#endif
-       return res;
+       return (struct ddir *) (entry+1);
 }
 
-static /*inline*/ struct dheader * dinit(int isdir, int size)
+#define NAME_ALLOC_LEN(len)    ((len+16) & ~15)
+
+struct dentry * d_alloc(struct dentry * parent, int len, int isdir)
 {
-       struct dheader * res = (struct dheader*)__get_free_page(GFP_KERNEL);
-       int restlen = PAGE_SIZE - sizeof(struct dheader);
-       struct dentry * ptr = BYTE_ADD(res, sizeof(struct dheader));
+       struct dentry *res;
+       int size = sizeof(struct dentry);
+       int flag = 0;
 
-       if(!res)
-               return NULL;
-        memset(res, 0, sizeof(struct dheader));
-       if(isdir) {
-               ptr = BYTE_ADD(ptr, sizeof(struct ddir));
+       if (isdir) {
                size += sizeof(struct ddir);
+               flag = D_DIR;
        }
-       if(BASE_DHEADER(ptr) != res) 
-               panic("Bad kernel page alignment");
-       size += sizeof(struct dentry) - D_MAXLEN;
-       res->emptylist = NULL;
-       res->free = 0;
-       while(restlen >= size) {
-#ifdef DEBUG
-               ins(ptr);
-               if(BASE_DHEADER(ptr) != res)
-                       panic("Wrong dinit!");
-#endif
-               ptr->d_next = res->emptylist;
-               res->emptylist = ptr;
-               ptr = BYTE_ADD(ptr, size);
-               res->free++;
-               restlen -= size;
-       }
-       res->maxfree = res->free;
-       return res;
-}
+       res = kmalloc(size, GFP_KERNEL);
+       if (!res)
+               return NULL;
+       memset(res, 0, size);
+       res->d_flag = flag;
 
-static /*inline*/ struct dentry * __dalloc(struct anchors * anchor,
-                                          struct dentry * parent, int isdir,
-                                          int len, int size)
-{
-       struct dheader ** free = isdir ? &anchor->dir_free : &anchor->free;
-       struct dheader ** full = isdir ? &anchor->dir_full : &anchor->full;
-       struct dheader * base = *free;
-       struct dentry * res;
-
-       if(!base) {
-               base = dinit(isdir, size);
-               if(!base)
-                       return NULL;
-               insert_header(free, base);
-       }
-       base->free--;
-       res = base->emptylist;
-       if(!(base->emptylist = res->d_next)) {
-               remove_header(free, base);
-               insert_header(full, base);
-       }
-       memset(res, 0, sizeof(struct dentry) - D_MAXLEN);
-       if(isdir) {
-               res->d_flag = D_DIR;
-               memset(d_dir(res), 0, sizeof(struct ddir));
+       res->d_name.name = kmalloc(NAME_ALLOC_LEN(len), GFP_KERNEL);
+       if (!res->d_name.name) {
+               kfree(res);
+               return NULL;
        }
-       res->d_len = len;
+       
+       res->d_name.len = len;
        res->d_parent = parent;
        if(parent) {
                struct ddir * pdir = d_dir(parent);
@@ -403,33 +331,6 @@ static /*inline*/ struct dentry * __dalloc(struct anchors * anchor,
        return res;
 }
 
-struct dentry * d_alloc(struct dentry * parent, int len, int isdir)
-{
-       int i, size;
-
-#ifdef DEBUG
-        if(the_root)
-               recursive_test(the_root);
-       LOG("d_alloc", parent);
-#endif
-       if(len >= D_MEDIUM) {
-               if(len >= D_LARGE) {
-                       i = 3;
-                       size = D_HUGE;
-               } else {
-                       i = 2;
-                       size = D_LARGE;
-               } 
-       } else if(len >= D_SMALL) {
-               i = 1;
-               size = D_MEDIUM;
-       } else {
-               i = 0;
-               size = D_SMALL;
-       }
-       return __dalloc(&anchors[i], parent, isdir, len, size);
-}
-
 extern blocking struct dentry * d_alloc_root(struct inode * root_inode)
 {
        struct dentry * res = the_root;
@@ -442,7 +343,7 @@ extern blocking struct dentry * d_alloc_root(struct inode * root_inode)
                the_root = res = d_alloc(NULL, 0, 1);
                LOG("d_alloc_root", res);
                res->d_parent = res;
-               res->d_name[0]='\0';
+               res->d_name.name[0]='\0';
                ddir = d_dir(res);
                ddir->dd_alloced = 999; /* protect from deletion */
        }
@@ -460,8 +361,8 @@ static inline unsigned long d_hash(char first, char last)
 
 static inline struct dentry ** d_base_entry(struct ddir * pdir, struct dentry * entry)
 {
-       return &pdir->dd_hashtable[d_hash(entry->d_name[0],
-                                         entry->d_name[entry->d_len-1])];
+       return &pdir->dd_hashtable[d_hash(entry->d_name.name[0],
+                                         entry->d_name.name[entry->d_name.len-1])];
 }
 
 static inline struct dentry ** d_base_qstr(struct ddir * pdir,
@@ -569,12 +470,8 @@ static /*inline*/ void _d_handle_zombie(struct dentry * entry,
 }
 
 static /*inline*/ blocking void _d_del(struct dentry * entry,
-                                      struct anchors * anchor,
                                       int flags)
 {
-       struct dheader ** free;
-       struct dheader ** full;
-       struct dheader * base = BASE_DHEADER(entry);
        struct ddir * ddir = NULL;
        struct ddir * pdir;
        struct inode * inode = entry->d_flag & D_PRELIMINARY ? NULL : entry->u.d_inode;
@@ -587,13 +484,6 @@ static /*inline*/ blocking void _d_del(struct dentry * entry,
                printk("VFS: dcache parent is NULL\n");
                return;
        }
-       if(entry->d_flag & D_DIR) {
-               free = &anchor->dir_free;
-               full = &anchor->dir_full;
-       } else {
-               free = &anchor->free;
-               full = &anchor->full;
-       }
        pdir = d_dir(entry->d_parent);
        if(!IS_ROOT(entry))
                _d_remove_from_parent(entry, pdir, inode, flags);
@@ -636,50 +526,23 @@ static /*inline*/ blocking void _d_del(struct dentry * entry,
                }
        }
        if(!(flags & D_NO_FREE) && !(entry->d_flag & D_ZOMBIE)) {
-               base->free++;
-               if(base->free == base->maxfree) {
-#ifndef DEBUG
-                       remove_header(free, base);
-                       free_page((unsigned long)base);
-                       goto done;
-#endif
-               }
-               entry->d_next = base->emptylist;
-               base->emptylist = entry;
-               if(!entry->d_next) {
-                       remove_header(full, base);
-                       insert_header(free, base);
-               }
+               kfree(entry->d_name.name);
+               kfree(entry);
 #ifdef DEBUG
                x_freed++;
 #endif
        }
-#ifndef DEBUG
-done:
-#else
+#ifdef DEBUG
        x_free++;
 #endif
 }
 
 blocking void d_del(struct dentry * entry, int flags)
 {
-       int i;
-
        if(!entry)
                return;
        LOG("d_clear", entry);
-       if(entry->d_len >= D_MEDIUM) {
-               if(entry->d_len >= D_LARGE) {
-                       i = 3;
-               } else {
-                       i = 2;
-               } 
-       } else if(entry->d_len >= D_SMALL) {
-               i = 1;
-       } else {
-               i = 0;
-       }
-       _d_del(entry, &anchors[i], flags);
+       _d_del(entry, flags);
 }
 
 static inline struct dentry * __dlookup(struct dentry ** base,
@@ -694,10 +557,10 @@ static inline struct dentry * __dlookup(struct dentry ** base,
                if(appendix)
                        totallen += appendix->len;
                do {
-                       if(tmp->d_len == totallen                       &&
+                       if(tmp->d_name.len == totallen                  &&
                           !(tmp->d_flag & D_DUPLICATE)                 &&
-                          !strncmp(tmp->d_name, name->name, name->len) &&
-                          (!appendix || !strncmp(tmp->d_name+name->len,
+                          !strncmp(tmp->d_name.name, name->name, name->len)    &&
+                          (!appendix || !strncmp(tmp->d_name.name+name->len,
                                                  appendix->name, appendix->len)))
                                return tmp;
                        tmp = tmp->d_hash_next;
@@ -755,7 +618,7 @@ static /*inline*/ blocking void _d_insert_to_parent(struct dentry * entry,
        if(inode && inode->i_dentry && (entry->d_flag & D_DIR)) {
                struct dentry * tmp = inode->i_dentry;
                printk("Auweia inode=%p entry=%p (%p %p %s)\n",
-                      inode, entry, parent->u.d_inode, parent, parent->d_name);
+                      inode, entry, parent->u.d_inode, parent, parent->d_name.name);
                printk("entry path="); printpath(entry); printk("\n");
                do {
                        TST("auweia",tmp);
@@ -801,15 +664,15 @@ blocking void d_add(struct dentry * entry, struct inode * inode,
        LOG("d_add", entry);
 #endif
        if(ininame) {
-               if(ininame->len != entry->d_len) {
+               if(ininame->len != entry->d_name.len) {
                        printk("VFS: d_add with wrong string length");
-                       entry->d_len = ininame->len; /* kludge */
+                       entry->d_name.len = ininame->len; /* kludge */
                }
-               memcpy(entry->d_name, ininame->name, ininame->len);
-               entry->d_name[ininame->len] = '\0';
+               memcpy(entry->d_name.name, ininame->name, ininame->len);
+               entry->d_name.name[ininame->len] = '\0';
        } else {
-               dummy.name = entry->d_name;
-               dummy.len = entry->d_len;
+               dummy.name = entry->d_name.name;
+               dummy.len = entry->d_name.len;
                ininame = &dummy;
        }
         if(entry->d_flag & D_HASHED)
@@ -871,11 +734,45 @@ blocking void d_entry_preliminary(struct dentry * parent,
        }
 }
 
+static inline void alloc_new_name(struct dentry * entry, int len)
+{
+       int alloc_len = NAME_ALLOC_LEN(len);
+       char *name;
+
+       if (alloc_len == NAME_ALLOC_LEN(entry->d_name.len))
+               return;
+       name = kmalloc(alloc_len, GFP_KERNEL);
+       if (!name)
+               printk("out of memory for dcache\n");
+       kfree(entry->d_name.name);
+       entry->d_name.name = name;
+}
+
+static inline void d_remove_old_parent(struct dentry * entry)
+{
+       struct ddir * pdir;
+       struct inode * inode;
+
+       pdir = d_dir(entry->d_parent);
+       inode = entry->u.d_inode;
+       _d_remove_from_parent(entry, pdir, inode, D_NO_CLEAR_INODE);
+}
+
+static inline void d_add_new_parent(struct dentry * entry, struct inode * new_parent)
+{
+       struct ddir * pdir;
+       struct inode * inode;
+
+       pdir = d_dir(entry->d_parent = new_parent->i_dentry);
+       inode = entry->u.d_inode;
+
+       _d_insert_to_parent(entry, pdir, inode, &entry->d_name, entry->d_flag);
+}
+
+
 blocking void d_move(struct dentry * entry, struct inode * newdir, 
                     struct qstr * newname, struct qstr * newapp)
 {
-       struct ddir tmp;
-       struct dentry * new;
        struct inode * inode;
        int len;
        int flags;
@@ -891,38 +788,29 @@ blocking void d_move(struct dentry * entry, struct inode * newdir,
                return;
        }
 #if 0
-printk("d_move %p '%s' -> '%s%s' dent_count=%d\n", inode, entry->d_name,
+printk("d_move %p '%s' -> '%s%s' dent_count=%d\n", inode, entry->d_name.name,
        newname->name, newapp ? newapp->name : "", inode->i_dent_count);
 #endif
        if(flags & D_ZOMBIE) {
                printk("VFS: moving zombie entry\n");
        }
-       if(flags & D_DIR) {
-               struct ddir * ddir = d_dir(entry);
 
-               memcpy(&tmp, ddir, sizeof(struct ddir));
+       d_remove_old_parent(entry);
 
-                /* Simulate empty dir for d_del(). */
-               memset(ddir, 0, sizeof(struct ddir));
-       }
        len = newname->len;
        if(newapp) {
                len += newapp->len;
                flags |= D_BASKET;
        } else
                flags &= ~D_BASKET;
-       new = d_alloc(newdir->i_dentry, len, flags & D_DIR);
-       memcpy(new->d_name, newname->name, newname->len);
+       alloc_new_name(entry, len);
+       memcpy(entry->d_name.name, newname->name, newname->len);
        if(newapp)
-               memcpy(new->d_name+newname->len, newapp->name, newapp->len);
-       new->d_name[len] = '\0';
-       d_del(entry, D_NO_CLEAR_INODE);
-       d_add(new, inode, NULL, flags & (D_DIR|D_BASKET));
-       if(flags & D_DIR) {
-               struct ddir * ddir = d_dir(new);
-
-               memcpy(ddir, &tmp, sizeof(struct ddir));
-               }
+               memcpy(entry->d_name.name+newname->len, newapp->name, newapp->len);
+       entry->d_name.name[len] = '\0';
+       entry->d_name.len = len;
+
+       d_add_new_parent(entry, newdir);
 }
 
 int d_path(struct dentry * entry, struct inode * chroot, char * buf)
@@ -939,8 +827,8 @@ int d_path(struct dentry * entry, struct inode * chroot, char * buf)
                        *buf++ = '/';
                        len++;
                }
-               memcpy(buf, entry->d_name, entry->d_len);
-               return len + entry->d_len;
+               memcpy(buf, entry->d_name.name, entry->d_name.len);
+               return len + entry->d_name.len;
        }
 }
 
@@ -966,7 +854,7 @@ blocking struct inode * d_inode(struct dentry ** changing_entry)
 
 #ifdef CONFIG_DCACHE_PRELOAD
        if(entry->d_flag & D_PRELIMINARY) {
-               struct qstr name = { entry->d_name, entry->d_len };
+               struct qstr name = { entry->d_name.name, entry->d_name.len };
                struct ddir * pdir = d_dir(entry->d_parent);
                struct dentry ** base = d_base_qstr(pdir, &name, NULL);
                struct dentry * found;
@@ -1014,7 +902,7 @@ blocking struct inode * d_inode(struct dentry ** changing_entry)
                        d_del(entry, D_NO_CLEAR_INODE);
                        *changing_entry = found;
                } else if(S_ISDIR(inode->i_mode)) {
-                       struct dentry * new = d_alloc(entry->d_parent, entry->d_len, 1);
+                       struct dentry * new = d_alloc(entry->d_parent, entry->d_name.len, 1);
                        if(new)
                                d_add(new, inode, &name, D_DIR);
                        *changing_entry = new;
index 198179b98c3d17066a48c25a8c7212f200af6ef4..c95b1a36733694607fd23a4332a3fe9cb0999d22 100644 (file)
@@ -951,7 +951,7 @@ static void basket_name(struct inode * dir, struct dentry * entry)
 {
        char prefix[32];
        struct qstr prename = { prefix, 14 };
-       struct qstr entname = { entry->d_name, entry->d_len };
+       struct qstr entname = { entry->d_name.name, entry->d_name.len };
        struct inode * inode;
        struct dentry * old = entry; /* dummy */
        int i;
index a86398ac3764e9add52cac7d2742c98f40ab0494..df2f5fb84b2014bd853b560aaecc223e9ba4cd7b 100644 (file)
@@ -266,8 +266,8 @@ asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count)
                                if(inode) {
                                        nr++;
                                        if(nr > (file->f_pos & ~BASKET_BIT)) {
-                                               int err = filldir(&buf, ptr->d_name,
-                                                                 ptr->d_len,
+                                               int err = filldir(&buf, ptr->d_name.name,
+                                                                 ptr->d_name.len,
                                                                  file->f_pos,
                                                                  inode->i_ino);
                                                if(err)
index ec47301aac26daf35db6be24a9c61d08a54b173c..8a5efcd2b5524f150f097ca3c202a5d351b502c1 100644 (file)
@@ -765,9 +765,9 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
                struct dentry * old = dir_i->i_dentry;
                struct dentry * new;
                vfs_lock();
-               new = d_alloc(old->d_parent, old->d_len, 1);
+               new = d_alloc(old->d_parent, old->d_name.len, 1);
                if(new) {
-                       struct qstr copy = { old->d_name, old->d_len };
+                       struct qstr copy = { old->d_name.name, old->d_name.len };
                        d_add(new, sb->s_mounted, &copy, D_DUPLICATE);
                        vfs_unlock();
                } else {
index 659eef522fc5d343ae9b44fb52ca750ca1478bf5..64f78b233aa71d42ddb843f77e79eb7134a3def3 100644 (file)
@@ -9,7 +9,7 @@
  * <schoebel@informatik.uni-stuttgart.de>.
  */
 
-#define D_MAXLEN   1024
+#define D_MAXLEN 1024
 
 /* public flags for d_add() */
 #define D_NORMAL     0
 
 #define IS_ROOT(x) ((x) == (x)->d_parent)
 
+/* "quick string" -- I introduced this to shorten the parameter list
+ * of many routines. Think of it as a (str,stlen) pair.
+ * Storing the len instead of doing strlen() very often is performance
+ * critical.
+ */
+struct qstr {
+       char * name;
+       int len;
+};
+
 struct dentry {
        union {
                struct inode  * d_inode;  /* Where the name belongs to */
@@ -38,19 +48,8 @@ struct dentry {
        struct dentry * d_hash_prev;
        struct dentry * d_basket_next;
        struct dentry * d_basket_prev;
-       short d_len;              /* set by dalloc() */
-       short d_flag;
-       char d_name[D_MAXLEN];
-};
-
-/* "quick string" -- I introduced this to shorten the parameter list
- * of many routines. Think of it as a (str,stlen) pair.
- * Storing the len instead of doing strlen() very often is performance
- * critical.
- */
-struct qstr {
-       const char * name;
-       int len;
+       struct qstr d_name;
+       unsigned int d_flag;
 };
 
 extern struct dentry * the_root;
index 76fa53a7e9fc9a5b868e2fe8218f6f7610d1f579..668abd39115b9fa2da436a9c9316076496310d5d 100644 (file)
@@ -15,7 +15,9 @@
 #include <linux/net.h>
 #include <linux/kdev_t.h>
 #include <linux/ioctl.h>
+
 #include <asm/atomic.h>
+#include <asm/bitops.h>
 
 /* Prefixes for routines (having no effect), but indicate what
  * the routine may do. This can greatly ease reasoning about routines...
index bc742821095ebf9a51df528a9d5874f41815ebf2..8b0602f8c8bc769c3bd9f1c2b31062c17e6084e0 100644 (file)
 #define PCI_DEVICE_ID_VIA_82C586_1     0x0571
 #define PCI_DEVICE_ID_VIA_82C576       0x0576
 #define PCI_DEVICE_ID_VIA_82C585       0x0585
-#define PCI_DEVICE_ID_VIA_82C586_0     0x0586
+#define PCI_DEVICE_ID_VIA_82C586       0x0586
 #define PCI_DEVICE_ID_VIA_82C416       0x1571
 
 #define PCI_VENDOR_ID_VORTEX           0x1119
index 28d93f56f0a9f95e57e70d3f472df6ef03f266ff..d1edca9c187391287e25e8554e78e076e5fc9b31 100644 (file)
@@ -31,6 +31,7 @@
 // * Only resolves operands of jump and call instructions.
 
 #include <fstream.h>
+#include <strstream.h>
 #include <iomanip.h>
 #include <stdio.h>
 #include <string.h>
@@ -184,9 +185,23 @@ NameList::decode(unsigned char* code, long eip_addr)
     
     char buf[1024];
     int lines = 0;
+    int eip_seen = 0;
+    long offset;
     while (fgets(buf, sizeof(buf), objdump_FILE)) {
+       if (eip_seen && buf[4] == ':') {
+           // assume objdump from binutils 2.8..., reformat to old style
+           offset = strtol(buf, 0, 16);
+           char newbuf[sizeof(buf)];
+           memset(newbuf, '\0', sizeof(newbuf));
+           ostrstream ost(newbuf, sizeof(newbuf));
+           ost.width(8);
+           ost << offset;
+           ost << " <_EIP+" << offset << ">: " << &buf[6] << ends;
+           strcpy(buf, newbuf);
+       }
        if (!strnequ(&buf[9], "<_EIP", 5))
            continue;
+       eip_seen = 1;
        if (strstr(buf, " is out of bounds"))
            break;
        lines++;
@@ -195,19 +210,28 @@ NameList::decode(unsigned char* code, long eip_addr)
            cout << buf;
            continue;
        }
-       long offset = strtol(buf, 0, 16);
-       char* bp_0 = strchr(buf, '>') + 2;
+       offset = strtol(buf, 0, 16);
+       char* bp_0 = strchr(buf, '>');
        KSym* ksym = find(eip_addr + offset);
+       if (bp_0)
+           bp_0 += 2;
+       else
+           bp_0 = strchr(buf, ':');
        if (ksym)
            cout << *ksym << ' ';
-       char* bp = bp_0;
+       char *bp_1 = strstr(bp_0, "\t");        // objdump from binutils 2.8...
+       if (bp_1)
+           ++bp_1;
+       else
+           bp_1 = bp_0;
+       char *bp = bp_1;
        while (!isspace(*bp))
            bp++;
        while (isspace(*bp))
            bp++;
-       if (*bp != '0') {
+       if (!isxdigit(*bp)) {
            cout << bp_0;
-       } else if (*bp_0 == 'j' || strnequ(bp_0, "call", 4)) { // a jump or call insn
+       } else if (*bp_1 == 'j' || strnequ(bp_1, "call", 4)) { // a jump or call insn
            long rel_addr = strtol(bp, 0, 16);
            ksym = find(eip_addr + rel_addr);
            if (ksym) {