Commit 7388b7aa authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.47

parent 4eeb9af8
...@@ -134,6 +134,12 @@ S: Computer Science Department ...@@ -134,6 +134,12 @@ S: Computer Science Department
S: Baltimore, Maryland 21218 S: Baltimore, Maryland 21218
S: USA S: USA
N: Axel Boldt
E: boldt@math.ucsb.edu
W: http://math-www.uni-paderborn.de/~axel/
D: Configuration help text support
D: Linux CD and Support Giveaway List
N: John Boyd N: John Boyd
E: boyd@cis.ohio-state.edu E: boyd@cis.ohio-state.edu
D: Co-author of wd7000 SCSI driver D: Co-author of wd7000 SCSI driver
...@@ -214,7 +220,7 @@ S: United Kingdom ...@@ -214,7 +220,7 @@ S: United Kingdom
N: Ray Dassen N: Ray Dassen
E: jdassen@wi.LeidenUniv.nl E: jdassen@wi.LeidenUniv.nl
U: http://www.wi.leidenuniv.nl/~jdassen/ W: http://www.wi.leidenuniv.nl/~jdassen/
D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer, D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer,
D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels. D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels.
S: Zuidsingel 10A S: Zuidsingel 10A
......
This diff is collapsed.
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 46 SUBLEVEL = 47
ARCH = i386 ARCH = i386
......
...@@ -19,9 +19,9 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF ...@@ -19,9 +19,9 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_BINFMT_ELF" = "y" ]; then if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
fi fi
#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 #bool 'Use Pentium-specific optimizations (does NOT work on i386)' CONFIG_M586
#if [ "$CONFIG_M586" = "n" ]; then #if [ "$CONFIG_M586" = "n" ]; then
bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 bool 'Use 486-specific optimizations (does NOT work on i386)' CONFIG_M486
#fi #fi
mainmenu_option next_comment mainmenu_option next_comment
......
...@@ -41,6 +41,7 @@ CONFIG_BLK_DEV_IDECD=y ...@@ -41,6 +41,7 @@ CONFIG_BLK_DEV_IDECD=y
# Networking options # Networking options
# #
# CONFIG_FIREWALL is not set # CONFIG_FIREWALL is not set
# CONFIG_NET_ALIAS is not set
CONFIG_INET=y CONFIG_INET=y
# CONFIG_IP_FORWARD is not set # CONFIG_IP_FORWARD is not set
# CONFIG_IP_MULTICAST is not set # CONFIG_IP_MULTICAST is not set
...@@ -122,10 +123,6 @@ CONFIG_ISO9660_FS=y ...@@ -122,10 +123,6 @@ CONFIG_ISO9660_FS=y
# CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set # CONFIG_QIC02_TAPE is not set
# CONFIG_APM is not set # CONFIG_APM is not set
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
CONFIG_APM_CPU_IDLE=y
# CONFIG_APM_DISPLAY_BLANK is not set
# #
# Sound # Sound
......
...@@ -19,7 +19,6 @@ M_OBJS := ...@@ -19,7 +19,6 @@ M_OBJS :=
L_OBJS := tty_io.o n_tty.o console.o keyboard.o serial.o \ L_OBJS := tty_io.o n_tty.o console.o keyboard.o serial.o \
tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \ tty_ioctl.o pty.o vt.o mem.o vc_screen.o random.o \
defkeymap.o consolemap.o selection.o defkeymap.o consolemap.o selection.o
SYMTAB_OBJS :=
ifeq ($(CONFIG_CYCLADES),y) ifeq ($(CONFIG_CYCLADES),y)
L_OBJS += cyclades.o L_OBJS += cyclades.o
...@@ -98,8 +97,7 @@ L_OBJS += tpqic02.o ...@@ -98,8 +97,7 @@ L_OBJS += tpqic02.o
endif endif
ifdef CONFIG_APM ifdef CONFIG_APM
L_OBJS += apm_bios.o LX_OBJS += apm_bios.o
SYMTAB_OBJS += apm_bios.o
endif endif
ifdef M ifdef M
......
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
* *
* New TIOCLINUX variants added. * New TIOCLINUX variants added.
* -- mj@k332.feld.cvut.cz, 19-Nov-95 * -- mj@k332.feld.cvut.cz, 19-Nov-95
*
* Restrict vt switching via ioctl()
* -- grif@cs.ucr.edu, 5-Dec-95
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -97,6 +100,7 @@ int last_console = 0; ...@@ -97,6 +100,7 @@ int last_console = 0;
int kmsg_redirect = 0; int kmsg_redirect = 0;
struct tty_struct * redirect = NULL; struct tty_struct * redirect = NULL;
struct wait_queue * keypress_wait = NULL; struct wait_queue * keypress_wait = NULL;
char vt_dont_switch = 0;
static void initialize_tty_struct(struct tty_struct *tty); static void initialize_tty_struct(struct tty_struct *tty);
...@@ -523,7 +527,7 @@ void complete_change_console(unsigned int new_console) ...@@ -523,7 +527,7 @@ void complete_change_console(unsigned int new_console)
{ {
unsigned char old_vc_mode; unsigned char old_vc_mode;
if (new_console == fg_console) if ((new_console == fg_console) || (vt_dont_switch))
return; return;
if (!vc_cons_allocated(new_console)) if (!vc_cons_allocated(new_console))
return; return;
...@@ -594,7 +598,7 @@ void complete_change_console(unsigned int new_console) ...@@ -594,7 +598,7 @@ void complete_change_console(unsigned int new_console)
*/ */
void change_console(unsigned int new_console) void change_console(unsigned int new_console)
{ {
if (new_console == fg_console) if ((new_console == fg_console) || (vt_dont_switch))
return; return;
if (!vc_cons_allocated(new_console)) if (!vc_cons_allocated(new_console))
return; return;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
* Dynamic keymap and string allocation - aeb@cwi.nl - May 1994 * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
* Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
#include "diacr.h" #include "diacr.h"
#include "selection.h" #include "selection.h"
extern char vt_dont_switch;
extern struct tty_driver console_driver; extern struct tty_driver console_driver;
#define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count) #define VT_IS_IN_USE(i) (console_driver.table[i] && console_driver.table[i]->count)
...@@ -1094,7 +1096,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -1094,7 +1096,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i; return i;
return con_get_unimap(ct, &(ud->entry_ct), list); return con_get_unimap(ct, &(ud->entry_ct), list);
} }
case VT_LOCKSWITCH:
if (!suser())
return -EPERM;
vt_dont_switch = 1;
return 0;
case VT_UNLOCKSWITCH:
if (!suser())
return -EPERM;
vt_dont_switch = 0;
return 0;
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
......
...@@ -477,7 +477,12 @@ el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ...@@ -477,7 +477,12 @@ el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8); unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
if (dev->mem_start) { /* Use the shared memory. */ if (dev->mem_start) { /* Use the shared memory. */
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
return; return;
} }
......
...@@ -32,8 +32,6 @@ static const char *version = ...@@ -32,8 +32,6 @@ static const char *version =
Much of this code should have been cleaned up, but every attempt Much of this code should have been cleaned up, but every attempt
has broken some clone part. has broken some clone part.
Doesn't currently work on all shared memory cards.
Sources: Sources:
The National Semiconductor LAN Databook, and the 3Com 3c503 databook. The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
*/ */
...@@ -512,8 +510,9 @@ static void ei_receive(struct device *dev) ...@@ -512,8 +510,9 @@ static void ei_receive(struct device *dev)
if (rx_pkt_count > high_water_mark) if (rx_pkt_count > high_water_mark)
high_water_mark = rx_pkt_count; high_water_mark = rx_pkt_count;
/* Bug alert! Reset ENISR_OVER to avoid spurious overruns! */ /* We used to also ack ENISR_OVER here, but that would sometimes mask
outb_p(ENISR_RX+ENISR_RX_ERR+ENISR_OVER, e8390_base+EN0_ISR); a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
return; return;
} }
...@@ -550,7 +549,7 @@ static void ei_rx_overrun(struct device *dev) ...@@ -550,7 +549,7 @@ static void ei_rx_overrun(struct device *dev)
/* Remove packets right away. */ /* Remove packets right away. */
ei_receive(dev); ei_receive(dev);
outb_p(0xff, e8390_base+EN0_ISR); outb_p(ENISR_OVER, e8390_base+EN0_ISR);
/* Generic 8390 insns to start up again, same as in open_8390(). */ /* Generic 8390 insns to start up again, same as in open_8390(). */
outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */ outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
......
This diff is collapsed.
...@@ -299,7 +299,12 @@ e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ...@@ -299,7 +299,12 @@ e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
mem_on(ioaddr, shared_mem, ring_page); mem_on(ioaddr, shared_mem, ring_page);
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr)); memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(shared_mem);
#endif
/* Turn off memory access: we would need to reprogram the window anyway. */ /* Turn off memory access: we would need to reprogram the window anyway. */
mem_off(ioaddr); mem_off(ioaddr);
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/trdevice.h> #include <linux/trdevice.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
/* The network devices currently exist only in the socket namespace, so these /* The network devices currently exist only in the socket namespace, so these
entries are unused. The only ones that make sense are entries are unused. The only ones that make sense are
...@@ -293,6 +296,28 @@ void unregister_netdev(struct device *dev) ...@@ -293,6 +296,28 @@ void unregister_netdev(struct device *dev)
/* else */ /* else */
if (dev->start) if (dev->start)
printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name); printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
/*
* must jump over main_device+aliases
* avoid alias devices unregistration so that only
* net_alias module manages them
*/
#ifdef CONFIG_NET_ALIAS
if (dev_base == dev)
dev_base = net_alias_nextdev(dev);
else
{
while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
d = net_alias_nextdev(d);
if (d && (net_alias_nextdev(d) == dev))
{
/*
* critical: bypass by consider devices as blocks (maindev+aliases)
*/
net_alias_nextdev_set(d, net_alias_nextdev(dev));
}
#else
if (dev_base == dev) if (dev_base == dev)
dev_base = dev->next; dev_base = dev->next;
else else
...@@ -304,6 +329,7 @@ void unregister_netdev(struct device *dev) ...@@ -304,6 +329,7 @@ void unregister_netdev(struct device *dev)
{ {
d->next = dev->next; d->next = dev->next;
} }
#endif
else else
{ {
printk("unregister_netdev: '%s' not found\n", dev->name); printk("unregister_netdev: '%s' not found\n", dev->name);
......
...@@ -270,7 +270,12 @@ ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ...@@ -270,7 +270,12 @@ ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8);
outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */ outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
} }
......
...@@ -129,6 +129,13 @@ int wd_probe1(struct device *dev, int ioaddr) ...@@ -129,6 +129,13 @@ int wd_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, 0); dev = init_etherdev(0, 0);
} }
/* Check for semi-valid mem_start/end values if supplied. */
if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
dev->mem_start = 0;
dev->mem_end = 0;
}
if (ei_debug && version_printed++ == 0) if (ei_debug && version_printed++ == 0)
printk(version); printk(version);
...@@ -246,7 +253,7 @@ int wd_probe1(struct device *dev, int ioaddr) ...@@ -246,7 +253,7 @@ int wd_probe1(struct device *dev, int ioaddr)
/* Snarf the interrupt now. There's no point in waiting since we cannot /* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */ share and the board will usually be enabled. */
if (request_irq(dev->irq, ei_interrupt, 0, "wd")) { if (request_irq(dev->irq, ei_interrupt, 0, model_name)) {
printk (" unable to get IRQ %d.\n", dev->irq); printk (" unable to get IRQ %d.\n", dev->irq);
return EAGAIN; return EAGAIN;
} }
...@@ -259,7 +266,7 @@ int wd_probe1(struct device *dev, int ioaddr) ...@@ -259,7 +266,7 @@ int wd_probe1(struct device *dev, int ioaddr)
} }
/* OK, were are certain this is going to work. Setup the device. */ /* OK, were are certain this is going to work. Setup the device. */
request_region(ioaddr, WD_IO_EXTENT,"wd"); request_region(ioaddr, WD_IO_EXTENT, model_name);
ei_status.name = model_name; ei_status.name = model_name;
ei_status.word16 = word16; ei_status.word16 = word16;
...@@ -352,7 +359,12 @@ wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ...@@ -352,7 +359,12 @@ wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
if (ei_status.word16) if (ei_status.word16)
outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
#ifdef notdef
/* Officially this is what we are doing, but the readl() is faster */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
#else
((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
} }
/* Block input and output are easy on shared memory ethercards, and trivial /* Block input and output are easy on shared memory ethercards, and trivial
......
...@@ -918,7 +918,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt) ...@@ -918,7 +918,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt)
ptr->host_scribble = NULL; ptr->host_scribble = NULL;
ptr->result = DID_ABORT << 16; ptr->result = DID_ABORT << 16;
ptr->done(ptr); ptr->scsi_done(ptr);
return SCSI_ABORT_SUCCESS; return SCSI_ABORT_SUCCESS;
} }
...@@ -942,7 +942,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt) ...@@ -942,7 +942,7 @@ int aha152x_abort( Scsi_Cmnd *SCpnt)
/* target entered bus free before COMMAND COMPLETE, nothing to abort */ /* target entered bus free before COMMAND COMPLETE, nothing to abort */
restore_flags(flags); restore_flags(flags);
current_SC->result = DID_ERROR << 16; current_SC->result = DID_ERROR << 16;
current_SC->done(current_SC); current_SC->scsi_done(current_SC);
current_SC = (Scsi_Cmnd *) NULL; current_SC = (Scsi_Cmnd *) NULL;
return SCSI_ABORT_SUCCESS; return SCSI_ABORT_SUCCESS;
} }
...@@ -1063,7 +1063,7 @@ int aha152x_reset(Scsi_Cmnd * __unused) ...@@ -1063,7 +1063,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
{ {
current_SC->host_scribble = NULL; current_SC->host_scribble = NULL;
current_SC->result = DID_RESET << 16; current_SC->result = DID_RESET << 16;
current_SC->done(current_SC); current_SC->scsi_done(current_SC);
current_SC=NULL; current_SC=NULL;
} }
...@@ -1083,7 +1083,7 @@ int aha152x_reset(Scsi_Cmnd * __unused) ...@@ -1083,7 +1083,7 @@ int aha152x_reset(Scsi_Cmnd * __unused)
ptr->host_scribble = NULL; ptr->host_scribble = NULL;
ptr->result = DID_RESET << 16; ptr->result = DID_RESET << 16;
ptr->done(ptr); ptr->scsi_done(ptr);
ptr = next; ptr = next;
} }
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#define CONST_XSENSE 0x08 #define CONST_XSENSE 0x08
#define CONST_CMND 0x10 #define CONST_CMND 0x10
#define CONST_MSG 0x20 #define CONST_MSG 0x20
#define CONST_HOST 0x40
#define CONST_DRIVER 0x80
static const char unknown[] = "UNKNOWN"; static const char unknown[] = "UNKNOWN";
...@@ -30,7 +32,8 @@ static const char unknown[] = "UNKNOWN"; ...@@ -30,7 +32,8 @@ static const char unknown[] = "UNKNOWN";
#ifdef CONSTANTS #ifdef CONSTANTS
#undef CONSTANTS #undef CONSTANTS
#endif #endif
#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE | CONST_CMND | CONST_MSG) #define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE \
| CONST_CMND | CONST_MSG | CONST_HOST | CONST_DRIVER)
#endif #endif
#if (CONSTANTS & CONST_COMMAND) #if (CONSTANTS & CONST_COMMAND)
...@@ -568,6 +571,64 @@ void print_Scsi_Cmnd (Scsi_Cmnd *cmd) { ...@@ -568,6 +571,64 @@ void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
print_command (cmd->cmnd); print_command (cmd->cmnd);
} }
#if (CONSTANTS & CONST_HOST)
static const char * hostbyte_table[]={
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",NULL};
void print_hostbyte(int scsiresult)
{ static int maxcode=0;
int i;
if(!maxcode) {
for(i=0;hostbyte_table[i];i++) ;
maxcode=i-1;
}
printk("Hostbyte=0x%02x",host_byte(scsiresult));
if(host_byte(scsiresult)>maxcode) {
printk("is invalid ");
return;
}
printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
}
#else
void print_hostbyte(int scsiresult)
{ printk("Hostbyte=0x%02x ",hostbyte(scsiresult));
}
#endif
#if (CONSTANTS & CONST_DRIVER)
static const char * driverbyte_table[]={
"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",NULL };
static const char * driversuggest_table[]={"SUGGEST_OK",
"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
void print_driverbyte(int scsiresult)
{ static int driver_max=0,suggest_max=0;
int i,dr=driver_byte(scsiresult)&DRIVER_MASK,
su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
if(!driver_max) {
for(i=0;driverbyte_table[i];i++) ;
driver_max=i;
for(i=0;driversuggest_table[i];i++) ;
suggest_max=i;
}
printk("Driverbyte=0x%02x",driver_byte(scsiresult));
printk("(%s,%s) ",
dr<driver_max ? driverbyte_table[dr]:"invalid",
su<suggest_max ? driversuggest_table[su]:"invalid");
}
#else
void print_driverbyte(int scsiresult)
{ printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
}
#endif
/* /*
* Overrides for Emacs so that we almost follow Linus's tabbing style. * Overrides for Emacs so that we almost follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
This diff is collapsed.
...@@ -89,6 +89,7 @@ extern const unsigned char scsi_command_size[8]; ...@@ -89,6 +89,7 @@ extern const unsigned char scsi_command_size[8];
#define DRIVER_INVALID 0x05 #define DRIVER_INVALID 0x05
#define DRIVER_TIMEOUT 0x06 #define DRIVER_TIMEOUT 0x06
#define DRIVER_HARD 0x07 #define DRIVER_HARD 0x07
#define DRIVER_SENSE 0x08
#define SUGGEST_RETRY 0x10 #define SUGGEST_RETRY 0x10
#define SUGGEST_ABORT 0x20 #define SUGGEST_ABORT 0x20
...@@ -97,8 +98,6 @@ extern const unsigned char scsi_command_size[8]; ...@@ -97,8 +98,6 @@ extern const unsigned char scsi_command_size[8];
#define SUGGEST_SENSE 0x80 #define SUGGEST_SENSE 0x80
#define SUGGEST_IS_OK 0xff #define SUGGEST_IS_OK 0xff
#define DRIVER_SENSE 0x08
#define DRIVER_MASK 0x0f #define DRIVER_MASK 0x0f
#define SUGGEST_MASK 0xf0 #define SUGGEST_MASK 0xf0
...@@ -448,6 +447,8 @@ extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int); ...@@ -448,6 +447,8 @@ extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
extern void print_command(unsigned char *); extern void print_command(unsigned char *);
extern void print_sense(const char *, Scsi_Cmnd *); extern void print_sense(const char *, Scsi_Cmnd *);
extern void print_driverbyte(int scsiresult);
extern void print_hostbyte(int scsiresult);
extern void scsi_mark_host_bus_reset(struct Scsi_Host *Host); extern void scsi_mark_host_bus_reset(struct Scsi_Host *Host);
......
...@@ -59,7 +59,6 @@ struct symbol_table scsi_symbol_table = { ...@@ -59,7 +59,6 @@ struct symbol_table scsi_symbol_table = {
X(kernel_scsi_ioctl), X(kernel_scsi_ioctl),
X(need_isa_buffer), X(need_isa_buffer),
X(request_queueable), X(request_queueable),
X(in_scan_scsis),
#if defined(CONFIG_PROC_FS) #if defined(CONFIG_PROC_FS)
X(proc_print_scsidevice), X(proc_print_scsidevice),
#endif #endif
......
...@@ -1304,12 +1304,14 @@ static void sd_finish() ...@@ -1304,12 +1304,14 @@ static void sd_finish()
if (!rscsi_disks[i].capacity && if (!rscsi_disks[i].capacity &&
rscsi_disks[i].device) rscsi_disks[i].device)
{ {
i = sd_init_onedisk(i);
if (MODULE_FLAG if (MODULE_FLAG
&& !rscsi_disks[i].has_part_table) { && !rscsi_disks[i].has_part_table) {
sd_sizes[i << 4] = rscsi_disks[i].capacity; sd_sizes[i << 4] = rscsi_disks[i].capacity;
/* revalidate does sd_init_onedisk via MAYBE_REINIT*/
revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0); revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0);
} }
else
i=sd_init_onedisk(i);
rscsi_disks[i].has_part_table = 1; rscsi_disks[i].has_part_table = 1;
} }
......
...@@ -297,7 +297,8 @@ int mem_mmap(struct inode * inode, struct file * file, ...@@ -297,7 +297,8 @@ int mem_mmap(struct inode * inode, struct file * file,
dtmp += PAGE_SIZE; dtmp += PAGE_SIZE;
} }
invalidate(); invalidate_range(vma->vm_mm, vma->vm_start, vma->vm_end);
invalidate_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end);
return 0; return 0;
} }
......
...@@ -91,13 +91,13 @@ struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_na ...@@ -91,13 +91,13 @@ struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_na
lptr->mnt_sem.count = 1; lptr->mnt_sem.count = 1;
if (dev_name && !getname(dev_name, &tmp)) { if (dev_name && !getname(dev_name, &tmp)) {
if ((lptr->mnt_devname = if ((lptr->mnt_devname =
(char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)NULL) (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
strcpy(lptr->mnt_devname, tmp); strcpy(lptr->mnt_devname, tmp);
putname(tmp); putname(tmp);
} }
if (dir_name && !getname(dir_name, &tmp)) { if (dir_name && !getname(dir_name, &tmp)) {
if ((lptr->mnt_dirname = if ((lptr->mnt_dirname =
(char *) kmalloc(strlen(tmp), GFP_KERNEL)) != (char *)NULL) (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
strcpy(lptr->mnt_dirname, tmp); strcpy(lptr->mnt_dirname, tmp);
putname(tmp); putname(tmp);
} }
......
...@@ -26,32 +26,81 @@ ...@@ -26,32 +26,81 @@
* - invalidate_page(mm, vmaddr) invalidates one page * - invalidate_page(mm, vmaddr) invalidates one page
* - invalidate_range(mm, start, end) invalidates a range of pages * - invalidate_range(mm, start, end) invalidates a range of pages
* *
* ..but the i386 has somewhat limited invalidation capabilities. * ..but the i386 has somewhat limited invalidation capabilities,
* and page-granular invalidates are available only on i486 and up.
*/ */
#define __invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
#ifdef __i486__
#define __invalidate_one(addr) \
__asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
#else
#define __invalidate_one(addr) invalidate()
#endif
#ifndef __SMP__ #ifndef __SMP__
#define invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax") #define invalidate() __invalidate()
#define invalidate_all() __invalidate()
static inline void invalidate_mm(struct mm_struct *mm)
{
if (mm == current->mm)
__invalidate();
}
static inline void invalidate_page(struct mm_struct *mm,
unsigned long addr)
{
if (mm == current->mm)
__invalidate_one(addr);
}
static inline void invalidate_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
if (mm == current->mm)
__invalidate();
}
#else #else
/*
* We aren't very clever about this yet - SMP could certainly
* avoid some global invalidates..
*/
#include <asm/smp.h> #include <asm/smp.h>
#define local_invalidate() \ #define local_invalidate() \
__asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax") __invalidate()
#define invalidate() \ #define invalidate() \
smp_invalidate(); smp_invalidate()
#endif
/*
* We aren't very clever about this yet. On a 486+ we could actually do
* page-granularity invalidates for better performance in some cases.
* And SMP could certainly avoid some global invalidates..
*/
#define invalidate_all() invalidate() #define invalidate_all() invalidate()
#define invalidate_mm(mm_struct) \
do { if ((mm_struct) == current->mm) invalidate(); } while (0) static inline void invalidate_mm(struct mm_struct *mm)
#define invalidate_page(mm_struct,addr) \ {
do { if ((mm_struct) == current->mm) invalidate(); } while (0) invalidate();
#define invalidate_range(mm_struct,start,end) \ }
do { if ((mm_struct) == current->mm) invalidate(); } while (0)
static inline void invalidate_page(struct mm_struct *mm,
unsigned long addr)
{
invalidate();
}
static inline void invalidate_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
invalidate();
}
#endif
/* Certain architectures need to do special things when pte's /* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following * within a page table are directly modified. Thus, the following
......
#ifndef _NET_ALIAS_H
#define _NET_ALIAS_H
#include <linux/types.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/in.h> /* for default IP behavior */
/*
* max. alias slot number allowed
*/
#define NET_ALIAS_MAX_SLOT 256
struct net_alias;
struct net_alias_info;
struct net_alias_type;
/*
* main alias structure
* note that *defines* dev & devname
*/
struct net_alias
{
struct device dev; /* alias device defn*/
char name[IFNAMSIZ]; /* device name defn */
unsigned hash; /* my hash value: for quick rehash */
unsigned slot; /* slot number */
void *data; /* private data */
struct device *main_dev; /* pointer to main device */
struct net_alias_type *nat; /* alias type bound */
struct net_alias *next; /* next alias (hashed linked list) */
};
/*
* alias structure pointed by main device
* it holds main device's alias hash table
*/
struct net_alias_info
{
int n_aliases; /* num aliases */
struct device *taildev; /* my last (alias) device */
struct net_alias *hash_tab[16]; /* hashed alias table */
};
/*
* net_alias_type class
* declares a generic (AF_ independent) structure that will
* manage generic to family-specific behavior.
*/
struct net_alias_type
{
int type; /* aliasing type: address family */
int n_attach; /* number of aliases attached */
char name[16]; /* af_name */
__u32 (*get_addr32) /* get __u32 addr 'representation'*/
(struct sockaddr*);
int (*addr_chk) /* address checking func: */
(struct device *, struct sockaddr *);
int (*alias_init_1) /* called after alias creation: */
(struct net_alias *alias, struct sockaddr *sa);
int (*alias_done_1) /* called before alias deletion */
(struct net_alias *alias);
int (*alias_print_1)
(char *buf, int len, struct net_alias *alias);
struct net_alias_type *next; /* link */
};
/*
* is dev an alias?
*/
static __inline__ int
net_alias_is(struct device *dev)
{
return (dev->my_alias != 0);
}
/*
* does dev have aliases?
*/
static __inline__ int
net_alias_has(struct device *dev)
{
return (dev->alias_info != 0);
}
extern void net_alias_init(void);
extern struct device * net_alias_dev_get(char *dev_name, int aliasing_ok, int *err, struct sockaddr *sa, void *data);
extern int net_alias_rehash(struct net_alias *alias, struct sockaddr *sa);
extern int net_alias_getinfo(char *buf, char **, off_t , int , int );
extern int net_alias_types_getinfo(char *buf, char **, off_t , int , int );
extern int register_net_alias_type(struct net_alias_type *nat, int type);
extern int unregister_net_alias_type(struct net_alias_type *nat);
extern struct device * net_alias_chk(struct device *dev, struct sockaddr *sa, int flags_1, int flags_0);
extern struct device * net_alias_chk32(struct device *dev, int family, __u32 addr32, int flags_1, int flags_0);
/*
* returns MY 'true' main device
* intended for alias devices
*/
static __inline__ struct device *net_alias_main_dev(struct device *dev)
{
return (net_alias_is(dev))? dev->my_alias->main_dev : dev;
}
/*
* returns NEXT 'true' device
* intended for true devices
*/
static __inline__ struct device *
net_alias_nextdev(struct device *dev)
{
return (dev->alias_info)? dev->alias_info->taildev->next : dev->next;
}
/*
* sets NEXT 'true' device
* intended for main devices (treat main device as block: dev+aliases).
*/
static __inline__ struct device *
net_alias_nextdev_set(struct device *dev, struct device *nextdev)
{
struct device *pdev = dev;
if (net_alias_has(dev))
{
pdev = dev->alias_info->taildev; /* point to last dev alias */
}
pdev->next = nextdev;
return nextdev;
}
/*
* addr_chk wrapper: check given generic address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk(struct device *dev, struct sockaddr *sa)
{
return net_alias_chk(dev, sa, IFF_UP, 0);
}
/*
* addr_chk32 wrapper: check given u32 address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk32(struct device *dev, int family, __u32 addr32)
{
return net_alias_chk32(dev, family, addr32, IFF_UP, 0);
}
#endif /* _NET_ALIAS_H */
...@@ -152,6 +152,8 @@ struct device ...@@ -152,6 +152,8 @@ struct device
unsigned long pkt_queue; /* Packets queued */ unsigned long pkt_queue; /* Packets queued */
struct device *slave; /* Slave device */ struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */
/* Pointer to the interface buffers. */ /* Pointer to the interface buffers. */
......
...@@ -89,6 +89,8 @@ enum net_directory_inos { ...@@ -89,6 +89,8 @@ enum net_directory_inos {
PROC_NET_SOCKSTAT, PROC_NET_SOCKSTAT,
PROC_NET_RTCACHE, PROC_NET_RTCACHE,
PROC_NET_AX25_BPQETHER, PROC_NET_AX25_BPQETHER,
PROC_NET_ALIAS_TYPES,
PROC_NET_ALIASES,
PROC_NET_LAST PROC_NET_LAST
}; };
......
...@@ -44,8 +44,8 @@ struct rlimit { ...@@ -44,8 +44,8 @@ struct rlimit {
long rlim_max; long rlim_max;
}; };
#define PRIO_MIN (-99) #define PRIO_MIN (-20)
#define PRIO_MAX 14 #define PRIO_MAX 20
#define PRIO_PROCESS 0 #define PRIO_PROCESS 0
#define PRIO_PGRP 1 #define PRIO_PGRP 1
......
...@@ -48,5 +48,7 @@ struct vt_consize { ...@@ -48,5 +48,7 @@ struct vt_consize {
ushort v_ccol; /* number of pixel columns per character */ ushort v_ccol; /* number of pixel columns per character */
}; };
#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ #define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
#define VT_LOCKSWITCH 0x560B /* disallow vt switching */
#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */
#endif /* _LINUX_VT_H */ #endif /* _LINUX_VT_H */
#ifndef _IP_ALIAS_H
#define _IP_ALIAS_H
/*
* IP alias specific prototypes
*/
#include <linux/net_alias.h>
extern int ip_alias_init(void);
extern int ip_alias_done(void);
#endif /* _IP_ALIAS_H */
...@@ -445,7 +445,7 @@ static int shm_map (struct vm_area_struct *shmd) ...@@ -445,7 +445,7 @@ static int shm_map (struct vm_area_struct *shmd)
return -ENOMEM; return -ENOMEM;
set_pte(page_table, __pte(shm_sgn)); set_pte(page_table, __pte(shm_sgn));
} }
invalidate(); invalidate_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
return 0; return 0;
} }
...@@ -680,7 +680,7 @@ int shm_swap (int prio, unsigned long limit) ...@@ -680,7 +680,7 @@ int shm_swap (int prio, unsigned long limit)
struct vm_area_struct *shmd; struct vm_area_struct *shmd;
unsigned long swap_nr; unsigned long swap_nr;
unsigned long id, idx; unsigned long id, idx;
int loop = 0, invalid = 0; int loop = 0;
int counter; int counter;
counter = shm_rss >> prio; counter = shm_rss >> prio;
...@@ -716,8 +716,6 @@ int shm_swap (int prio, unsigned long limit) ...@@ -716,8 +716,6 @@ int shm_swap (int prio, unsigned long limit)
if (--counter < 0) { /* failed */ if (--counter < 0) { /* failed */
failed: failed:
if (invalid)
invalidate();
swap_free (swap_nr); swap_free (swap_nr);
return 0; return 0;
} }
...@@ -766,7 +764,7 @@ int shm_swap (int prio, unsigned long limit) ...@@ -766,7 +764,7 @@ int shm_swap (int prio, unsigned long limit)
mem_map[MAP_NR(pte_page(pte))].count--; mem_map[MAP_NR(pte_page(pte))].count--;
if (shmd->vm_mm->rss > 0) if (shmd->vm_mm->rss > 0)
shmd->vm_mm->rss--; shmd->vm_mm->rss--;
invalid++; invalidate_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
/* continue looping through circular list */ /* continue looping through circular list */
} while (0); } while (0);
if ((shmd = shmd->vm_next_share) == shp->attaches) if ((shmd = shmd->vm_next_share) == shp->attaches)
...@@ -776,8 +774,6 @@ int shm_swap (int prio, unsigned long limit) ...@@ -776,8 +774,6 @@ int shm_swap (int prio, unsigned long limit)
if (mem_map[MAP_NR(pte_page(page))].count != 1) if (mem_map[MAP_NR(pte_page(page))].count != 1)
goto check_table; goto check_table;
shp->shm_pages[idx] = swap_nr; shp->shm_pages[idx] = swap_nr;
if (invalid)
invalidate();
write_swap_page (swap_nr, (char *) pte_page(page)); write_swap_page (swap_nr, (char *) pte_page(page));
free_page(pte_page(page)); free_page(pte_page(page));
swap_successes++; swap_successes++;
......
...@@ -76,6 +76,9 @@ extern void __remqu (void); ...@@ -76,6 +76,9 @@ extern void __remqu (void);
#include "../drivers/net/slhc.h" #include "../drivers/net/slhc.h"
#endif #endif
#endif #endif
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
#endif #endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
#include <linux/bios32.h> #include <linux/bios32.h>
...@@ -412,6 +415,10 @@ struct symbol_table symbol_table = { ...@@ -412,6 +415,10 @@ struct symbol_table symbol_table = {
/* Device callback registration */ /* Device callback registration */
X(register_netdevice_notifier), X(register_netdevice_notifier),
X(unregister_netdevice_notifier), X(unregister_netdevice_notifier),
#ifdef CONFIG_NET_ALIAS
X(register_net_alias_type),
X(unregister_net_alias_type),
#endif
#endif #endif
/* support for loadable net drivers */ /* support for loadable net drivers */
...@@ -452,11 +459,7 @@ struct symbol_table symbol_table = { ...@@ -452,11 +459,7 @@ struct symbol_table symbol_table = {
* So we add it here too. There is a duplicate set in scsi.c * So we add it here too. There is a duplicate set in scsi.c
* that is used when the entire scsi subsystem is a loadable * that is used when the entire scsi subsystem is a loadable
* module. * module.
*
* in_scan_scsis is a hack, and should go away once the new
* memory allocation code is in the NCR driver
*/ */
X(in_scan_scsis),
X(scsi_register_module), X(scsi_register_module),
X(scsi_unregister_module), X(scsi_unregister_module),
X(scsi_free), X(scsi_free),
......
...@@ -141,7 +141,8 @@ int filemap_swapout(struct vm_area_struct * vma, ...@@ -141,7 +141,8 @@ int filemap_swapout(struct vm_area_struct * vma,
unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page)); unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page));
set_pte(page_table, __pte(entry)); set_pte(page_table, __pte(entry));
invalidate(); /* Yuck, perhaps a slightly modified swapout parameter set? */
invalidate_page(vma->vm_mm, (offset + vma->vm_start - vma->vm_offset));
error = filemap_write_page(vma, offset, page); error = filemap_write_page(vma, offset, page);
if (pte_val(*page_table) == entry) if (pte_val(*page_table) == entry)
pte_clear(page_table); pte_clear(page_table);
...@@ -179,13 +180,14 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma, ...@@ -179,13 +180,14 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
if (!pte_dirty(pte)) if (!pte_dirty(pte))
return 0; return 0;
set_pte(ptep, pte_mkclean(pte)); set_pte(ptep, pte_mkclean(pte));
invalidate_page(vma->vm_mm, address);
page = pte_page(pte); page = pte_page(pte);
mem_map[MAP_NR(page)].count++; mem_map[MAP_NR(page)].count++;
} else { } else {
if (pte_none(pte)) if (pte_none(pte))
return 0; return 0;
pte_clear(ptep); pte_clear(ptep);
invalidate(); invalidate_page(vma->vm_mm, address);
if (!pte_present(pte)) { if (!pte_present(pte)) {
swap_free(pte_val(pte)); swap_free(pte_val(pte));
return 0; return 0;
...@@ -274,7 +276,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address, ...@@ -274,7 +276,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_range(vma->vm_mm, end - size, end);
return error; return error;
} }
......
...@@ -134,7 +134,7 @@ void clear_page_tables(struct task_struct * tsk) ...@@ -134,7 +134,7 @@ void clear_page_tables(struct task_struct * tsk)
} }
for (i = 0 ; i < USER_PTRS_PER_PGD ; i++) for (i = 0 ; i < USER_PTRS_PER_PGD ; i++)
free_one_pgd(page_dir + i); free_one_pgd(page_dir + i);
invalidate(); invalidate_mm(tsk->mm);
} }
/* /*
...@@ -153,12 +153,12 @@ void free_page_tables(struct task_struct * tsk) ...@@ -153,12 +153,12 @@ void free_page_tables(struct task_struct * tsk)
printk("%s trying to free kernel page-directory: not good\n", tsk->comm); printk("%s trying to free kernel page-directory: not good\n", tsk->comm);
return; return;
} }
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, swapper_pg_dir); SET_PAGE_DIR(tsk, swapper_pg_dir);
tsk->mm->pgd = swapper_pg_dir; /* or else... */ tsk->mm->pgd = swapper_pg_dir; /* or else... */
for (i = 0 ; i < PTRS_PER_PGD ; i++) for (i = 0 ; i < PTRS_PER_PGD ; i++)
free_one_pgd(page_dir + i); free_one_pgd(page_dir + i);
pgd_free(page_dir); pgd_free(page_dir);
invalidate();
} }
int new_page_tables(struct task_struct * tsk) int new_page_tables(struct task_struct * tsk)
...@@ -171,6 +171,7 @@ int new_page_tables(struct task_struct * tsk) ...@@ -171,6 +171,7 @@ int new_page_tables(struct task_struct * tsk)
page_dir = pgd_offset(&init_mm, 0); page_dir = pgd_offset(&init_mm, 0);
for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++) for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
new_pg[i] = page_dir[i]; new_pg[i] = page_dir[i];
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, new_pg); SET_PAGE_DIR(tsk, new_pg);
tsk->mm->pgd = new_pg; tsk->mm->pgd = new_pg;
return 0; return 0;
...@@ -285,7 +286,9 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, ...@@ -285,7 +286,9 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
break; break;
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
} }
invalidate(); /* Note that the src ptes get c-o-w treatment, so they change too. */
invalidate_range(src, vma->vm_start, vma->vm_end);
invalidate_range(dst, vma->vm_start, vma->vm_end);
return error; return error;
} }
...@@ -369,7 +372,7 @@ int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long si ...@@ -369,7 +372,7 @@ int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long si
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_range(mm, end - size, end);
return 0; return 0;
} }
...@@ -429,7 +432,7 @@ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot) ...@@ -429,7 +432,7 @@ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot)
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_range(current->mm, end - size, end);
return error; return error;
} }
...@@ -499,7 +502,7 @@ int remap_page_range(unsigned long from, unsigned long offset, unsigned long siz ...@@ -499,7 +502,7 @@ int remap_page_range(unsigned long from, unsigned long offset, unsigned long siz
from = (from + PGDIR_SIZE) & PGDIR_MASK; from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_range(current->mm, from - size, from);
return error; return error;
} }
...@@ -514,7 +517,7 @@ static void put_page(pte_t * page_table, pte_t pte) ...@@ -514,7 +517,7 @@ static void put_page(pte_t * page_table, pte_t pte)
return; return;
} }
/* no need for invalidate */ /* no need for invalidate */
*page_table = pte; set_pte(page_table, pte);
} }
/* /*
...@@ -547,7 +550,7 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig ...@@ -547,7 +550,7 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig
if (!pte_none(*pte)) { if (!pte_none(*pte)) {
printk("put_dirty_page: page already exists\n"); printk("put_dirty_page: page already exists\n");
pte_clear(pte); pte_clear(pte);
invalidate(); invalidate_page(tsk->mm, address);
} }
set_pte(pte, pte_mkwrite(pte_mkdirty(mk_pte(page, PAGE_COPY)))); set_pte(pte, pte_mkwrite(pte_mkdirty(mk_pte(page, PAGE_COPY))));
/* no need for invalidate */ /* no need for invalidate */
...@@ -610,17 +613,17 @@ void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, ...@@ -610,17 +613,17 @@ void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma,
copy_page(old_page,new_page); copy_page(old_page,new_page);
set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)))); set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
free_page(old_page); free_page(old_page);
invalidate(); invalidate_page(vma->vm_mm, address);
return; return;
} }
set_pte(page_table, BAD_PAGE); set_pte(page_table, BAD_PAGE);
free_page(old_page); free_page(old_page);
oom(tsk); oom(tsk);
invalidate(); invalidate_page(vma->vm_mm, address);
return; return;
} }
set_pte(page_table, pte_mkdirty(pte_mkwrite(pte))); set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
invalidate(); invalidate_page(vma->vm_mm, address);
if (new_page) if (new_page)
free_page(new_page); free_page(new_page);
return; return;
...@@ -842,7 +845,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -842,7 +845,7 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
return 1; return 1;
/* ok, need to mark it read-only, so invalidate any possible old TB entry */ /* ok, need to mark it read-only, so invalidate any possible old TB entry */
set_pte(from_table, pte_wrprotect(from)); set_pte(from_table, pte_wrprotect(from));
invalidate(); invalidate_page(from_area->vm_mm, from_address);
return 1; return 1;
} }
......
...@@ -72,6 +72,7 @@ static inline void change_pmd_range(pgd_t * pgd, unsigned long address, ...@@ -72,6 +72,7 @@ static inline void change_pmd_range(pgd_t * pgd, unsigned long address,
static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot) static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
{ {
pgd_t *dir; pgd_t *dir;
unsigned long beg = start;
dir = pgd_offset(current->mm, start); dir = pgd_offset(current->mm, start);
while (start < end) { while (start < end) {
...@@ -79,7 +80,7 @@ static void change_protection(unsigned long start, unsigned long end, pgprot_t n ...@@ -79,7 +80,7 @@ static void change_protection(unsigned long start, unsigned long end, pgprot_t n
start = (start + PGDIR_SIZE) & PGDIR_MASK; start = (start + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_range(current->mm, beg, end);
return; return;
} }
......
...@@ -457,7 +457,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc ...@@ -457,7 +457,7 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc
return 0; return 0;
vma->vm_mm->rss--; vma->vm_mm->rss--;
set_pte(page_table, __pte(entry)); set_pte(page_table, __pte(entry));
invalidate(); invalidate_page(vma->vm_mm, address);
tsk->nswap++; tsk->nswap++;
write_swap_page(entry, (char *) page); write_swap_page(entry, (char *) page);
} }
...@@ -472,13 +472,13 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc ...@@ -472,13 +472,13 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc
} }
vma->vm_mm->rss--; vma->vm_mm->rss--;
set_pte(page_table, __pte(entry)); set_pte(page_table, __pte(entry));
invalidate(); invalidate_page(vma->vm_mm, address);
free_page(page); free_page(page);
return 1; return 1;
} }
vma->vm_mm->rss--; vma->vm_mm->rss--;
pte_clear(page_table); pte_clear(page_table);
invalidate(); invalidate_page(vma->vm_mm, address);
entry = mem_map[MAP_NR(page)].count; entry = mem_map[MAP_NR(page)].count;
free_page(page); free_page(page);
return entry; return entry;
......
...@@ -105,7 +105,7 @@ static void free_area_pages(unsigned long address, unsigned long size) ...@@ -105,7 +105,7 @@ static void free_area_pages(unsigned long address, unsigned long size)
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_all();
} }
static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size) static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size)
...@@ -166,7 +166,7 @@ static int alloc_area_pages(unsigned long address, unsigned long size) ...@@ -166,7 +166,7 @@ static int alloc_area_pages(unsigned long address, unsigned long size)
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_all();
return 0; return 0;
} }
...@@ -227,7 +227,7 @@ static int remap_area_pages(unsigned long address, unsigned long offset, unsigne ...@@ -227,7 +227,7 @@ static int remap_area_pages(unsigned long address, unsigned long offset, unsigne
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} }
invalidate(); invalidate_all();
return 0; return 0;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
mainmenu_option next_comment mainmenu_option next_comment
comment 'Networking options' comment 'Networking options'
bool 'Network firewalls' CONFIG_FIREWALL bool 'Network firewalls' CONFIG_FIREWALL
bool 'Network aliasing' CONFIG_NET_ALIAS
bool 'TCP/IP networking' CONFIG_INET bool 'TCP/IP networking' CONFIG_INET
if [ "$CONFIG_INET" = "y" ]; then if [ "$CONFIG_INET" = "y" ]; then
source net/ipv4/Config.in source net/ipv4/Config.in
......
...@@ -19,6 +19,10 @@ ifdef CONFIG_FIREWALL ...@@ -19,6 +19,10 @@ ifdef CONFIG_FIREWALL
O_OBJS += firewall.o O_OBJS += firewall.o
endif endif
ifdef CONFIG_NET_ALIAS
O_OBJS += net_alias.o
endif
endif endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
...@@ -70,6 +70,9 @@ ...@@ -70,6 +70,9 @@
#include <net/arp.h> #include <net/arp.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
/* /*
* The list of packet types we will receive (as opposed to discard) * The list of packet types we will receive (as opposed to discard)
...@@ -356,6 +359,19 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri) ...@@ -356,6 +359,19 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
return; return;
} }
/*
*
* If dev is an alias, switch to its main device.
* "arp" resolution has been made with alias device, so
* arp entries refer to alias, not main.
*
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev))
skb->dev = dev = net_alias_main_dev(dev);
#endif
save_flags(flags); save_flags(flags);
cli(); cli();
if (!where) /* Always keep order. It helps other hosts if (!where) /* Always keep order. It helps other hosts
...@@ -561,7 +577,7 @@ void dev_transmit(void) ...@@ -561,7 +577,7 @@ void dev_transmit(void)
{ {
struct device *dev; struct device *dev;
for (dev = dev_base; dev != NULL; dev = dev->next) for (dev = dev_base; dev != NULL; dev = dev->next)
{ {
if (dev->flags != 0 && !dev->tbusy) { if (dev->flags != 0 && !dev->tbusy) {
/* /*
...@@ -753,6 +769,13 @@ void dev_tint(struct device *dev) ...@@ -753,6 +769,13 @@ void dev_tint(struct device *dev)
struct sk_buff *skb; struct sk_buff *skb;
unsigned long flags; unsigned long flags;
/*
* aliases do not trasmit (by now :)
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev)) return;
#endif
save_flags(flags); save_flags(flags);
/* /*
* Work the queues in priority order * Work the queues in priority order
...@@ -984,9 +1007,20 @@ static int dev_ifsioc(void *arg, unsigned int getset) ...@@ -984,9 +1007,20 @@ static int dev_ifsioc(void *arg, unsigned int getset)
* See which interface the caller is talking about. * See which interface the caller is talking about.
*/ */
/*
*
* net_alias_dev_get(): dev_get() with added alias naming magic.
* only allow alias creation/deletion if (getset==SIOCSIFADDR)
*
*/
#ifdef CONFIG_NET_ALIAS
if ((dev = net_alias_dev_get(ifr.ifr_name, getset == SIOCSIFADDR, &err, NULL, NULL)) == NULL)
return(err);
#else
if ((dev = dev_get(ifr.ifr_name)) == NULL) if ((dev = dev_get(ifr.ifr_name)) == NULL)
return(-ENODEV); return(-ENODEV);
#endif
switch(getset) switch(getset)
{ {
case SIOCGIFFLAGS: /* Get interface flags */ case SIOCGIFFLAGS: /* Get interface flags */
...@@ -1079,6 +1113,16 @@ static int dev_ifsioc(void *arg, unsigned int getset) ...@@ -1079,6 +1113,16 @@ static int dev_ifsioc(void *arg, unsigned int getset)
} }
else else
{ {
/*
* if dev is an alias, must rehash to update
* address change
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev))
net_alias_rehash(dev->my_alias,&ifr.ifr_addr);
#endif
dev->pa_addr = (*(struct sockaddr_in *) dev->pa_addr = (*(struct sockaddr_in *)
&ifr.ifr_addr).sin_addr.s_addr; &ifr.ifr_addr).sin_addr.s_addr;
dev->family = ifr.ifr_addr.sa_family; dev->family = ifr.ifr_addr.sa_family;
...@@ -1382,6 +1426,18 @@ int net_dev_init(void) ...@@ -1382,6 +1426,18 @@ int net_dev_init(void)
dev_get_info dev_get_info
}); });
/*
* Initialise net_alias engine
*
* - register net_alias device notifier
* - register proc entries: /proc/net/alias_types
* /proc/net/aliases
*/
#ifdef CONFIG_NET_ALIAS
net_alias_init();
#endif
bh_base[NET_BH].routine = net_bh; bh_base[NET_BH].routine = net_bh;
enable_bh(NET_BH); enable_bh(NET_BH);
return 0; return 0;
......
This diff is collapsed.
...@@ -17,6 +17,9 @@ if [ "$CONFIG_IP_FORWARD" = "y" ]; then ...@@ -17,6 +17,9 @@ if [ "$CONFIG_IP_FORWARD" = "y" ]; then
bool 'IP: multicast routing(in progress)' CONFIG_IP_MROUTE bool 'IP: multicast routing(in progress)' CONFIG_IP_MROUTE
fi fi
fi fi
if [ "$CONFIG_NET_ALIAS" = "y" ]; then
tristate 'IP: aliasing support' CONFIG_IP_ALIAS
fi
comment '(it is safe to leave these untouched)' comment '(it is safe to leave these untouched)'
bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
tristate 'IP: Reverse ARP' CONFIG_INET_RARP tristate 'IP: Reverse ARP' CONFIG_INET_RARP
......
...@@ -36,6 +36,14 @@ else ...@@ -36,6 +36,14 @@ else
endif endif
endif endif
ifeq ($(CONFIG_IP_ALIAS),y)
IPV4_OBJS += ip_alias.o
else
ifeq ($(CONFIG_IP_ALIAS),m)
M_OBJS += ip_alias.o
endif
endif
ifdef CONFIG_INET ifdef CONFIG_INET
O_OBJS := $(IPV4_OBJS) O_OBJS := $(IPV4_OBJS)
endif endif
......
...@@ -88,6 +88,9 @@ ...@@ -88,6 +88,9 @@
#include <net/raw.h> #include <net/raw.h>
#include <net/icmp.h> #include <net/icmp.h>
#include <linux/ip_fw.h> #include <linux/ip_fw.h>
#ifdef CONFIG_IP_ALIAS
#include <net/ip_alias.h>
#endif
#define min(a,b) ((a)<(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b))
...@@ -1530,6 +1533,13 @@ void inet_proto_init(struct net_proto *pro) ...@@ -1530,6 +1533,13 @@ void inet_proto_init(struct net_proto *pro)
ip_mr_init(); ip_mr_init();
#endif #endif
/*
* Initialise AF_INET alias type (register net_alias_type)
*/
#if defined(CONFIG_IP_ALIAS)
ip_alias_init();
#endif
/* /*
* Create all the /proc entries. * Create all the /proc entries.
*/ */
......
...@@ -96,6 +96,9 @@ ...@@ -96,6 +96,9 @@
#include <net/netrom.h> #include <net/netrom.h>
#endif #endif
#endif #endif
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
#include <asm/system.h> #include <asm/system.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -891,6 +894,19 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -891,6 +894,19 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* cache. * cache.
*/ */
/*
* try to switch to alias device whose address is tip, if any
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_has(dev))
{
struct device *adev;
adev = net_alias_chk32(dev,AF_INET,tip,IFF_UP,IFF_NOARP);
if (adev != NULL) dev = adev;
}
#endif
if (arp->ar_op == htons(ARPOP_REQUEST)) if (arp->ar_op == htons(ARPOP_REQUEST))
{ {
/* /*
...@@ -1019,7 +1035,15 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1019,7 +1035,15 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
entry->timer.data = (unsigned long)entry; entry->timer.data = (unsigned long)entry;
memcpy(entry->ha, sha, dev->addr_len); memcpy(entry->ha, sha, dev->addr_len);
entry->last_updated = entry->last_used = jiffies; entry->last_updated = entry->last_used = jiffies;
/*
* make entry point to 'correct' device
*/
#ifdef CONFIG_NET_ALIAS
entry->dev = dev;
#else
entry->dev = skb->dev; entry->dev = skb->dev;
#endif
skb_queue_head_init(&entry->skb); skb_queue_head_init(&entry->skb);
if (arp_lock == 1) if (arp_lock == 1)
{ {
......
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/inet.h>
#ifdef ALIAS_USER_LAND_DEBUG
#include "net_alias.h"
#include "ip_alias.h"
#include "user_stubs.h"
#endif
#include <linux/net_alias.h>
#include <net/ip_alias.h>
/*
* AF_INET alias init
*/
static int
ip_alias_init_1(struct net_alias *alias, struct sockaddr *sa)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_init(%s) called.\n", alias->name);
#endif
MOD_INC_USE_COUNT;
return 0;
}
/*
* AF_INET alias done
*/
static int
ip_alias_done_1(struct net_alias *alias)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_done(%s) called.\n", alias->name);
#endif
MOD_DEC_USE_COUNT;
return 0;
}
/*
* print address info
*/
int
ip_alias_print_1(char *buf, int len, struct net_alias *alias)
{
char *p;
p = (char *) &alias->dev.pa_addr;
return sprintf(buf, "%d.%d.%d.%d",
(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
}
/*
* net_alias AF_INET type defn.
*/
struct net_alias_type ip_alias_type =
{
AF_INET, /* type */
0, /* n_attach */
"ip", /* name */
NULL, /* get_addr32() */
NULL, /* addr_chk() */
ip_alias_init_1, /* alias_init_1() */
ip_alias_done_1, /* alias_done_1() */
ip_alias_print_1, /* alias_print_1() */
NULL /* next */
};
/*
* ip_alias module initialization
*/
int ip_alias_init(void)
{
return register_net_alias_type(&ip_alias_type, AF_INET);
}
/*
* ip_alias module done
*/
int ip_alias_done(void)
{
return unregister_net_alias_type(&ip_alias_type);
}
#ifdef MODULE
int init_module(void)
{
if (ip_alias_init() != 0)
return -EIO;
return 0;
}
void cleanup_module(void)
{
if (ip_alias_done() != 0)
printk("ip_alias: can't remove module");
}
#endif /* MODULE */
...@@ -151,6 +151,9 @@ ...@@ -151,6 +151,9 @@
#include <linux/firewall.h> #include <linux/firewall.h>
#include <linux/mroute.h> #include <linux/mroute.h>
#include <net/netlink.h> #include <net/netlink.h>
#ifdef CONFIG_NET_ALIAS
#include <linux/net_alias.h>
#endif
extern int last_retran; extern int last_retran;
extern void sort_send(struct sock *sk); extern void sort_send(struct sock *sk);
...@@ -313,7 +316,18 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -313,7 +316,18 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* function entry. * function entry.
*/ */
/*
* also check device aliases address : will avoid
* a full lookup over device chain
*/
#ifdef CONFIG_NET_ALIAS
if ( iph->daddr == skb->dev->pa_addr ||
( net_alias_has(skb->dev) && net_alias_addr_chk32(skb->dev,AF_INET, iph->daddr )) ||
(brd = ip_chk_addr(iph->daddr)) != 0)
#else
if ( iph->daddr == skb->dev->pa_addr || (brd = ip_chk_addr(iph->daddr)) != 0) if ( iph->daddr == skb->dev->pa_addr || (brd = ip_chk_addr(iph->daddr)) != 0)
#endif
{ {
if (opt && opt->srr) if (opt && opt->srr)
{ {
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
# 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for # 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for
# use with a config.in modified for make menuconfig. # use with a config.in modified for make menuconfig.
# #
# 301195 (boldt@math.ucsb.edu) - added help text support
#
# #
# Make sure we're really running bash. # Make sure we're really running bash.
...@@ -44,6 +46,37 @@ function mainmenu_name () { ...@@ -44,6 +46,37 @@ function mainmenu_name () {
: :
} }
#
# help prints the corresponding help text from Configure.help to stdout
#
# help variable
#
function help () {
if [ -f Documentation/Configure.help ]
then
#first escape regexp special characters in the argument:
var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g')
#now pick out the right help text:
text=$(sed -n "/^$var[ ]*\$/,\${
/^$var[ ]*\$/b
/^#.*/b;/^[ ]*\$/q
p
}" Documentation/Configure.help)
if [ -z "$text" ]
then
echo; echo " Sorry, no help available for this option yet.";echo
else
(echo; echo "$text"; echo) | more
fi
else
echo;
echo " Can't access the file Documentation/Configure.help which"
echo " should contain the help texts."
echo
fi
}
# #
# readln reads a line into $ans. # readln reads a line into $ans.
# #
...@@ -78,17 +111,17 @@ function comment () { ...@@ -78,17 +111,17 @@ function comment () {
# #
function define_bool () { function define_bool () {
case "$2" in case "$2" in
"y" | "Y") "y")
echo "$1=y" >>$CONFIG echo "$1=y" >>$CONFIG
echo "#define $1 1" >>$CONFIG_H echo "#define $1 1" >>$CONFIG_H
;; ;;
"m" | "M") "m")
echo "$1=m" >>$CONFIG echo "$1=m" >>$CONFIG
echo "#undef $1" >>$CONFIG_H echo "#undef $1" >>$CONFIG_H
;; ;;
"n" | "N") "n")
echo "# $1 is not set" >>$CONFIG echo "# $1 is not set" >>$CONFIG
echo "#undef $1" >>$CONFIG_H echo "#undef $1" >>$CONFIG_H
;; ;;
...@@ -102,18 +135,24 @@ function define_bool () { ...@@ -102,18 +135,24 @@ function define_bool () {
# bool question define # bool question define
# #
function bool () { function bool () {
ans=""
def=$(eval echo "\${$2:-'n'}") def=$(eval echo "\${$2:-'n'}")
case "$def" in case "$def" in
"y") defprompt="Y/n" "y") defprompt="Y/n/?"
;; ;;
"n") defprompt="N/y" "n") defprompt="N/y/?"
;; ;;
esac esac
while [ "$ans" != "y" -a "$ans" != "n" ]; do while :; do
readln "$1 ($2) [$defprompt] " "$def" readln "$1 ($2) [$defprompt] " "$def"
done case "$ans" in
define_bool "$2" "$ans" [yY] | [yY]es ) define_bool "$2" "y"
break;;
[nN] | [nN]o ) define_bool "$2" "n"
break;;
* ) help "$2"
;;
esac
done
} }
# #
...@@ -122,20 +161,28 @@ function bool () { ...@@ -122,20 +161,28 @@ function bool () {
# tristate question define # tristate question define
# #
function tristate () { function tristate () {
ans=""
def=$(eval echo "\${$2:-'n'}") def=$(eval echo "\${$2:-'n'}")
case "$def" in case "$def" in
"y") defprompt="Y/m/n" "y") defprompt="Y/m/n/?"
;; ;;
"m") defprompt="M/n/y" "m") defprompt="M/n/y/?"
;; ;;
"n") defprompt="N/y/m" "n") defprompt="N/y/m/?"
;; ;;
esac esac
while [ "$ans" != "y" -a "$ans" != "n" -a "$ans" != "m" ]; do while :; do
readln "$1 ($2) [$defprompt] " "$def" readln "$1 ($2) [$defprompt] " "$def"
done case "$ans" in
define_bool "$2" "$ans" [yY] | [yY]es ) define_bool "$2" "y"
break ;;
[nN] | [nN]o ) define_bool "$2" "n"
break ;;
[mM] ) define_bool "$2" "m"
break ;;
* ) help "$2"
;;
esac
done
} }
# #
...@@ -153,18 +200,32 @@ function dep_tristate () { ...@@ -153,18 +200,32 @@ function dep_tristate () {
if [ "$3" != "m" ]; then if [ "$3" != "m" ]; then
tristate "$1" "$2" tristate "$1" "$2"
else else
ans=""
case "$def" in case "$def" in
"y" | "m") defprompt="M/n" "y" | "m") defprompt="M/n/?"
def="m" def="m"
;; ;;
"n") defprompt="N/m" "n") defprompt="N/m/?"
;; ;;
esac esac
while [ "$ans" != "n" -a "$ans" != "m" ]; do while :; do
readln "$1 ($2) [$defprompt] " "$def" readln "$1 ($2) [$defprompt] " "$def"
done case "$ans" in
define_bool "$2" "$ans" [nN] | [nN]o ) define_bool "$2" "n"
break ;;
[mM] ) define_bool "$2" "m"
break ;;
[yY] | [yY]es ) echo
echo " This answer is not allowed, because it is not consistent with"
echo " your other choices."
echo " This driver depends on another one which you chose to compile"
echo " as a module. This means that you can either compile this one"
echo " as a module as well (with M) or leave it out altogether (N)."
echo
;;
* ) help "$2"
;;
esac
done
fi fi
} }
...@@ -185,13 +246,17 @@ function define_int () { ...@@ -185,13 +246,17 @@ function define_int () {
# int question define default # int question define default
# #
function int () { function int () {
# Slimier hack to get bash to rescan a line.
ans="x"
def=$(eval echo "\${$2:-$3}") def=$(eval echo "\${$2:-$3}")
while [ $[$ans+0] != "$ans" ]; do while :; do
readln "$1 ($2) [$def] " "$def" readln "$1 ($2) [$def] " "$def"
done case "$ans" in
define_int "$2" "$ans" [1-9] | [1-9][0-9] | [1-9][0-9][0-9] | [1-9][0-9][0-9][0-9] )
define_int "$2" "$ans"
break;;
* ) help "$2"
;;
esac
done
} }
# #
...@@ -216,6 +281,7 @@ function choice () { ...@@ -216,6 +281,7 @@ function choice () {
# determine default answer: # determine default answer:
names="" names=""
set -- $choices set -- $choices
firstvar=$2
while [ -n "$2" ]; do while [ -n "$2" ]; do
if [ -n "$names" ]; then if [ -n "$names" ]; then
names="$names, $1" names="$names, $1"
...@@ -230,29 +296,34 @@ function choice () { ...@@ -230,29 +296,34 @@ function choice () {
val="" val=""
while [ -z "$val" ]; do while [ -z "$val" ]; do
ambg=n
readln "$question ($names) [$def] " "$def" readln "$question ($names) [$def] " "$def"
ans=$(echo $ans | tr a-z A-Z) ans=$(echo $ans | tr a-z A-Z)
set -- $choices set -- $choices
val=""
while [ -n "$1" ]; do while [ -n "$1" ]; do
name=$(echo $1 | tr a-z A-Z) name=$(echo $1 | tr a-z A-Z)
case "$name" in case "$name" in
${ans}*) "$ans"* )
if [ "$name" = "$ans" ]; then if [ "$name" = "$ans" ]; then
val="$2" val="$2"
break # stop on exact match break # stop on exact match
fi fi
if [ -n "$val" ]; then if [ -n "$val" ]; then
echo \ echo;echo \
" Sorry, \"$ans\" is ambiguous; please enter a longer string." " Sorry, \"$ans\" is ambiguous; please enter a longer string."
echo
val="" val=""
ambg=y
break break
else else
val="$2" val="$2"
fi;; fi;;
esac esac
shift; shift shift; shift
done done
if [ "$val" = "" -a "$ambg" = "n" ]; then
help "$firstvar"
fi
done done
set -- $choices set -- $choices
while [ -n "$2" ]; do while [ -n "$2" ]; do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment