diff -u --recursive --new-file v2.1.43/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.43/linux/Documentation/Configure.help Mon Jun 16 16:35:53 1997 +++ linux/Documentation/Configure.help Mon Jun 16 17:18:38 1997 @@ -287,17 +287,19 @@ 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 diff -u --recursive --new-file v2.1.43/linux/Makefile linux/Makefile --- v2.1.43/linux/Makefile Mon Jun 16 16:35:53 1997 +++ linux/Makefile Mon Jun 16 16:45:03 1997 @@ -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/) diff -u --recursive --new-file v2.1.43/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.43/linux/drivers/block/ide.c Mon Jun 16 16:35:54 1997 +++ linux/drivers/block/ide.c Mon Jun 16 17:18:38 1997 @@ -2603,6 +2603,7 @@ 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 */ diff -u --recursive --new-file v2.1.43/linux/drivers/block/ide.h linux/drivers/block/ide.h --- v2.1.43/linux/drivers/block/ide.h Mon Jun 16 16:35:54 1997 +++ linux/drivers/block/ide.h Tue Jun 17 18:42:44 1997 @@ -298,7 +298,7 @@ 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 { diff -u --recursive --new-file v2.1.43/linux/drivers/block/triton.c linux/drivers/block/triton.c --- v2.1.43/linux/drivers/block/triton.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/block/triton.c Mon Jun 16 17:18:38 1997 @@ -122,15 +122,25 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ } 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 */ } diff -u --recursive --new-file v2.1.43/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.1.43/linux/drivers/char/rtc.c Mon Jun 16 16:35:55 1997 +++ linux/drivers/char/rtc.c Tue Jun 17 09:31:15 1997 @@ -180,7 +180,7 @@ 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; diff -u --recursive --new-file v2.1.43/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.43/linux/drivers/net/Config.in Mon Jun 16 16:35:55 1997 +++ linux/drivers/net/Config.in Tue Jun 17 15:44:23 1997 @@ -143,12 +143,8 @@ 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 diff -u --recursive --new-file v2.1.43/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.43/linux/drivers/pci/pci.c Mon Jun 16 16:35:56 1997 +++ linux/drivers/pci/pci.c Mon Jun 16 17:21:11 1997 @@ -204,7 +204,7 @@ 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"), diff -u --recursive --new-file v2.1.43/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.43/linux/fs/dcache.c Mon Jun 16 16:35:57 1997 +++ linux/fs/dcache.c Tue Jun 17 20:16:40 1997 @@ -71,6 +71,7 @@ #include #include #include +#include /* this should be removed after the beta phase */ /* #define DEBUG */ @@ -90,33 +91,6 @@ #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 @@ 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_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 @@ { 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 @@ 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 @@ 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 @@ 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 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*/ 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 @@ 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 @@ } } 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 @@ 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 @@ 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 @@ 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 @@ } } +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 @@ 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(entry->d_name.name+newname->len, newapp->name, newapp->len); + entry->d_name.name[len] = '\0'; + entry->d_name.len = len; - memcpy(ddir, &tmp, sizeof(struct ddir)); - } + d_add_new_parent(entry, newdir); } int d_path(struct dentry * entry, struct inode * chroot, char * buf) @@ -939,8 +827,8 @@ *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 @@ #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 @@ 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; diff -u --recursive --new-file v2.1.43/linux/fs/namei.c linux/fs/namei.c --- v2.1.43/linux/fs/namei.c Mon Jun 16 16:35:58 1997 +++ linux/fs/namei.c Tue Jun 17 15:47:12 1997 @@ -951,7 +951,7 @@ { 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; diff -u --recursive --new-file v2.1.43/linux/fs/readdir.c linux/fs/readdir.c --- v2.1.43/linux/fs/readdir.c Mon Jun 16 16:35:59 1997 +++ linux/fs/readdir.c Tue Jun 17 15:58:08 1997 @@ -266,8 +266,8 @@ 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) diff -u --recursive --new-file v2.1.43/linux/fs/super.c linux/fs/super.c --- v2.1.43/linux/fs/super.c Mon Jun 16 16:35:59 1997 +++ linux/fs/super.c Tue Jun 17 15:46:42 1997 @@ -765,9 +765,9 @@ 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, ©, D_DUPLICATE); vfs_unlock(); } else { diff -u --recursive --new-file v2.1.43/linux/include/linux/dalloc.h linux/include/linux/dalloc.h --- v2.1.43/linux/include/linux/dalloc.h Mon Jun 16 16:36:00 1997 +++ linux/include/linux/dalloc.h Tue Jun 17 15:38:05 1997 @@ -9,7 +9,7 @@ * . */ -#define D_MAXLEN 1024 +#define D_MAXLEN 1024 /* public flags for d_add() */ #define D_NORMAL 0 @@ -26,6 +26,16 @@ #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 * 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; diff -u --recursive --new-file v2.1.43/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.43/linux/include/linux/fs.h Mon Jun 16 16:36:00 1997 +++ linux/include/linux/fs.h Tue Jun 17 18:42:19 1997 @@ -15,7 +15,9 @@ #include #include #include + #include +#include /* Prefixes for routines (having no effect), but indicate what * the routine may do. This can greatly ease reasoning about routines... diff -u --recursive --new-file v2.1.43/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.43/linux/include/linux/pci.h Mon Jun 16 16:36:00 1997 +++ linux/include/linux/pci.h Mon Jun 16 17:20:17 1997 @@ -497,7 +497,7 @@ #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 diff -u --recursive --new-file v2.1.43/linux/scripts/ksymoops.cc linux/scripts/ksymoops.cc --- v2.1.43/linux/scripts/ksymoops.cc Sun Nov 10 04:04:07 1996 +++ linux/scripts/ksymoops.cc Tue Jun 17 17:12:51 1997 @@ -31,6 +31,7 @@ // * Only resolves operands of jump and call instructions. #include +#include #include #include #include @@ -184,9 +185,23 @@ 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 @@ 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) {