Commit aea252fa authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.2

parent b960c886
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 1 SUBLEVEL = 2
ARCH = i386 ARCH = i386
...@@ -84,7 +84,7 @@ endif ...@@ -84,7 +84,7 @@ endif
# Include the make variables (CC, etc...) # Include the make variables (CC, etc...)
# #
ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o ipc/ipc.o ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o net/network.a
FILESYSTEMS =fs/filesystems.a FILESYSTEMS =fs/filesystems.a
DRIVERS =drivers/block/block.a \ DRIVERS =drivers/block/block.a \
drivers/char/char.a \ drivers/char/char.a \
......
...@@ -23,7 +23,10 @@ fi ...@@ -23,7 +23,10 @@ fi
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'Networking support' CONFIG_NET y bool 'Networking support' CONFIG_NET y
bool 'PCI alpha motherboard' CONFIG_PCI n bool 'PCI alpha motherboard' CONFIG_PCI n
bool 'System V IPC' CONFIG_SYSVIPC n if [ "$CONFIG_PCI" = "y" ]; then
bool ' PCI bridge optimisation (experimental)' CONFIG_PCI_OPTIMIZE n
fi
bool 'System V IPC' CONFIG_SYSVIPC y
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
comment 'Loadable module support' comment 'Loadable module support'
...@@ -33,19 +36,28 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -33,19 +36,28 @@ if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options' comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET y bool 'TCP/IP networking' CONFIG_INET y
if [ "$CONFIG_INET" = "y" ]; then if [ "$CONFIG_INET" = "y" ]; then
bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD n
bool 'IP multicasting' CONFIG_IP_MULTICAST n bool 'IP: multicasting' CONFIG_IP_MULTICAST n
bool 'IP firewalling' CONFIG_IP_FIREWALL n bool 'IP: firewalling' CONFIG_IP_FIREWALL n
bool 'IP accounting' CONFIG_IP_ACCT n bool 'IP: accounting' CONFIG_IP_ACCT n
bool 'IP: tunneling' CONFIG_NET_IPIP n
if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE y
bool 'IP: masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
fi
comment '(it is safe to leave these untouched)' comment '(it is safe to leave these untouched)'
bool 'PC/TCP compatibility mode' CONFIG_INET_PCTCP n bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP n
bool 'Reverse ARP' CONFIG_INET_RARP n bool 'IP: Reverse ARP' CONFIG_INET_RARP n
bool 'Assume subnets are local' CONFIG_INET_SNARL y bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
fi fi
bool 'The IPX protocol' CONFIG_IPX n bool 'The IPX protocol' CONFIG_IPX n
#bool 'Appletalk DDP' CONFIG_ATALK n bool 'Appletalk DDP' CONFIG_ATALK n
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
if [ "$CONFIG_AX25" = "y" ]; then
bool 'Amateur Radio NET/ROM' CONFIG_NETROM n
fi
fi fi
comment 'SCSI support' comment 'SCSI support'
...@@ -65,6 +77,10 @@ bool 'SCSI tape support' CONFIG_CHR_DEV_ST n ...@@ -65,6 +77,10 @@ bool 'SCSI tape support' CONFIG_CHR_DEV_ST n
bool 'SCSI CDROM support' CONFIG_BLK_DEV_SR y bool 'SCSI CDROM support' CONFIG_BLK_DEV_SR y
bool 'SCSI generic support' CONFIG_CHR_DEV_SG n bool 'SCSI generic support' CONFIG_CHR_DEV_SG n
comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
comment 'SCSI low-level drivers' comment 'SCSI low-level drivers'
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
...@@ -106,10 +122,16 @@ bool 'SLIP (serial line) support' CONFIG_SLIP n ...@@ -106,10 +122,16 @@ bool 'SLIP (serial line) support' CONFIG_SLIP n
if [ "$CONFIG_SLIP" = "y" ]; then if [ "$CONFIG_SLIP" = "y" ]; then
bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
bool ' 16 channels instead of 4' SL_SLIP_LOTS n bool ' 16 channels instead of 4' SL_SLIP_LOTS n
# bool ' SLIP debugging on' SL_DUMP y
fi fi
bool 'PPP (point-to-point) support' CONFIG_PPP n bool 'PPP (point-to-point) support' CONFIG_PPP n
if [ "$CONFIG_PPP" = "y" ]; then
bool ' 16 channels instead of 4' CONFIG_PPP_LOTS n
fi
if [ "$CONFIG_AX25" = "y" ]; then
bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC y
fi
bool 'PLIP (parallel port) support' CONFIG_PLIP n bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'EQL (serial line load balancing) support' CONFIG_EQUALIZER n
bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
...@@ -129,11 +151,11 @@ if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then ...@@ -129,11 +151,11 @@ if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
fi fi
bool 'Other ISA cards' CONFIG_NET_ISA n bool 'Other ISA cards' CONFIG_NET_ISA n
if [ "$CONFIG_NET_ISA" = "y" ]; then if [ "$CONFIG_NET_ISA" = "y" ]; then
bool 'Arcnet support' CONFIG_ARCNET n
bool 'Cabletron E21xx support' CONFIG_E2100 n bool 'Cabletron E21xx support' CONFIG_E2100 n
bool 'DEPCA support' CONFIG_DEPCA y bool 'DEPCA support' CONFIG_DEPCA y
bool 'EtherWorks 3 support' CONFIG_EWRK3 n bool 'EtherWorks 3 support' CONFIG_EWRK3 n
if [ "$CONFIG_NET_ALPHA" = "y" ]; then if [ "$CONFIG_NET_ALPHA" = "y" ]; then
bool 'Arcnet support' CONFIG_ARCNET n
bool 'AT1700 support' CONFIG_AT1700 n bool 'AT1700 support' CONFIG_AT1700 n
# bool 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n # bool 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n
bool 'EtherExpress support' CONFIG_EEXPRESS n bool 'EtherExpress support' CONFIG_EEXPRESS n
...@@ -144,6 +166,9 @@ if [ "$CONFIG_NET_ISA" = "y" ]; then ...@@ -144,6 +166,9 @@ if [ "$CONFIG_NET_ISA" = "y" ]; then
bool 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n bool 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
bool 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n bool 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
bool 'NE2000/NE1000 support' CONFIG_NE2000 n bool 'NE2000/NE1000 support' CONFIG_NE2000 n
if [ "$CONFIG_AX25" = "y" ]; then
bool 'Ottawa PI and PI/2 support' CONFIG_PI y
fi
bool 'SK_G16 support' CONFIG_SK_G16 n bool 'SK_G16 support' CONFIG_SK_G16 n
fi fi
bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
...@@ -167,6 +192,10 @@ if [ "$CONFIG_NET_POCKET" = "y" ]; then ...@@ -167,6 +192,10 @@ if [ "$CONFIG_NET_POCKET" = "y" ]; then
# bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n # bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n
# bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n # bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n
fi fi
bool 'Token Ring driver support' CONFIG_TR n
if [ "$CONFIG_TR" = "y" ]; then
bool 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR y
fi
fi fi
fi fi
...@@ -195,7 +224,8 @@ bool 'Second extended fs support' CONFIG_EXT2_FS y ...@@ -195,7 +224,8 @@ bool 'Second extended fs support' CONFIG_EXT2_FS y
bool 'xiafs filesystem support' CONFIG_XIA_FS n bool 'xiafs filesystem support' CONFIG_XIA_FS n
bool 'msdos fs support' CONFIG_MSDOS_FS y bool 'msdos fs support' CONFIG_MSDOS_FS y
if [ "$CONFIG_MSDOS_FS" = "y" ]; then if [ "$CONFIG_MSDOS_FS" = "y" ]; then
bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n #bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
comment 'Umsdos is not supported in 1.3.0: wait for 1.3.1'
fi fi
bool '/proc filesystem support' CONFIG_PROC_FS y bool '/proc filesystem support' CONFIG_PROC_FS y
if [ "$CONFIG_INET" = "y" ]; then if [ "$CONFIG_INET" = "y" ]; then
......
#define DEBUG
/* /*
* bios32.c - PCI BIOS functions for Alpha systems not using BIOS * bios32.c - PCI BIOS functions for Alpha systems not using BIOS
* emulation code. * emulation code.
...@@ -108,7 +107,8 @@ static void layout_dev(struct pci_dev *dev) ...@@ -108,7 +107,8 @@ static void layout_dev(struct pci_dev *dev)
0xffffffff); 0xffffffff);
pcibios_read_config_dword(bus->number, dev->devfn, reg, &base); pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
if (!base) { if (!base) {
break; /* done with this device */ /* this base-address register is unused */
continue;
} }
/* /*
* We've read the base address register back after * We've read the base address register back after
...@@ -449,6 +449,48 @@ static void noname_fixup(void) ...@@ -449,6 +449,48 @@ static void noname_fixup(void)
} }
} }
#endif /* !PCI_MODIFY */ #endif /* !PCI_MODIFY */
/*
* The SRM console *disables* the IDE interface, this code *
* enables it. With the miniloader, this may not be necessary
* but it shouldn't hurt either.
*
* This code bangs on a control register of the 87312 Super
* I/O chip that implements parallel port/serial
* ports/IDE/FDI. Depending on the motherboard, the Super I/O
* chip can be configured through a pair of registers that are
* located either at I/O ports 0x26e/0x26f or 0x398/0x399.
* Unfortunately, autodetecting which base address is in use
* works only once (right after a reset). On the other hand,
* the Noname board hardwires the I/O ports to 0x26e/0x26f so
* we just use those. The Super I/O chip has the additional
* quirk that configuration register data must be written
* twice (I believe this is a saftey feature to prevent
* accidental modification---happy PC world...).
*/
{
long flags;
int data;
/* update needs to be atomic: */
save_flags(flags);
cli();
outb(0, 0x26e); /* set the index register for reg #0 */
data = inb(0x26f); /* read the current contents */
#ifdef DEBUG
printk("base @ 0x26e: reg#0 0x%x\n", data);
#endif
outb(0, 0x26e); /* set the index register for reg #0 */
outb(data | 0x40, 0x26f); /* turn on IDE */
outb(data | 0x40, 0x26f); /* yes, we really mean it... */
#ifdef DEBUG
outb(0, 0x26e); data = inb(0x26f);
printk("base @ 0x26e: reg#0 0x%x\n", data);
#endif
restore_flags(flags);
}
} }
...@@ -475,4 +517,31 @@ unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end) ...@@ -475,4 +517,31 @@ unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
return mem_start; return mem_start;
} }
char *pcibios_strerror (int error)
{
static char buf[80];
switch (error) {
case PCIBIOS_SUCCESSFUL:
return "SUCCESSFUL";
case PCIBIOS_FUNC_NOT_SUPPORTED:
return "FUNC_NOT_SUPPORTED";
case PCIBIOS_BAD_VENDOR_ID:
return "SUCCESSFUL";
case PCIBIOS_DEVICE_NOT_FOUND:
return "DEVICE_NOT_FOUND";
case PCIBIOS_BAD_REGISTER_NUMBER:
return "BAD_REGISTER_NUMBER";
default:
sprintf (buf, "UNKNOWN RETURN 0x%x", error);
return buf;
}
}
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
...@@ -505,10 +505,11 @@ sys_call_table: ...@@ -505,10 +505,11 @@ sys_call_table:
.quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys .quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys
.quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect .quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect
.quad sys_madvise, do_entSys, do_entSys, do_entSys, sys_getgroups .quad sys_madvise, do_entSys, do_entSys, do_entSys, sys_getgroups
.quad do_entSys, do_entSys, do_entSys, sys_setitimer, do_entSys /* map BSD's setpgrp to sys_setpgid for binary compatibility: */
.quad do_entSys, sys_getitimer, sys_gethostname, do_entSys, sys_getdtablesize .quad sys_setgroups, do_entSys, sys_setpgid, sys_setitimer, do_entSys
.quad do_entSys, sys_getitimer, sys_gethostname, sys_sethostname, sys_getdtablesize
.quad sys_dup2, sys_newfstat, sys_fcntl, sys_select, do_entSys .quad sys_dup2, sys_newfstat, sys_fcntl, sys_select, do_entSys
.quad sys_fsync, do_entSys, sys_socket, do_entSys, do_entSys .quad sys_fsync, sys_setpriority, sys_socket, do_entSys, do_entSys
/*100*/ .quad do_entSys, do_entSys, do_entSys, sys_sigreturn, sys_bind /*100*/ .quad do_entSys, do_entSys, do_entSys, sys_sigreturn, sys_bind
.quad do_entSys, sys_listen, do_entSys, do_entSys, do_entSys .quad do_entSys, sys_listen, do_entSys, do_entSys, do_entSys
.quad do_entSys, sys_sigsuspend, do_entSys, do_entSys, do_entSys .quad do_entSys, sys_sigsuspend, do_entSys, do_entSys, do_entSys
...@@ -529,9 +530,9 @@ sys_call_table: ...@@ -529,9 +530,9 @@ sys_call_table:
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, osf_swapon .quad do_entSys, do_entSys, do_entSys, do_entSys, osf_swapon
/*200*/ .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys /*200*/ .quad sys_msgctl, sys_msgget, sys_msgrcv, sys_msgsnd, sys_semctl
.quad do_entSys, do_entSys, osf_utsname, do_entSys, do_entSys .quad sys_semget, sys_semop, osf_utsname, do_entSys, osf_shmat
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad sys_shmctl, sys_shmdt, sys_shmget, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
...@@ -550,5 +551,5 @@ sys_call_table: ...@@ -550,5 +551,5 @@ sys_call_table:
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
/* linux-specific system calls start at 300 */ /* linux-specific system calls start at 300 */
/*300*/ .quad sys_bdflush, sys_sethae, do_entSys, do_entSys, do_entSys /*300*/ .quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
...@@ -232,6 +232,8 @@ static inline void handle_irq(int irq, struct pt_regs * regs) ...@@ -232,6 +232,8 @@ static inline void handle_irq(int irq, struct pt_regs * regs)
action->handler(irq, regs); action->handler(irq, regs);
} }
#ifndef CONFIG_PCI
static void local_device_interrupt(unsigned long vector, struct pt_regs * regs) static void local_device_interrupt(unsigned long vector, struct pt_regs * regs)
{ {
switch (vector) { switch (vector) {
...@@ -259,6 +261,8 @@ static void local_device_interrupt(unsigned long vector, struct pt_regs * regs) ...@@ -259,6 +261,8 @@ static void local_device_interrupt(unsigned long vector, struct pt_regs * regs)
} }
} }
#endif /* !CONFIG_PCI */
/* /*
* The vector is 0x8X0 for EISA interrupt X, and 0x9X0 for the local * The vector is 0x8X0 for EISA interrupt X, and 0x9X0 for the local
* motherboard interrupts.. This is for the Jensen. * motherboard interrupts.. This is for the Jensen.
...@@ -373,6 +377,11 @@ int probe_irq_off(unsigned int irqs) ...@@ -373,6 +377,11 @@ int probe_irq_off(unsigned int irqs)
static void machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) static void machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs)
{ {
printk("Machine check\n"); printk("Machine check\n");
#ifdef LCA_MEM_ESR
printk("esr=%lx, ear=%lx, ioc_stat0=%lx, ioc_stat1=%lx\n",
*(unsigned long*)LCA_MEM_ESR, *(unsigned long*)LCA_MEM_EAR,
*(unsigned long*)LCA_IOC_STAT0, *(unsigned long*)LCA_IOC_STAT1);
#endif
} }
asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/shm.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -41,7 +42,7 @@ extern dev_t get_unnamed_dev(void); ...@@ -41,7 +42,7 @@ extern dev_t get_unnamed_dev(void);
extern void put_unnamed_dev(dev_t); extern void put_unnamed_dev(dev_t);
extern asmlinkage int sys_umount(char *); extern asmlinkage int sys_umount(char *);
extern asmlinkage int sys_swapon(const char *specialfile); extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
/* /*
* OSF/1 directory handling functions... * OSF/1 directory handling functions...
...@@ -51,7 +52,7 @@ extern asmlinkage int sys_swapon(const char *specialfile); ...@@ -51,7 +52,7 @@ extern asmlinkage int sys_swapon(const char *specialfile);
* offset differences aren't the same as "d_reclen"). * offset differences aren't the same as "d_reclen").
*/ */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+7) & ~7) #define ROUND_UP(x) (((x)+3) & ~3)
struct osf_dirent { struct osf_dirent {
unsigned int d_ino; unsigned int d_ino;
...@@ -115,7 +116,7 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent, ...@@ -115,7 +116,7 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent,
buf.basep = basep; buf.basep = basep;
buf.count = count; buf.count = count;
buf.error = 0; buf.error = 0;
error = file->f_op->readdir(file->f_inode, file, dirent, osf_filldir); error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir);
if (error < 0) if (error < 0)
return error; return error;
if (count == buf.count) if (count == buf.count)
...@@ -442,8 +443,8 @@ asmlinkage int osf_utsname(char * name) ...@@ -442,8 +443,8 @@ asmlinkage int osf_utsname(char * name)
asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat) asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat)
{ {
/* for now, simply ignore flags, lowat and hiwat... */ /* for now, simply ignore lowat and hiwat... */
return sys_swapon(path); return sys_swapon(path, flags);
} }
asmlinkage unsigned long sys_getpagesize(void) asmlinkage unsigned long sys_getpagesize(void)
...@@ -492,3 +493,19 @@ asmlinkage int osf_getdomainname(char *name, int namelen) ...@@ -492,3 +493,19 @@ asmlinkage int osf_getdomainname(char *name, int namelen)
} }
return 0; return 0;
} }
asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
{
unsigned long raddr;
int err;
err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
if (err)
return err;
/*
* This works because all user-level addresses are
* non-negative longs!
*/
return raddr;
}
...@@ -61,7 +61,8 @@ struct screen_info screen_info = { ...@@ -61,7 +61,8 @@ struct screen_info screen_info = {
0, /* orig-video-mode */ 0, /* orig-video-mode */
80, /* orig-video-cols */ 80, /* orig-video-cols */
0,0,0, /* ega_ax, ega_bx, ega_cx */ 0,0,0, /* ega_ax, ega_bx, ega_cx */
25 /* orig-video-lines */ 25, /* orig-video-lines */
16 /* orig-video-points */
}; };
static unsigned long find_end_memory(void) static unsigned long find_end_memory(void)
...@@ -94,11 +95,7 @@ void setup_arch(char **cmdline_p, ...@@ -94,11 +95,7 @@ void setup_arch(char **cmdline_p,
set_hae(hae.cache); /* sync HAE register w/hae_cache */ set_hae(hae.cache); /* sync HAE register w/hae_cache */
ROOT_DEV = 0x0802; /* sda2 */ ROOT_DEV = 0x0802; /* sda2 */
#ifndef CONFIG_PCI
aux_device_present = 0xaa; aux_device_present = 0xaa;
#else
aux_device_present = 0x00;
#endif
command_line[COMMAND_LINE_SIZE - 1] = '\0'; command_line[COMMAND_LINE_SIZE - 1] = '\0';
strcpy(command_line, COMMAND_LINE); strcpy(command_line, COMMAND_LINE);
......
...@@ -54,6 +54,7 @@ asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, ...@@ -54,6 +54,7 @@ asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
{ {
printk("Arithmetic trap: %02lx %016lx\n", summary, write_mask); printk("Arithmetic trap: %02lx %016lx\n", summary, write_mask);
die_if_kernel("Arithmetic fault", &regs, 0); die_if_kernel("Arithmetic fault", &regs, 0);
send_sig(SIGFPE, current, 1);
} }
asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2,
...@@ -61,6 +62,7 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, ...@@ -61,6 +62,7 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2,
struct pt_regs regs) struct pt_regs regs)
{ {
die_if_kernel("Instruction fault", &regs, type); die_if_kernel("Instruction fault", &regs, type);
send_sig(SIGILL, current, 1);
} }
/* /*
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
.c.o: .c.o:
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
checksum.o
lib.a: $(OBJS) lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS) $(AR) rcs lib.a $(OBJS)
......
/*
* arch/alpha/lib/checksum.c
*
* This file contains network checksum routines that are better done
* in an architecture-specific manner due to speed..
*/
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
{
/* not yet */
return 0;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
unsigned int sum)
{
/* not yet */
return 0;
}
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum)
{
/* not yet */
return 0;
}
/*
* the same as csum_partial, but copies from fs:src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum)
{
/* not yet */
return 0;
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
unsigned short ip_compute_csum(unsigned char * buff, int len)
{
/* not yet */
return 0;
}
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* Alpha IO and memory functions.. Just expand the inlines in the header * Alpha IO and memory functions.. Just expand the inlines in the header
* files.. * files..
*/ */
#include <linux/kernel.h>
#include <asm/io.h> #include <asm/io.h>
/* /*
...@@ -96,3 +98,121 @@ void writel(unsigned int b, unsigned long addr) ...@@ -96,3 +98,121 @@ void writel(unsigned int b, unsigned long addr)
{ {
__writel(b, addr); __writel(b, addr);
} }
/*
* Read COUNT 16-bit words from port PORT into memory starting at
* SRC. SRC must be at least short aligned. This is used by the
* IDE driver to read disk sectors. Performance is important, but
* the interfaces seems to be slow: just using the inlined version
* of the inw() breaks things.
*/
#undef insw
void insw (unsigned long port, void *dst, unsigned long count)
{
unsigned int *ip, w;
if (((unsigned long)dst) & 0x3) {
if (((unsigned long)dst) & 0x1) {
panic("insw: memory not short aligned");
}
*(unsigned short*)dst = inw(port);
dst += 2;
--count;
}
ip = dst;
while (count >= 2) {
w = inw(port);
w |= inw(port) << 16;
count -= 2;
*ip++ = w;
}
if (count) {
w = inw(port);
*(unsigned short*)ip = w;
}
}
/*
* Read COUNT 32-bit words from port PORT into memory starting at
* SRC. SRC must be at least word aligned. This is used by the
* IDE driver to read disk sectors. Performance is important, but
* the interfaces seems to be slow: just using the inlined version
* of the inw() breaks things.
*/
#undef insl
void insl (unsigned long port, void *dst, unsigned long count)
{
unsigned int *ip, w;
if (((unsigned long)dst) & 0x3) {
panic("insl: memory not aligned");
}
ip = dst;
while (count > 0) {
w = inw(port);
--count;
*ip++ = w;
}
}
/*
* Like insw but in the opposite direction. This is used by the IDE
* driver to write disk sectors. Performance is important, but the
* interfaces seems to be slow: just using the inlined version of the
* outw() breaks things.
*/
#undef outsw
void outsw (unsigned long port, void *src, unsigned long count)
{
unsigned int *ip, w;
if (((unsigned long)src) & 0x3) {
if (((unsigned long)src) & 0x1) {
panic("outsw: memory not short aligned");
}
outw(*(unsigned short*)src, port);
src += 2;
--count;
}
ip = src;
while (count >= 2) {
w = *ip++;
count -= 2;
outw(w >> 0, port);
outw(w >> 16, port);
}
if (count) {
outw(*(unsigned short*)ip, port);
}
}
/*
* Like insl but in the opposite direction. This is used by the IDE
* driver to write disk sectors. Performance is important, but the
* interfaces seems to be slow: just using the inlined version of the
* outw() breaks things.
*/
#undef outsw
void outsl (unsigned long port, void *src, unsigned long count)
{
unsigned int *ip, w;
if (((unsigned long)src) & 0x3) {
panic("outsw: memory not aligned");
}
ip = src;
while (count > 0) {
w = *ip++;
--count;
outw(w, port);
}
}
...@@ -39,8 +39,9 @@ endif ...@@ -39,8 +39,9 @@ endif
HEAD := arch/i386/kernel/head.o HEAD := arch/i386/kernel/head.o
SUBDIRS := $(SUBDIRS) arch/i386/kernel arch/i386/mm SUBDIRS := $(SUBDIRS) arch/i386/kernel arch/i386/mm arch/i386/lib
ARCHIVES := arch/i386/kernel/kernel.o arch/i386/mm/mm.o $(ARCHIVES) ARCHIVES := arch/i386/kernel/kernel.o arch/i386/mm/mm.o $(ARCHIVES)
LIBS := $(TOPDIR)/arch/i386/lib/lib.a $(LIBS) $(TOPDIR)/arch/i386/lib/lib.a
ifdef CONFIG_IBCS ifdef CONFIG_IBCS
SUBDIRS := $(SUBDIRS) arch/i386/ibcs SUBDIRS := $(SUBDIRS) arch/i386/ibcs
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
.S.o: .S.o:
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = process.o signal.o entry.o traps.o irq.o vm86.o bios32.o ptrace.o ioport.o ldt.o setup.o OBJS = process.o signal.o entry.o traps.o irq.o vm86.o bios32.o ptrace.o \
ioport.o ldt.o setup.o sys_i386.o
all: kernel.o head.o all: kernel.o head.o
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
/* /*
* atomically swap in the new signal mask, and wait for a signal. * atomically swap in the new signal mask, and wait for a signal.
......
/*
* linux/arch/i386/kernel/sys_i386.c
*
* This file contains various random system calls that
* have a non-standard calling sequence on the Linux/i386
* platform.
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/stat.h>
#include <asm/segment.h>
/*
* Perform the select(nd, in, out, ex, tv) system call.
* Linux/i386 didn't use to be able to handle 5 system call
* parameters, so the old select used a memory block for
* parameter passing..
*/
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
asmlinkage int old_select(unsigned long *buffer)
{
int n;
fd_set *inp;
fd_set *outp;
fd_set *exp;
struct timeval *tvp;
n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
if (n)
return n;
n = get_user(buffer);
inp = (fd_set *) get_user(buffer+1);
outp = (fd_set *) get_user(buffer+2);
exp = (fd_set *) get_user(buffer+3);
tvp = (struct timeval *) get_user(buffer+4);
return sys_select(n, inp, outp, exp, tvp);
}
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
{
int version;
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
if (call <= SEMCTL)
switch (call) {
case SEMOP:
return sys_semop (first, (struct sembuf *)ptr, second);
case SEMGET:
return sys_semget (first, second, third);
case SEMCTL: {
union semun fourth;
int err;
if (!ptr)
return -EINVAL;
if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
return err;
fourth.__pad = (void *) get_fs_long(ptr);
return sys_semctl (first, second, third, fourth);
}
default:
return -EINVAL;
}
if (call <= MSGCTL)
switch (call) {
case MSGSND:
return sys_msgsnd (first, (struct msgbuf *) ptr,
second, third);
case MSGRCV:
switch (version) {
case 0: {
struct ipc_kludge tmp;
int err;
if (!ptr)
return -EINVAL;
if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
return err;
memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
sizeof (tmp));
return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
}
case 1: default:
return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
}
case MSGGET:
return sys_msgget ((key_t) first, second);
case MSGCTL:
return sys_msgctl (first, second, (struct msqid_ds *) ptr);
default:
return -EINVAL;
}
if (call <= SHMCTL)
switch (call) {
case SHMAT:
switch (version) {
case 0: default: {
ulong raddr;
int err;
if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
return err;
err = sys_shmat (first, (char *) ptr, second, &raddr);
if (err)
return err;
put_fs_long (raddr, (ulong *) third);
return 0;
}
case 1: /* iBCS2 emulator entry point */
if (get_fs() != get_ds())
return -EINVAL;
return sys_shmat (first, (char *) ptr, second, (ulong *) third);
}
case SHMDT:
return sys_shmdt ((char *)ptr);
case SHMGET:
return sys_shmget (first, second, third);
case SHMCTL:
return sys_shmctl (first, second, (struct shmid_ds *) ptr);
default:
return -EINVAL;
}
return -EINVAL;
}
...@@ -217,6 +217,8 @@ static inline unsigned long get_vflags(struct vm86_regs * regs) ...@@ -217,6 +217,8 @@ static inline unsigned long get_vflags(struct vm86_regs * regs)
static inline int is_revectored(int nr, struct revectored_struct * bitmap) static inline int is_revectored(int nr, struct revectored_struct * bitmap)
{ {
if (verify_area(VERIFY_READ, bitmap, 256/8) < 0)
return 1;
__asm__ __volatile__("btl %2,%%fs:%1\n\tsbbl %0,%0" __asm__ __volatile__("btl %2,%%fs:%1\n\tsbbl %0,%0"
:"=r" (nr) :"=r" (nr)
:"m" (*bitmap),"r" (nr)); :"m" (*bitmap),"r" (nr));
...@@ -298,22 +300,32 @@ __res; }) ...@@ -298,22 +300,32 @@ __res; })
static void do_int(struct vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp) static void do_int(struct vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp)
{ {
unsigned short seg = get_fs_word((void *) ((i<<2)+2)); unsigned short *intr_ptr, seg;
if (seg == BIOSSEG || regs->cs == BIOSSEG || if (regs->cs == BIOSSEG)
is_revectored(i, &current->tss.vm86_info->int_revectored)) goto cannot_handle;
return_to_32bit(regs, VM86_INTx + (i << 8)); if (is_revectored(i, &current->tss.vm86_info->int_revectored))
goto cannot_handle;
if (i==0x21 && is_revectored(AH(regs),&current->tss.vm86_info->int21_revectored)) if (i==0x21 && is_revectored(AH(regs),&current->tss.vm86_info->int21_revectored))
return_to_32bit(regs, VM86_INTx + (i << 8)); goto cannot_handle;
intr_ptr = (unsigned short *) (i << 2);
if (verify_area(VERIFY_READ, intr_ptr, 4) < 0)
goto cannot_handle;
seg = get_fs_word(intr_ptr+1);
if (seg == BIOSSEG)
goto cannot_handle;
pushw(ssp, sp, get_vflags(regs)); pushw(ssp, sp, get_vflags(regs));
pushw(ssp, sp, regs->cs); pushw(ssp, sp, regs->cs);
pushw(ssp, sp, IP(regs)); pushw(ssp, sp, IP(regs));
regs->cs = seg; regs->cs = seg;
SP(regs) -= 6; SP(regs) -= 6;
IP(regs) = get_fs_word((void *) (i<<2)); IP(regs) = get_fs_word(intr_ptr+0);
clear_TF(regs); clear_TF(regs);
clear_IF(regs); clear_IF(regs);
return; return;
cannot_handle:
return_to_32bit(regs, VM86_INTx + (i << 8));
} }
void handle_vm86_debug(struct vm86_regs * regs, long error_code) void handle_vm86_debug(struct vm86_regs * regs, long error_code)
......
#
# Makefile for i386-specific library files..
#
.c.s:
$(CC) $(CFLAGS) -S $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) -c $<
OBJS = checksum.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
sync
dep:
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif
...@@ -110,7 +110,7 @@ endif ...@@ -110,7 +110,7 @@ endif
dummy: dummy:
conhakehash: conmakehash.c conmakehash: conmakehash.c
$(HOSTCC) -o conmakehash conmakehash.c $(HOSTCC) -o conmakehash conmakehash.c
uni_hash_tbl.h: $(FONTMAPFILE) conmakehash uni_hash_tbl.h: $(FONTMAPFILE) conmakehash
......
...@@ -190,7 +190,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -190,7 +190,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
} }
/* Mask interrupts from the ethercard. */ /* Mask interrupts from the ethercard. */
outb(0x00, e8390_base + EN0_IMR); outb_p(0x00, e8390_base + EN0_IMR);
ei_local->irqlock = 1; ei_local->irqlock = 1;
restore_flags(flags); restore_flags(flags);
......
...@@ -149,8 +149,6 @@ static int eql_header(unsigned char *buff, struct device *dev, ...@@ -149,8 +149,6 @@ static int eql_header(unsigned char *buff, struct device *dev,
unsigned len, struct sk_buff *skb); /* */ unsigned len, struct sk_buff *skb); /* */
static int eql_rebuild_header(void *buff, struct device *dev, static int eql_rebuild_header(void *buff, struct device *dev,
unsigned long raddr, struct sk_buff *skb); /* */ unsigned long raddr, struct sk_buff *skb); /* */
static unsigned short eql_type_trans (struct sk_buff *skb,
struct device *dev); /* */
/* ioctl() handlers /* ioctl() handlers
---------------- */ ---------------- */
...@@ -414,12 +412,6 @@ eql_rebuild_header(void *buff, struct device *dev, ...@@ -414,12 +412,6 @@ eql_rebuild_header(void *buff, struct device *dev,
} }
static
unsigned short
eql_type_trans (struct sk_buff *skb, struct device *dev)
{
return htons (ETH_P_IP);
}
/* private ioctl functions /* private ioctl functions
......
...@@ -118,7 +118,7 @@ static char *version = ...@@ -118,7 +118,7 @@ static char *version =
#include <linux/timer.h> #include <linux/timer.h>
#include "pi2.h" #include "pi2.h"
#include "z8530.h" #include "z8530.h"
#include "ax25.h" #include <net/ax25.h>
struct mbuf { struct mbuf {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright 1993, 1994, 1995 Drew Eckhardt, Frederic Potter, * Copyright 1993, 1994, 1995 Drew Eckhardt, Frederic Potter,
* David Mosberger-Tang * David Mosberger-Tang
*/ */
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bios32.h> #include <linux/bios32.h>
...@@ -68,6 +69,8 @@ struct pci_dev_info dev_info[] = { ...@@ -68,6 +69,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82375, "82375EB"), DEVICE( INTEL, INTEL_82375, "82375EB"),
BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00), BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00),
DEVICE( INTEL, INTEL_82430, "82430ZX Aries"), DEVICE( INTEL, INTEL_82430, "82430ZX Aries"),
DEVICE( INTEL, INTEL_82437, "82437 Triton"),
DEVICE( INTEL, INTEL_82371, "82471 Triton"),
DEVICE( SMC, SMC_37C665, "FDC 37C665"), DEVICE( SMC, SMC_37C665, "FDC 37C665"),
DEVICE( ATI, ATI_M32, "Mach 32"), DEVICE( ATI, ATI_M32, "Mach 32"),
DEVICE( ATI, ATI_M64, "Mach 64"), DEVICE( ATI, ATI_M64, "Mach 64"),
...@@ -84,6 +87,7 @@ struct pci_dev_info dev_info[] = { ...@@ -84,6 +87,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( AL, AL_M1445, "M1445"), DEVICE( AL, AL_M1445, "M1445"),
DEVICE( AL, AL_M1449, "M1449"), DEVICE( AL, AL_M1449, "M1449"),
DEVICE( AL, AL_M1451, "M1451"), DEVICE( AL, AL_M1451, "M1451"),
DEVICE( AL, AL_M4803, "M4803"),
DEVICE( TSENG, TSENG_W32P_2, "ET4000W32P"), DEVICE( TSENG, TSENG_W32P_2, "ET4000W32P"),
DEVICE( TSENG, TSENG_W32P_b, "ET4000W32P rev B"), DEVICE( TSENG, TSENG_W32P_b, "ET4000W32P rev B"),
DEVICE( TSENG, TSENG_W32P_c, "ET4000W32P rev C"), DEVICE( TSENG, TSENG_W32P_c, "ET4000W32P rev C"),
...@@ -113,7 +117,6 @@ struct pci_dev_info dev_info[] = { ...@@ -113,7 +117,6 @@ struct pci_dev_info dev_info[] = {
DEVICE( ZEINET, ZEINET_1221, "1221"), DEVICE( ZEINET, ZEINET_1221, "1221"),
DEVICE( EF, EF_ATM, "155P-MF1"), DEVICE( EF, EF_ATM, "155P-MF1"),
DEVICE( HER, HER_STING, "Stingray"), DEVICE( HER, HER_STING, "Stingray"),
DEVICE( HER, HER_STING, "Stingray"),
DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"), DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"),
DEVICE( CT, CT_65545, "65545"), DEVICE( CT, CT_65545, "65545"),
DEVICE( FD, FD_36C70, "TMC-18C30"), DEVICE( FD, FD_36C70, "TMC-18C30"),
......
...@@ -876,9 +876,6 @@ inline void internal_cmnd (Scsi_Cmnd * SCpnt) ...@@ -876,9 +876,6 @@ inline void internal_cmnd (Scsi_Cmnd * SCpnt)
int clock; int clock;
#endif #endif
if ((unsigned long) &SCpnt < current->kernel_stack_page)
panic("Kernel stack overflow.");
host = SCpnt->host; host = SCpnt->host;
/* /*
......
...@@ -915,7 +915,7 @@ static int sd_init_onedisk(int i) ...@@ -915,7 +915,7 @@ static int sd_init_onedisk(int i)
while(jiffies < time1 + HZ); /* Wait 1 second for next try */ while(jiffies < time1 + HZ); /* Wait 1 second for next try */
printk( "." ); printk( "." );
}; };
} while(the_result && spintime && spintime+50*HZ > jiffies); } while(the_result && spintime && spintime+100*HZ > jiffies);
if (spintime) { if (spintime) {
if (the_result) if (the_result)
printk( "not responding...\n" ); printk( "not responding...\n" );
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/unistd.h> #include <linux/unistd.h>
typedef int (*sysfun_p)(int); typedef int (*sysfun_p)(int, ...);
extern sysfun_p sys_call_table[]; extern sysfun_p sys_call_table[];
#define SYS(name) (sys_call_table[__NR_##name]) #define SYS(name) (sys_call_table[__NR_##name])
...@@ -168,7 +168,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -168,7 +168,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
unsigned int load_addr; unsigned int load_addr;
int elf_exec_fileno; int elf_exec_fileno;
int elf_bss; int elf_bss;
int old_fs, retval; int retval;
unsigned int last_bss; unsigned int last_bss;
int error; int error;
int i, k; int i, k;
...@@ -195,16 +195,44 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -195,16 +195,44 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL); kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL);
if(!elf_phdata) return 0xffffffff; if(!elf_phdata) return 0xffffffff;
old_fs = get_fs();
set_fs(get_ds());
retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata, retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
set_fs(old_fs);
elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY); elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
if (elf_exec_fileno < 0) return 0xffffffff; if (elf_exec_fileno < 0) return 0xffffffff;
file = current->files->fd[elf_exec_fileno]; file = current->files->fd[elf_exec_fileno];
/*
* First calculate the maximum range of VMA that we need to
* use, and then allocate the entire thing. Then unmap
* and remap the individual portions of the file to the
* correct address.
*/
if( interp_elf_ex->e_type == ET_DYN )
{
int maxvma = 0;
eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
if(eppnt->p_type == PT_LOAD) {
if( maxvma < eppnt->p_vaddr + eppnt->p_memsz)
maxvma = eppnt->p_vaddr + eppnt->p_memsz;
}
error = do_mmap(file, 0, maxvma, PROT_READ,
MAP_PRIVATE | MAP_DENYWRITE, 0);
if(error < 0 && error > -1024) goto oops; /* Real error */
load_addr = error;
SYS(munmap)(load_addr, maxvma);
}
else
{
/*
* For normal executables, we do not use this offset,
* since the vaddr field contains an absolute address.
*/
load_addr = 0;
}
eppnt = elf_phdata; eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
if(eppnt->p_type == PT_LOAD) { if(eppnt->p_type == PT_LOAD) {
...@@ -212,30 +240,44 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -212,30 +240,44 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
error = do_mmap(file, error = do_mmap(file,
eppnt->p_vaddr & 0xfffff000, load_addr + (eppnt->p_vaddr & 0xfffff000),
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
elf_prot, elf_prot,
MAP_PRIVATE | MAP_DENYWRITE | (interp_elf_ex->e_type == ET_EXEC ? MAP_FIXED : 0), MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED,
eppnt->p_offset & 0xfffff000); eppnt->p_offset & 0xfffff000);
if(!load_addr && interp_elf_ex->e_type == ET_DYN) if(error < 0 && error > -1024) break; /* Real error */
load_addr = error;
/*
* Find the end of the file mapping for this phdr, and keep
* track of the largest address we see for this.
*/
k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
if(k > elf_bss) elf_bss = k; if(k > elf_bss) elf_bss = k;
if(error < 0 && error > -1024) break; /* Real error */
/*
* Do the same thing for the memory mapping - between
* elf_bss and last_bss is the bss section.
*/
k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
if(k > last_bss) last_bss = k; if(k > last_bss) last_bss = k;
} }
/* Now use mmap to map the library into memory. */ /* Now use mmap to map the library into memory. */
oops:
SYS(close)(elf_exec_fileno); SYS(close)(elf_exec_fileno);
if(error < 0 && error > -1024) { if(error < 0 && error > -1024) {
kfree(elf_phdata); kfree(elf_phdata);
return 0xffffffff; return 0xffffffff;
} }
/*
* Now fill out the bss section. First pad the last page up
* to the page boundary, and then perform a mmap to make sure
* that there are zeromapped pages up to and including the last
* bss page.
*/
padzero(elf_bss); padzero(elf_bss);
len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */ len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
...@@ -266,7 +308,7 @@ static unsigned int load_aout_interp(struct exec * interp_ex, ...@@ -266,7 +308,7 @@ static unsigned int load_aout_interp(struct exec * interp_ex,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
retval = read_exec(interpreter_inode, 32, (char *) 0, retval = read_exec(interpreter_inode, 32, (char *) 0,
interp_ex->a_text+interp_ex->a_data); interp_ex->a_text+interp_ex->a_data, 0);
} else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) { } else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data, do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
...@@ -274,7 +316,7 @@ static unsigned int load_aout_interp(struct exec * interp_ex, ...@@ -274,7 +316,7 @@ static unsigned int load_aout_interp(struct exec * interp_ex,
retval = read_exec(interpreter_inode, retval = read_exec(interpreter_inode,
N_TXTOFF(*interp_ex) , N_TXTOFF(*interp_ex) ,
(char *) N_TXTADDR(*interp_ex), (char *) N_TXTADDR(*interp_ex),
interp_ex->a_text+interp_ex->a_data); interp_ex->a_text+interp_ex->a_data, 0);
} else } else
retval = -1; retval = -1;
...@@ -350,11 +392,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -350,11 +392,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize *
elf_ex.e_phnum, GFP_KERNEL); elf_ex.e_phnum, GFP_KERNEL);
old_fs = get_fs();
set_fs(get_ds());
retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata, retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
elf_ex.e_phentsize * elf_ex.e_phnum); elf_ex.e_phentsize * elf_ex.e_phnum, 1);
set_fs(old_fs);
if (retval < 0) { if (retval < 0) {
kfree (elf_phdata); kfree (elf_phdata);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
...@@ -382,9 +421,6 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -382,9 +421,6 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
end_code = 0; end_code = 0;
end_data = 0; end_data = 0;
old_fs = get_fs();
set_fs(get_ds());
for(i=0;i < elf_ex.e_phnum; i++){ for(i=0;i < elf_ex.e_phnum; i++){
if(elf_ppnt->p_type == PT_INTERP) { if(elf_ppnt->p_type == PT_INTERP) {
/* This is the program interpreter used for shared libraries - /* This is the program interpreter used for shared libraries -
...@@ -394,7 +430,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -394,7 +430,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
GFP_KERNEL); GFP_KERNEL);
retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter, retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
elf_ppnt->p_filesz); elf_ppnt->p_filesz, 1);
/* If the program interpreter is one of these two, /* If the program interpreter is one of these two,
then assume an iBCS2 image. Otherwise assume then assume an iBCS2 image. Otherwise assume
a native linux image. */ a native linux image. */
...@@ -407,7 +443,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -407,7 +443,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if(retval >= 0) if(retval >= 0)
retval = namei(elf_interpreter, &interpreter_inode); retval = namei(elf_interpreter, &interpreter_inode);
if(retval >= 0) if(retval >= 0)
retval = read_exec(interpreter_inode,0,bprm->buf,128); retval = read_exec(interpreter_inode,0,bprm->buf,128, 1);
if(retval >= 0){ if(retval >= 0){
interp_ex = *((struct exec *) bprm->buf); /* exec-header */ interp_ex = *((struct exec *) bprm->buf); /* exec-header */
...@@ -424,8 +460,6 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -424,8 +460,6 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
elf_ppnt++; elf_ppnt++;
}; };
set_fs(old_fs);
/* Some simple consistency checks for the interpreter */ /* Some simple consistency checks for the interpreter */
if(elf_interpreter){ if(elf_interpreter){
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
...@@ -649,7 +683,7 @@ load_elf_library(int fd){ ...@@ -649,7 +683,7 @@ load_elf_library(int fd){
struct inode * inode; struct inode * inode;
unsigned int len; unsigned int len;
int elf_bss; int elf_bss;
int old_fs, retval; int retval;
unsigned int bss; unsigned int bss;
int error; int error;
int i,j, k; int i,j, k;
...@@ -692,11 +726,8 @@ load_elf_library(int fd){ ...@@ -692,11 +726,8 @@ load_elf_library(int fd){
elf_phdata = (struct elf_phdr *) elf_phdata = (struct elf_phdr *)
kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
old_fs = get_fs();
set_fs(get_ds());
retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata, retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
sizeof(struct elf_phdr) * elf_ex.e_phnum); sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
set_fs(old_fs);
j = 0; j = 0;
for(i=0; i<elf_ex.e_phnum; i++) for(i=0; i<elf_ex.e_phnum; i++)
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
/* /*
* #!-checking implemented by tytso. * #!-checking implemented by tytso.
*/ */
/* /*
* Demand-loading implemented 01.12.91 - no need to read anything but * Demand-loading implemented 01.12.91 - no need to read anything but
* the header into memory. The inode of the executable is put into * the header into memory. The inode of the executable is put into
...@@ -297,17 +296,19 @@ asmlinkage int sys_uselib(const char * library) ...@@ -297,17 +296,19 @@ asmlinkage int sys_uselib(const char * library)
* memory and creates the pointer tables from them, and puts their * memory and creates the pointer tables from them, and puts their
* addresses on the "stack", returning the new stack pointer value. * addresses on the "stack", returning the new stack pointer value.
*/ */
unsigned long * create_tables(char * p,int argc,int envc,int ibcs) unsigned long * create_tables(char * p, struct linux_binprm * bprm, int ibcs)
{ {
unsigned long *argv,*envp; unsigned long *argv,*envp;
unsigned long * sp; unsigned long * sp;
struct vm_area_struct *mpnt; struct vm_area_struct *mpnt;
int argc = bprm->argc;
int envc = bprm->envc;
mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL); mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
if (mpnt) { if (mpnt) {
mpnt->vm_task = current; mpnt->vm_task = current;
mpnt->vm_start = PAGE_MASK & (unsigned long) p; mpnt->vm_start = PAGE_MASK & (unsigned long) p;
mpnt->vm_end = TASK_SIZE; mpnt->vm_end = STACK_TOP;
mpnt->vm_page_prot = PAGE_COPY; mpnt->vm_page_prot = PAGE_COPY;
mpnt->vm_flags = VM_STACK_FLAGS; mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_ops = NULL; mpnt->vm_ops = NULL;
...@@ -316,28 +317,28 @@ unsigned long * create_tables(char * p,int argc,int envc,int ibcs) ...@@ -316,28 +317,28 @@ unsigned long * create_tables(char * p,int argc,int envc,int ibcs)
mpnt->vm_pte = 0; mpnt->vm_pte = 0;
insert_vm_struct(current, mpnt); insert_vm_struct(current, mpnt);
} }
sp = (unsigned long *) (0xfffffffc & (unsigned long) p); sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
sp -= envc+1; sp -= envc+1;
envp = sp; envp = sp;
sp -= argc+1; sp -= argc+1;
argv = sp; argv = sp;
if (!ibcs) { if (!ibcs) {
put_fs_long((unsigned long)envp,--sp); put_user(envp,--sp);
put_fs_long((unsigned long)argv,--sp); put_user(argv,--sp);
} }
put_fs_long((unsigned long)argc,--sp); put_user(argc,--sp);
current->mm->arg_start = (unsigned long) p; current->mm->arg_start = (unsigned long) p;
while (argc-->0) { while (argc-->0) {
put_fs_long((unsigned long) p,argv++); put_user(p,argv++);
while (get_fs_byte(p++)) /* nothing */ ; while (get_fs_byte(p++)) /* nothing */ ;
} }
put_fs_long(0,argv); put_user(NULL,argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p; current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) { while (envc-->0) {
put_fs_long((unsigned long) p,envp++); put_user(p,envp++);
while (get_fs_byte(p++)) /* nothing */ ; while (get_fs_byte(p++)) /* nothing */ ;
} }
put_fs_long(0,envp); put_user(NULL,envp);
current->mm->env_end = (unsigned long) p; current->mm->env_end = (unsigned long) p;
return sp; return sp;
} }
...@@ -357,7 +358,7 @@ static int count(char ** argv) ...@@ -357,7 +358,7 @@ static int count(char ** argv)
error = verify_area(VERIFY_READ, tmp, sizeof(char *)); error = verify_area(VERIFY_READ, tmp, sizeof(char *));
if (error) if (error)
return error; return error;
while ((p = (char *) get_fs_long((unsigned long *) (tmp++))) != NULL) { while ((p = (char *) get_user(tmp++)) != NULL) {
i++; i++;
error = verify_area(VERIFY_READ, p, 1); error = verify_area(VERIFY_READ, p, 1);
if (error) if (error)
...@@ -400,7 +401,7 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page, ...@@ -400,7 +401,7 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
while (argc-- > 0) { while (argc-- > 0) {
if (from_kmem == 1) if (from_kmem == 1)
set_fs(new_fs); set_fs(new_fs);
if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc))) if (!(tmp = (char *)get_user(argv+argc)))
panic("VFS: argc is wrong"); panic("VFS: argc is wrong");
if (from_kmem == 1) if (from_kmem == 1)
set_fs(old_fs); set_fs(old_fs);
...@@ -439,8 +440,8 @@ unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page) ...@@ -439,8 +440,8 @@ unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page)
unsigned long code_limit,data_limit,code_base,data_base; unsigned long code_limit,data_limit,code_base,data_base;
int i; int i;
code_limit = TASK_SIZE; code_limit = STACK_TOP;
data_limit = TASK_SIZE; data_limit = STACK_TOP;
code_base = data_base = 0; code_base = data_base = 0;
current->mm->start_code = code_base; current->mm->start_code = code_base;
data_base += data_limit; data_base += data_limit;
...@@ -460,7 +461,7 @@ unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page) ...@@ -460,7 +461,7 @@ unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page)
* without bmap support. * without bmap support.
*/ */
int read_exec(struct inode *inode, unsigned long offset, int read_exec(struct inode *inode, unsigned long offset,
char * addr, unsigned long count) char * addr, unsigned long count, int to_kmem)
{ {
struct file file; struct file file;
int result = -ENOEXEC; int result = -ENOEXEC;
...@@ -484,12 +485,17 @@ int read_exec(struct inode *inode, unsigned long offset, ...@@ -484,12 +485,17 @@ int read_exec(struct inode *inode, unsigned long offset,
goto close_readexec; goto close_readexec;
} else } else
file.f_pos = offset; file.f_pos = offset;
if (get_fs() == USER_DS) { if (to_kmem) {
unsigned long old_fs = get_fs();
set_fs(get_ds());
result = file.f_op->read(inode, &file, addr, count);
set_fs(old_fs);
} else {
result = verify_area(VERIFY_WRITE, addr, count); result = verify_area(VERIFY_WRITE, addr, count);
if (result) if (result)
goto close_readexec; goto close_readexec;
result = file.f_op->read(inode, &file, addr, count);
} }
result = file.f_op->read(inode, &file, addr, count);
close_readexec: close_readexec:
if (file.f_op->release) if (file.f_op->release)
file.f_op->release(inode,&file); file.f_op->release(inode,&file);
...@@ -552,18 +558,19 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -552,18 +558,19 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
{ {
struct linux_binprm bprm; struct linux_binprm bprm;
struct linux_binfmt * fmt; struct linux_binfmt * fmt;
unsigned long old_fs;
int i; int i;
int retval; int retval;
int sh_bang = 0; int sh_bang = 0;
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-4; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
bprm.page[i] = 0; bprm.page[i] = 0;
retval = open_namei(filename, 0, 0, &bprm.inode, NULL); retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
if (retval) if (retval)
return retval; return retval;
bprm.filename = filename; bprm.filename = filename;
bprm.loader = 0;
bprm.exec = 0;
if ((bprm.argc = count(argv)) < 0) if ((bprm.argc = count(argv)) < 0)
return bprm.argc; return bprm.argc;
if ((bprm.envc = count(envp)) < 0) if ((bprm.envc = count(envp)) < 0)
...@@ -608,10 +615,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -608,10 +615,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
goto exec_error2; goto exec_error2;
} }
memset(bprm.buf,0,sizeof(bprm.buf)); memset(bprm.buf,0,sizeof(bprm.buf));
old_fs = get_fs(); retval = read_exec(bprm.inode,0,bprm.buf,128,1);
set_fs(get_ds());
retval = read_exec(bprm.inode,0,bprm.buf,128);
set_fs(old_fs);
if (retval < 0) if (retval < 0)
goto exec_error2; goto exec_error2;
if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) { if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
...@@ -688,6 +692,8 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -688,6 +692,8 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
goto restart_interp; goto restart_interp;
} }
if (!sh_bang) { if (!sh_bang) {
bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
bprm.exec = bprm.p;
bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0); bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0); bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
if (!bprm.p) { if (!bprm.p) {
...@@ -738,20 +744,23 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -738,20 +744,23 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{ {
struct exec ex; struct exec ex;
struct file * file; struct file * file;
int fd, error; int fd;
unsigned long error;
unsigned long p = bprm->p; unsigned long p = bprm->p;
unsigned long fd_offset; unsigned long fd_offset;
ex = *((struct exec *) bprm->buf); /* exec-header */ ex = *((struct exec *) bprm->buf); /* exec-header */
if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
N_MAGIC(ex) != QMAGIC) || N_MAGIC(ex) != QMAGIC) ||
ex.a_trsize || ex.a_drsize || N_TRSIZE(ex) || N_DRSIZE(ex) ||
bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { bprm->inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
return -ENOEXEC; return -ENOEXEC;
} }
current->personality = PER_LINUX; current->personality = PER_LINUX;
fd_offset = N_TXTOFF(ex); fd_offset = N_TXTOFF(ex);
#ifdef __i386__
if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) { if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) {
printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n"); printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n");
return -ENOEXEC; return -ENOEXEC;
...@@ -762,15 +771,18 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -762,15 +771,18 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n"); printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n");
return -ENOEXEC; return -ENOEXEC;
} }
#endif
/* OK, This is the point of no return */ /* OK, This is the point of no return */
flush_old_exec(bprm); flush_old_exec(bprm);
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
current->mm->end_data = ex.a_data +
(current->mm->start_data = N_DATADDR(ex));
current->mm->brk = ex.a_bss + current->mm->brk = ex.a_bss +
(current->mm->start_brk = (current->mm->start_brk = N_BSSADDR(ex));
(current->mm->end_data = ex.a_data +
(current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex)))));
current->mm->rss = 0; current->mm->rss = 0;
current->mm->mmap = NULL; current->mm->mmap = NULL;
current->suid = current->euid = current->fsuid = bprm->e_uid; current->suid = current->euid = current->fsuid = bprm->e_uid;
...@@ -779,7 +791,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -779,7 +791,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
do_mmap(NULL, 0, ex.a_text+ex.a_data, do_mmap(NULL, 0, ex.a_text+ex.a_data,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data); read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data, 0);
} else { } else {
if (ex.a_text & 0xfff || ex.a_data & 0xfff) if (ex.a_text & 0xfff || ex.a_data & 0xfff)
printk(KERN_NOTICE "executable not page aligned\n"); printk(KERN_NOTICE "executable not page aligned\n");
...@@ -795,7 +807,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -795,7 +807,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
read_exec(bprm->inode, fd_offset, read_exec(bprm->inode, fd_offset,
(char *) N_TXTADDR(ex), ex.a_text+ex.a_data); (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);
goto beyond_if; goto beyond_if;
} }
...@@ -810,12 +822,12 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -810,12 +822,12 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
return error; return error;
} }
error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data, error = do_mmap(file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text); fd_offset + ex.a_text);
sys_close(fd); sys_close(fd);
if (error != N_TXTADDR(ex) + ex.a_text) { if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
} }
...@@ -833,11 +845,14 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -833,11 +845,14 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
(*current->binfmt->use_count)++; (*current->binfmt->use_count)++;
set_brk(current->mm->start_brk, current->mm->brk); set_brk(current->mm->start_brk, current->mm->brk);
fd_offset = setup_arg_pages(ex.a_text,bprm->page) - MAX_ARG_PAGES*PAGE_SIZE;
p += fd_offset;
if (bprm->loader)
bprm->loader += fd_offset;
bprm->exec += fd_offset;
p += setup_arg_pages(ex.a_text,bprm->page); p = (unsigned long)create_tables((char *)p, bprm,
p -= MAX_ARG_PAGES*PAGE_SIZE;
p = (unsigned long)create_tables((char *)p,
bprm->argc, bprm->envc,
current->personality != PER_LINUX); current->personality != PER_LINUX);
current->mm->start_stack = p; current->mm->start_stack = p;
start_thread(regs, ex.a_entry, p); start_thread(regs, ex.a_entry, p);
...@@ -855,7 +870,7 @@ static int load_aout_library(int fd) ...@@ -855,7 +870,7 @@ static int load_aout_library(int fd)
unsigned int len; unsigned int len;
unsigned int bss; unsigned int bss;
unsigned int start_addr; unsigned int start_addr;
int error; unsigned long error;
file = current->files->fd[fd]; file = current->files->fd[fd];
inode = file->f_inode; inode = file->f_inode;
...@@ -867,9 +882,9 @@ static int load_aout_library(int fd) ...@@ -867,9 +882,9 @@ static int load_aout_library(int fd)
set_fs(USER_DS); set_fs(USER_DS);
/* We come in here for the regular a.out style of shared libraries */ /* We come in here for the regular a.out style of shared libraries */
if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize || if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
return -ENOEXEC; return -ENOEXEC;
} }
if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
......
...@@ -257,7 +257,6 @@ int ext2_new_block (struct super_block * sb, unsigned long goal, ...@@ -257,7 +257,6 @@ int ext2_new_block (struct super_block * sb, unsigned long goal,
struct buffer_head * bh2; struct buffer_head * bh2;
char * p, * r; char * p, * r;
int i, j, k, tmp; int i, j, k, tmp;
unsigned long lmap;
int bitmap_nr; int bitmap_nr;
struct ext2_group_desc * gdp; struct ext2_group_desc * gdp;
struct ext2_super_block * es; struct ext2_super_block * es;
...@@ -310,22 +309,16 @@ int ext2_new_block (struct super_block * sb, unsigned long goal, ...@@ -310,22 +309,16 @@ int ext2_new_block (struct super_block * sb, unsigned long goal,
if (j) { if (j) {
/* /*
* The goal was occupied; search forward for a free * The goal was occupied; search forward for a free
* block within the next 32 blocks * block within the next XX blocks.
*
* end_goal is more or less random, but it has to be
* less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
* next 64-bit boundary is simple..
*/ */
lmap = ((((unsigned long *) bh->b_data)[j >> 5]) >> int end_goal = (j + 63) & ~63;
((j & 31) + 1)); j = find_next_zero_bit(bh->b_data, end_goal, j);
if (j < EXT2_BLOCKS_PER_GROUP(sb) - 32) if (j < end_goal)
lmap |= (((unsigned long *) bh->b_data)[(j >> 5) + 1]) << goto got_block;
(31 - (j & 31));
else
lmap |= 0xffffffff << (31 - (j & 31));
if (lmap != 0xffffffffl) {
k = ffz(lmap) + 1;
if ((j + k) < EXT2_BLOCKS_PER_GROUP(sb)) {
j += k;
goto got_block;
}
}
} }
ext2_debug ("Bit not found near goal\n"); ext2_debug ("Bit not found near goal\n");
......
...@@ -196,8 +196,10 @@ void proc_read_inode(struct inode * inode) ...@@ -196,8 +196,10 @@ void proc_read_inode(struct inode * inode)
return; return;
} }
ino &= 0x0000ffff; ino &= 0x0000ffff;
inode->i_uid = p->euid; if (p->dumpable) {
inode->i_gid = p->egid; inode->i_uid = p->uid;
inode->i_gid = p->gid;
}
switch (ino) { switch (ino) {
case PROC_PID_INO: case PROC_PID_INO:
inode->i_nlink = 4; inode->i_nlink = 4;
......
...@@ -154,9 +154,10 @@ static int do_select(int n, fd_set *in, fd_set *out, fd_set *ex, ...@@ -154,9 +154,10 @@ static int do_select(int n, fd_set *in, fd_set *out, fd_set *ex,
* We do a VERIFY_WRITE here even though we are only reading this time: * We do a VERIFY_WRITE here even though we are only reading this time:
* we'll write to it eventually.. * we'll write to it eventually..
*/ */
static int __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdset) static int __get_fd_set(int nr, unsigned long * fs_pointer, fd_set * fdset)
{ {
int error; int error, i;
unsigned long * tmp;
FD_ZERO(fdset); FD_ZERO(fdset);
if (!fs_pointer) if (!fs_pointer)
...@@ -164,9 +165,12 @@ static int __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdse ...@@ -164,9 +165,12 @@ static int __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdse
error = verify_area(VERIFY_WRITE,fs_pointer,sizeof(fd_set)); error = verify_area(VERIFY_WRITE,fs_pointer,sizeof(fd_set));
if (error) if (error)
return error; return error;
while (nr > 0) { tmp = fdset->fds_bits;
*fdset = get_user(fs_pointer); for (i = __FDSET_LONGS; i > 0; i--) {
fdset++; if (nr <= 0)
break;
*tmp = get_user(fs_pointer);
tmp++;
fs_pointer++; fs_pointer++;
nr -= 8 * sizeof(unsigned long); nr -= 8 * sizeof(unsigned long);
} }
...@@ -175,9 +179,13 @@ static int __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdse ...@@ -175,9 +179,13 @@ static int __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdse
static void __set_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdset) static void __set_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdset)
{ {
int i;
if (!fs_pointer) if (!fs_pointer)
return; return;
while (nr > 0) { for (i = __FDSET_LONGS; i > 0; i--) {
if (nr <= 0)
break;
put_user(*fdset, fs_pointer); put_user(*fdset, fs_pointer);
fdset++; fdset++;
fs_pointer++; fs_pointer++;
...@@ -186,7 +194,7 @@ static void __set_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fds ...@@ -186,7 +194,7 @@ static void __set_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fds
} }
#define get_fd_set(nr,fsp,fdp) \ #define get_fd_set(nr,fsp,fdp) \
__get_fd_set(nr, (unsigned long *) (fsp), (unsigned long *) (fdp)) __get_fd_set(nr, (unsigned long *) (fsp), fdp)
#define set_fd_set(nr,fsp,fdp) \ #define set_fd_set(nr,fsp,fdp) \
__set_fd_set(nr, (unsigned long *) (fsp), (unsigned long *) (fdp)) __set_fd_set(nr, (unsigned long *) (fsp), (unsigned long *) (fdp))
...@@ -245,28 +253,3 @@ asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct ...@@ -245,28 +253,3 @@ asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct
set_fd_set(n, exp, &res_ex); set_fd_set(n, exp, &res_ex);
return i; return i;
} }
/*
* Perform the select(nd, in, out, ex, tv) system call.
* Linux/i386 didn't use to be able to handle 5 system call
* parameters, so the old select used a memory block for
* parameter passing..
*/
asmlinkage int old_select(unsigned long *buffer)
{
int n;
fd_set *inp;
fd_set *outp;
fd_set *exp;
struct timeval *tvp;
n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
if (n)
return n;
n = get_user(buffer);
inp = (fd_set *) get_user(buffer+1);
outp = (fd_set *) get_user(buffer+2);
exp = (fd_set *) get_user(buffer+3);
tvp = (struct timeval *) get_user(buffer+4);
return sys_select(n, inp, outp, exp, tvp);
}
#ifndef __ALPHA_A_OUT_H__
#define __ALPHA_A_OUT_H__
/* OSF/1 pseudo-a.out header */
struct exec
{
/* OSF/1 "file" header */
unsigned short f_magic, f_nscns;
unsigned int f_timdat;
unsigned long f_symptr;
unsigned int f_nsyms;
unsigned short f_opthdr, f_flags;
/* followed by a more normal "a.out" header */
unsigned long a_info; /* after that it looks quite normal.. */
unsigned long a_text;
unsigned long a_data;
unsigned long a_bss;
unsigned long a_entry;
unsigned long a_textstart; /* with a few additions that actually make sense */
unsigned long a_datastart;
unsigned long a_bssstart;
unsigned int a_gprmask, a_fprmask; /* but what are these? */
unsigned long a_gpvalue;
};
#define N_TXTADDR(x) ((x).a_textstart)
#define N_DATADDR(x) ((x).a_datastart)
#define N_BSSADDR(x) ((x).a_bssstart)
#define N_DRSIZE(x) 0
#define N_TRSIZE(x) 0
#define N_SYMSIZE(x) 0
#define SCNHSZ 64 /* XXX should be sizeof(scnhdr) */
#define SCNROUND 16
#define N_TXTOFF(x) \
((long) N_MAGIC(x) == ZMAGIC ? 0 : \
(sizeof(struct exec) + (x).f_nscns*SCNHSZ + SCNROUND - 1) & ~(SCNROUND - 1))
#ifdef __KERNEL__
#define STACK_TOP (0x00120000000UL)
#endif
#endif /* __A_OUT_GNU_H__ */
#ifndef _ALPHA_CHECKSUM_H
#define _ALPHA_CHECKSUM_H
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
extern inline unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
extern unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
unsigned int sum);
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
/*
* the same as csum_partial, but copies from fs:src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern unsigned short ip_compute_csum(unsigned char * buff, int len);
#endif
#ifndef _ALPHA_DIRENT_H
#define _ALPHA_DIRENT_H
struct dirent {
ino_t d_ino;
unsigned short d_reclen;
unsigned short d_namlen;
char d_name[256];
};
#endif
...@@ -33,14 +33,27 @@ ...@@ -33,14 +33,27 @@
/* for F_[GET|SET]FL */ /* for F_[GET|SET]FL */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* for posix fcntl() and lockf() */
#define F_RDLCK 1 #define F_RDLCK 1
#define F_WRLCK 2 #define F_WRLCK 2
#define F_UNLCK 8 #define F_UNLCK 8
/* For bsd flock () */ /* for old implementation of bsd flock () */
#define F_EXLCK 16 /* or 3 */ #define F_EXLCK 16 /* or 3 */
#define F_SHLCK 32 /* or 4 */ #define F_SHLCK 32 /* or 4 */
/* operations for bsd flock(), also used by the kernel implementation */
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* or'd with one of the above to prevent
blocking */
#define LOCK_UN 8 /* remove lock */
#ifdef __KERNEL__
#define F_POSIX 1
#define F_FLOCK 2
#endif /* __KERNEL__ */
struct flock { struct flock {
short l_type; short l_type;
short l_whence; short l_whence;
......
...@@ -18,6 +18,13 @@ extern struct hae { ...@@ -18,6 +18,13 @@ extern struct hae {
unsigned long *reg; unsigned long *reg;
} hae; } hae;
/*
* Virtual -> physical identity mapping starts at this offset
*/
#define IDENT_ADDR (0xfffffc0000000000UL)
#ifdef __KERNEL__
/* /*
* We try to avoid hae updates (thus the cache), but when we * We try to avoid hae updates (thus the cache), but when we
* do need to update the hae, we need to do it atomically, so * do need to update the hae, we need to do it atomically, so
...@@ -34,11 +41,6 @@ extern inline void set_hae(unsigned long new_hae) ...@@ -34,11 +41,6 @@ extern inline void set_hae(unsigned long new_hae)
setipl(ipl); setipl(ipl);
} }
/*
* Virtual -> physical identity mapping starts at this offset
*/
#define IDENT_ADDR (0xfffffc0000000000UL)
/* /*
* Change virtual addresses to physical addresses and vv. * Change virtual addresses to physical addresses and vv.
*/ */
...@@ -52,6 +54,31 @@ extern inline void * phys_to_virt(unsigned long address) ...@@ -52,6 +54,31 @@ extern inline void * phys_to_virt(unsigned long address)
return (void *) (address + IDENT_ADDR); return (void *) (address + IDENT_ADDR);
} }
#else /* !__KERNEL__ */
/*
* Define actual functions in private name-space so it's easier to
* accomodate things like XFree or svgalib that like to define their
* own versions of inb etc.
*/
extern unsigned int _inb (unsigned long port);
extern unsigned int _inw (unsigned long port);
extern unsigned int _inl (unsigned long port);
extern void _outb (unsigned char b,unsigned long port);
extern void _outw (unsigned short w,unsigned long port);
extern void _outl (unsigned int l,unsigned long port);
#ifndef inb
# define inb(p) _inb((p))
# define inw(p) _inw((p))
# define inl(p) _inl((p))
# define outb(b,p) _outb((b),(p))
# define outw(w,p) _outw((w),(p))
# define outl(l,p) _outl((l),(p))
#endif
#endif /* __KERNEL__ */
/* /*
* There are different version of the alpha motherboards: the * There are different version of the alpha motherboards: the
* "interesting" (read: slightly braindead) Jensen type hardware * "interesting" (read: slightly braindead) Jensen type hardware
......
...@@ -55,20 +55,6 @@ ...@@ -55,20 +55,6 @@
#define LCA_DMA_WIN_BASE (1024*1024*1024) #define LCA_DMA_WIN_BASE (1024*1024*1024)
#define LCA_DMA_WIN_SIZE (1024*1024*1024) #define LCA_DMA_WIN_SIZE (1024*1024*1024)
/*
* Translate physical memory address as seen on (PCI) bus into
* a kernel virtual address and vv.
*/
extern inline unsigned long virt_to_bus(void * address)
{
return virt_to_phys(address) + LCA_DMA_WIN_BASE;
}
extern inline void * bus_to_virt(unsigned long address)
{
return phys_to_virt(address - LCA_DMA_WIN_BASE);
}
/* /*
* Memory Controller registers: * Memory Controller registers:
*/ */
...@@ -142,6 +128,22 @@ extern inline void * bus_to_virt(unsigned long address) ...@@ -142,6 +128,22 @@ extern inline void * bus_to_virt(unsigned long address)
#define HAE_ADDRESS LCA_IOC_HAE #define HAE_ADDRESS LCA_IOC_HAE
#ifdef __KERNEL__
/*
* Translate physical memory address as seen on (PCI) bus into
* a kernel virtual address and vv.
*/
extern inline unsigned long virt_to_bus(void * address)
{
return virt_to_phys(address) + LCA_DMA_WIN_BASE;
}
extern inline void * bus_to_virt(unsigned long address)
{
return phys_to_virt(address - LCA_DMA_WIN_BASE);
}
/* /*
* I/O functions: * I/O functions:
* *
...@@ -287,6 +289,14 @@ extern void outb(unsigned char b, unsigned long addr); ...@@ -287,6 +289,14 @@ extern void outb(unsigned char b, unsigned long addr);
extern void outw(unsigned short b, unsigned long addr); extern void outw(unsigned short b, unsigned long addr);
extern void outl(unsigned int b, unsigned long addr); extern void outl(unsigned int b, unsigned long addr);
/*
* String versions of in/out ops:
*/
extern void insw (unsigned long port, void *src, unsigned long count);
extern void insl (unsigned long port, void *src, unsigned long count);
extern void outsw (unsigned long port, void *dst, unsigned long count);
extern void outsl (unsigned long port, void *dst, unsigned long count);
extern unsigned long readb(unsigned long addr); extern unsigned long readb(unsigned long addr);
extern unsigned long readw(unsigned long addr); extern unsigned long readw(unsigned long addr);
...@@ -309,4 +319,10 @@ extern void writew(unsigned short b, unsigned long addr); ...@@ -309,4 +319,10 @@ extern void writew(unsigned short b, unsigned long addr);
extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end); extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end);
#endif #endif /* __KERNEL__ */
#define RTC_PORT(x) (0x70 + (x))
#define RTC_ADDR(x) (0x80 | (x))
#define RTC_ALWAYS_BCD 0
#endif /* __ALPHA_LCA__H */
#ifndef _ASMAXP_SHMPARAM_H
#define _ASMAXP_SHMPARAM_H
/*
* Address range for shared memory attaches if no address passed to
* shmat(). These ought to be changed to something >4GB so 32-bit
* errors are caught more easily. However, they don't seem to be used
* execept for ELF stuff, so it's not really critical until we get ELF
* support for the Alpha.
*/
#define SHM_RANGE_START 0x50000000
#define SHM_RANGE_END 0x60000000
/*
* Format of a swap-entry for shared memory pages currently out in
* swap space (see also mm/swap.c).
*
* SWP_TYPE = SHM_SWP_TYPE
* SWP_OFFSET is used as follows:
*
* bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
* bits 7..21: index of page within shared memory segment (SHM_IDX)
* (actually fewer bits get used since SHMMAX is so low)
*/
/*
* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
* there is a static array of size SHMMNI.
*/
#define _SHM_ID_BITS 7
#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)
#define SHM_IDX_SHIFT (_SHM_ID_BITS)
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
/*
* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the Alpha and
* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
*/
#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
#define SHMALL /* max shm system wide (pages) */ \
(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
#define SHMSEG SHMMNI /* max shared segs per process */
#endif /* _ASMAXP_SHMPARAM_H */
...@@ -60,6 +60,7 @@ struct ltchars { ...@@ -60,6 +60,7 @@ struct ltchars {
#define TIOCSWINSZ _IOW('t', 103, struct winsize) #define TIOCSWINSZ _IOW('t', 103, struct winsize)
#define TIOCGWINSZ _IOR('t', 104, struct winsize) #define TIOCGWINSZ _IOR('t', 104, struct winsize)
#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
#define TIOCGLTC _IOR('t', 116, struct ltchars) #define TIOCGLTC _IOR('t', 116, struct ltchars)
#define TIOCSLTC _IOW('t', 117, struct ltchars) #define TIOCSLTC _IOW('t', 117, struct ltchars)
...@@ -70,7 +71,6 @@ struct ltchars { ...@@ -70,7 +71,6 @@ struct ltchars {
#define TIOCNXCL 0x540D #define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E #define TIOCSCTTY 0x540E
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412 #define TIOCSTI 0x5412
#define TIOCMGET 0x5415 #define TIOCMGET 0x5415
#define TIOCMBIS 0x5416 #define TIOCMBIS 0x5416
......
...@@ -99,4 +99,57 @@ typedef unsigned long u64; ...@@ -99,4 +99,57 @@ typedef unsigned long u64;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#undef __FD_SET
static inline void __FD_SET(unsigned long fd, fd_set *fdsetp)
{
unsigned long _tmp = fd / __NFDBITS;
unsigned long _rem = fd % __NFDBITS;
fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
}
#undef __FD_CLR
static inline void __FD_CLR(unsigned long fd, fd_set *fdsetp)
{
unsigned long _tmp = fd / __NFDBITS;
unsigned long _rem = fd % __NFDBITS;
fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
}
#undef __FD_ISSET
static inline int __FD_ISSET(unsigned long fd, fd_set *p)
{
unsigned long _tmp = fd / __NFDBITS;
unsigned long _rem = fd % __NFDBITS;
return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
}
/*
* This will unroll the loop for the normal constant cases (4 or 8 longs,
* for 256 and 512-bit fd_sets respectively)
*/
#undef __FD_ZERO
static inline void __FD_ZERO(fd_set *p)
{
unsigned long *tmp = p->fds_bits;
int i;
if (__builtin_constant_p(__FDSET_LONGS)) {
switch (__FDSET_LONGS) {
case 8:
tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
return;
case 4:
tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
return;
}
}
i = __FDSET_LONGS;
while (i) {
i--;
*tmp = 0;
tmp++;
}
}
#endif #endif
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* yet. I'll have to see about this later.. * yet. I'll have to see about this later..
*/ */
#ifdef __LIBRARY__
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \ #define _syscall0(type,name) \
type name(void) \ type name(void) \
...@@ -46,8 +48,12 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ ...@@ -46,8 +48,12 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
return (type) -1; \ return (type) -1; \
} }
#endif /* __LIBRARY__ */
#ifdef __KERNEL_SYSCALLS__ #ifdef __KERNEL_SYSCALLS__
#include <linux/string.h>
extern unsigned long kernel_fork(void); extern unsigned long kernel_fork(void);
static inline unsigned long fork(void) static inline unsigned long fork(void)
{ {
......
#ifndef __I386_A_OUT_H__
#define __I386_A_OUT_H__
struct exec
{
unsigned long a_info; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
unsigned a_syms; /* length of symbol table data in file, in bytes */
unsigned a_entry; /* start address */
unsigned a_trsize; /* length of relocation info for text, in bytes */
unsigned a_drsize; /* length of relocation info for data, in bytes */
};
#define N_TRSIZE(a) ((a).a_trsize)
#define N_DRSIZE(a) ((a).a_drsize)
#define N_SYMSIZE(a) ((a).a_syms)
#ifdef __KERNEL__
#define STACK_TOP TASK_SIZE
#endif
#endif /* __A_OUT_GNU_H__ */
#ifndef _I386_CHECKSUM_H
#define _I386_CHECKSUM_H
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
/*
* the same as csum_partial, but copies from fs:src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum);
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*
* By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
* Arnt Gulbrandsen.
*/
static inline unsigned short ip_fast_csum(unsigned char * iph,
unsigned int ihl) {
unsigned short int sum;
__asm__("
movl (%%esi), %%eax
andl $15, %%ecx
subl $4, %%ecx
jbe 2f
addl 4(%%esi), %%eax
adcl 8(%%esi), %%eax
adcl 12(%%esi), %%eax
1: adcl 16(%%esi), %%eax
lea 4(%%esi), %%esi
decl %%ecx
jne 1b
adcl $0, %%eax
movl %%eax, %%ecx
shrl $16, %%eax
addw %%ecx, %%eax
adcl $0, %%eax
notl %%eax
andl $65535, %%eax
2:
"
: "=a" (sum)
: "S" (iph), "c"(ihl)
: "ax", "cx", "si");
return(sum);
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
unsigned int sum) {
__asm__("
addl %2, %0
adcl %3, %0
adcl %4, %0
adcl $0, %0
movl %0, %2
shrl $16, %2
addw %2, %0
adcl $0, %0
notl %0
andl $65535, %0
"
: "=r" (sum)
: "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
: "si" );
return((unsigned short)sum);
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
unsigned short int sum;
__asm__("
movl %%eax, %%ecx
shrl $16, %%ecx
addw %%cx, %%ax
adcl $0, %%eax
notl %%eax
andl $65535, %%eax
"
: "=a"(sum)
: "a" (csum_partial(buff, len, 0))
: "cx");
return(sum);
}
#endif
...@@ -132,4 +132,12 @@ static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsign ...@@ -132,4 +132,12 @@ static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsign
regs->esp = esp; regs->esp = esp;
} }
/*
* Return saved PC of a blocked thread.
*/
extern inline unsigned long thread_saved_pc(struct thread_struct *t)
{
return ((unsigned long *)t->esp)[3];
}
#endif /* __ASM_I386_PROCESSOR_H */ #endif /* __ASM_I386_PROCESSOR_H */
...@@ -42,7 +42,7 @@ static inline void __put_user(unsigned long x, void * y, int size) ...@@ -42,7 +42,7 @@ static inline void __put_user(unsigned long x, void * y, int size)
case 2: case 2:
__asm__ ("movw %w1,%%fs:%0" __asm__ ("movw %w1,%%fs:%0"
:"=m" (*__sd(y)) :"=m" (*__sd(y))
:"iq" ((unsigned short) x), "m" (*__sd(y))); :"ir" ((unsigned short) x), "m" (*__sd(y)));
break; break;
case 4: case 4:
__asm__ ("movl %1,%%fs:%0" __asm__ ("movl %1,%%fs:%0"
...@@ -66,7 +66,7 @@ static inline unsigned long __get_user(const void * y, int size) ...@@ -66,7 +66,7 @@ static inline unsigned long __get_user(const void * y, int size)
return (unsigned char) result; return (unsigned char) result;
case 2: case 2:
__asm__ ("movw %%fs:%1,%w0" __asm__ ("movw %%fs:%1,%w0"
:"=q" (result) :"=r" (result)
:"m" (*__sd(y))); :"m" (*__sd(y)));
return (unsigned short) result; return (unsigned short) result;
case 4: case 4:
...@@ -249,7 +249,7 @@ static inline void __constant_memcpy_fromfs(void * to, const void * from, unsign ...@@ -249,7 +249,7 @@ static inline void __constant_memcpy_fromfs(void * to, const void * from, unsign
case 12: case 12:
*(int *) to = __get_user((const int *) from, 4); *(int *) to = __get_user((const int *) from, 4);
*(1+(int *) to) = __get_user(1+(const int *) from, 4); *(1+(int *) to) = __get_user(1+(const int *) from, 4);
*(1+(int *) to) = __get_user(2+(const int *) from, 4); *(2+(int *) to) = __get_user(2+(const int *) from, 4);
return; return;
case 16: case 16:
*(int *) to = __get_user((const int *) from, 4); *(int *) to = __get_user((const int *) from, 4);
......
#ifndef _ASMI386_SHMPARAM_H
#define _ASMI386_SHMPARAM_H
/* address range for shared memory attaches if no address passed to shmat() */
#define SHM_RANGE_START 0x50000000
#define SHM_RANGE_END 0x60000000
/*
* Format of a swap-entry for shared memory pages currently out in
* swap space (see also mm/swap.c).
*
* SWP_TYPE = SHM_SWP_TYPE
* SWP_OFFSET is used as follows:
*
* bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
* bits 7..21: index of page within shared memory segment (SHM_IDX)
* (actually fewer bits get used since SHMMAX is so low)
*/
/*
* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
* there is a static array of size SHMMNI.
*/
#define _SHM_ID_BITS 7
#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)
#define SHM_IDX_SHIFT (_SHM_ID_BITS)
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
/*
* _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
* SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
*/
#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
#define SHMALL /* max shm system wide (pages) */ \
(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
#define SHMSEG SHMMNI /* max shared segs per process */
#endif /* _ASMI386_SHMPARAM_H */
...@@ -75,4 +75,29 @@ typedef unsigned long long u64; ...@@ -75,4 +75,29 @@ typedef unsigned long long u64;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#undef __FD_SET
#define __FD_SET(fd,fdsetp) \
__asm__ __volatile__("btsl %1,%0": \
"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
#undef __FD_CLR
#define __FD_CLR(fd,fdsetp) \
__asm__ __volatile__("btrl %1,%0": \
"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
#undef __FD_ISSET
#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
unsigned char __result; \
__asm__ __volatile__("btl %1,%2 ; setb %0" \
:"=q" (__result) :"r" ((int) (fd)), \
"m" (*(fd_set *) (fdsetp))); \
__result; }))
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) \
__asm__ __volatile__("cld ; rep ; stosl" \
:"=m" (*(fd_set *) (fdsetp)) \
:"a" (0), "c" (__FDSET_LONGS), \
"D" ((fd_set *) (fdsetp)) :"cx","di")
#endif #endif
...@@ -5,17 +5,7 @@ ...@@ -5,17 +5,7 @@
#ifndef __STRUCT_EXEC_OVERRIDE__ #ifndef __STRUCT_EXEC_OVERRIDE__
struct exec #include <asm/a.out.h>
{
unsigned long a_info; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
unsigned a_syms; /* length of symbol table data in file, in bytes */
unsigned a_entry; /* start address */
unsigned a_trsize; /* length of relocation info for text, in bytes */
unsigned a_drsize; /* length of relocation info for data, in bytes */
};
#endif /* __STRUCT_EXEC_OVERRIDE__ */ #endif /* __STRUCT_EXEC_OVERRIDE__ */
...@@ -137,7 +127,11 @@ enum machine_type { ...@@ -137,7 +127,11 @@ enum machine_type {
#ifdef linux #ifdef linux
#include <asm/page.h> #include <asm/page.h>
#ifdef __i386__
#define SEGMENT_SIZE 1024 #define SEGMENT_SIZE 1024
#else
#define SEGMENT_SIZE PAGE_SIZE
#endif
#endif #endif
#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) #define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
......
...@@ -21,7 +21,8 @@ struct linux_binprm{ ...@@ -21,7 +21,8 @@ struct linux_binprm{
struct inode * inode; struct inode * inode;
int e_uid, e_gid; int e_uid, e_gid;
int argc, envc; int argc, envc;
char * filename; /* Name of binary */ char * filename; /* Name of binary */
unsigned long loader, exec;
}; };
/* /*
...@@ -40,13 +41,13 @@ extern int register_binfmt(struct linux_binfmt *); ...@@ -40,13 +41,13 @@ extern int register_binfmt(struct linux_binfmt *);
extern int unregister_binfmt(struct linux_binfmt *); extern int unregister_binfmt(struct linux_binfmt *);
extern int read_exec(struct inode *inode, unsigned long offset, extern int read_exec(struct inode *inode, unsigned long offset,
char * addr, unsigned long count); char * addr, unsigned long count, int to_kmem);
extern int open_inode(struct inode * inode, int mode); extern int open_inode(struct inode * inode, int mode);
extern void flush_old_exec(struct linux_binprm * bprm); extern void flush_old_exec(struct linux_binprm * bprm);
extern unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page); extern unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page);
extern unsigned long * create_tables(char * p,int argc,int envc,int ibcs); extern unsigned long * create_tables(char * p,struct linux_binprm * bprm,int ibcs);
extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page, extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem); unsigned long p, int from_kmem);
......
...@@ -57,4 +57,5 @@ extern int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, ...@@ -57,4 +57,5 @@ extern int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
extern pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, extern pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned int val); unsigned char where, unsigned int val);
extern char *pcibios_strerror (int error); extern char *pcibios_strerror (int error);
#endif /* BIOS32_H */ #endif /* BIOS32_H */
...@@ -33,11 +33,14 @@ ...@@ -33,11 +33,14 @@
#define IOCBASECMD(cmd) ((cmd) & ~IOCPARM_MASK) #define IOCBASECMD(cmd) ((cmd) & ~IOCPARM_MASK)
#define IOCGROUP(cmd) (((cmd) >> 8) & 0xFF) #define IOCGROUP(cmd) (((cmd) >> 8) & 0xFF)
#ifndef _IO
/* _IO(magic, subcode); size field is zero and the /* _IO(magic, subcode); size field is zero and the
* subcode determines the command. * subcode determines the command.
*/ */
#define _IO(c,d) (IOC_VOID | ((c)<<8) | (d)) /* param encoded */ #define _IO(c,d) (IOC_VOID | ((c)<<8) | (d)) /* param encoded */
#endif
#ifndef _IOW
/* _IOXX(magic, subcode, arg_t); where arg_t is the type of the /* _IOXX(magic, subcode, arg_t); where arg_t is the type of the
* (last) argument field in the ioctl call, if present. * (last) argument field in the ioctl call, if present.
*/ */
...@@ -48,6 +51,7 @@ ...@@ -48,6 +51,7 @@
/* WR rather than RW to avoid conflict with stdio.h */ /* WR rather than RW to avoid conflict with stdio.h */
#define _IOWR(c,d,t) (IOC_INOUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ #define _IOWR(c,d,t) (IOC_INOUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \
((c)<<8) | (d)) ((c)<<8) | (d))
#endif /* !_IOW */
#endif /* _LINUX_IOCTL_H */ #endif /* _LINUX_IOCTL_H */
...@@ -67,6 +67,12 @@ struct msg { ...@@ -67,6 +67,12 @@ struct msg {
#define MSG_STAT 11 #define MSG_STAT 11
#define MSG_INFO 12 #define MSG_INFO 12
extern asmlinkage int sys_msgget (key_t key, int msgflg);
extern asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
extern asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp,
int msgflg);
extern asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_MSG_H */ #endif /* _LINUX_MSG_H */
...@@ -113,7 +113,7 @@ struct fs_struct { ...@@ -113,7 +113,7 @@ struct fs_struct {
struct mm_struct { struct mm_struct {
int count; int count;
unsigned long start_code, end_code, end_data; unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack, start_mmap; unsigned long start_brk, brk, start_stack, start_mmap;
unsigned long arg_start, arg_end, env_start, env_end; unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss; unsigned long rss;
...@@ -129,7 +129,7 @@ struct mm_struct { ...@@ -129,7 +129,7 @@ struct mm_struct {
#define INIT_MM { \ #define INIT_MM { \
0, \ 0, \
0, 0, 0, \ 0, 0, 0, 0, \
0, 0, 0, 0, \ 0, 0, 0, 0, \
0, 0, 0, 0, \ 0, 0, 0, 0, \
0, \ 0, \
...@@ -280,7 +280,6 @@ extern void exit_thread(void); ...@@ -280,7 +280,6 @@ extern void exit_thread(void);
extern int do_execve(char *, char **, char **, struct pt_regs *); extern int do_execve(char *, char **, char **, struct pt_regs *);
extern int do_fork(unsigned long, unsigned long, struct pt_regs *); extern int do_fork(unsigned long, unsigned long, struct pt_regs *);
asmlinkage int do_signal(unsigned long, struct pt_regs *);
/* /*
* The wait-queues are circular lists, and you have to be *very* sure * The wait-queues are circular lists, and you have to be *very* sure
...@@ -293,10 +292,11 @@ extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wa ...@@ -293,10 +292,11 @@ extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wa
#ifdef DEBUG #ifdef DEBUG
if (wait->next) { if (wait->next) {
__label__ here;
unsigned long pc; unsigned long pc;
__asm__ __volatile__("call 1f\n" pc = (unsigned long) &&here;
"1:\tpopl %0":"=r" (pc)); here:
printk("add_wait_queue (%08x): wait->next = %08x\n",pc,(unsigned long) wait->next); printk("add_wait_queue (%08lx): wait->next = %08lx\n",pc,(unsigned long) wait->next);
} }
#endif #endif
save_flags(flags); save_flags(flags);
...@@ -342,10 +342,12 @@ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * ...@@ -342,10 +342,12 @@ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue *
restore_flags(flags); restore_flags(flags);
#ifdef DEBUG #ifdef DEBUG
if (!ok) { if (!ok) {
__label__ here;
ok = (unsigned long) &&here;
printk("removed wait_queue not on list.\n"); printk("removed wait_queue not on list.\n");
printk("list = %08x, queue = %08x\n",(unsigned long) p, (unsigned long) wait); printk("list = %08lx, queue = %08lx\n",(unsigned long) p, (unsigned long) wait);
__asm__("call 1f\n1:\tpopl %0":"=r" (ok)); here:
printk("eip = %08x\n",ok); printk("eip = %08lx\n",ok);
} }
#endif #endif
} }
......
...@@ -103,6 +103,10 @@ struct sem_undo { ...@@ -103,6 +103,10 @@ struct sem_undo {
short * semadj; /* array of adjustments, one per semaphore */ short * semadj; /* array of adjustments, one per semaphore */
}; };
extern asmlinkage int sys_semget (key_t key, int nsems, int semflg);
extern asmlinkage int sys_semop (int semid, struct sembuf *sops, unsigned nsops);
extern asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_SEM_H */ #endif /* _LINUX_SEM_H */
#ifndef _LINUX_SHM_H_ #ifndef _LINUX_SHM_H_
#define _LINUX_SHM_H_ #define _LINUX_SHM_H_
#include <linux/ipc.h> #include <linux/ipc.h>
#include <asm/shmparam.h>
struct shmid_ds { struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */ struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */ int shm_segsz; /* size of segment (bytes) */
...@@ -38,40 +41,6 @@ struct shminfo { ...@@ -38,40 +41,6 @@ struct shminfo {
int shmall; int shmall;
}; };
/* address range for shared memory attaches if no address passed to shmat() */
#define SHM_RANGE_START 0x50000000
#define SHM_RANGE_END 0x60000000
/* format of page table entries that correspond to shared memory pages
currently out in swap space (see also mm/swap.c):
bit 0 (PAGE_PRESENT) is = 0
bits 7..1 (SWP_TYPE) are = SHM_SWP_TYPE
bits 31..8 are used like this:
bits 14..8 (SHM_ID) the id of the shared memory segment
bits 29..15 (SHM_IDX) the index of the page within the shared memory segment
(actually only bits 24..15 get used since SHMMAX is so low)
*/
#define SHM_ID_SHIFT 8
/* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
there is a static array of size SHMMNI. */
#define _SHM_ID_BITS 7
#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)
#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS)
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
/* We must have SHM_ID_SHIFT + _SHM_ID_BITS + _SHM_IDX_BITS <= 32
and SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). */
#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
#define SHMALL (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))/* max shm system wide (pages) */
#define SHMLBA 0x1000 /* attach addr a multiple of this */
#define SHMSEG SHMMNI /* max shared segs per process */
#ifdef __KERNEL__ #ifdef __KERNEL__
/* shm_mode upper byte flags */ /* shm_mode upper byte flags */
...@@ -90,6 +59,11 @@ struct shm_info { ...@@ -90,6 +59,11 @@ struct shm_info {
ulong swap_successes; ulong swap_successes;
}; };
extern asmlinkage int sys_shmget (key_t key, int size, int flag);
extern asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr);
extern asmlinkage int sys_shmdt (char *shmaddr);
extern asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_SHM_H_ */ #endif /* _LINUX_SHM_H_ */
......
#ifndef _LINUX_SWAP_H
#define _LINUX_SWAP_H
#define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */
#define SWAP_FLAG_PRIO_MASK 0x7fff
#define SWAP_FLAG_PRIO_SHIFT 0
#endif /* _LINUX_SWAP_H */
...@@ -2,257 +2,6 @@ ...@@ -2,257 +2,6 @@
#define _LINUX_TERMIOS_H #define _LINUX_TERMIOS_H
#include <linux/types.h> #include <linux/types.h>
#include <asm/termios.h>
/* 0x54 is just a magic number to make these relatively unique ('T') */
#define TCGETS 0x5401
#define TCSETS 0x5402
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TCGETA 0x5405
#define TCSETA 0x5406
#define TCSETAW 0x5407
#define TCSETAF 0x5408
#define TCSBRK 0x5409
#define TCXONC 0x540A
#define TCFLSH 0x540B
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define FIONREAD 0x541B
#define TIOCINQ FIONREAD
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define FIONBIO 0x5421
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
};
#define NCC 8
struct termio {
unsigned short c_iflag; /* input mode flags */
unsigned short c_oflag; /* output mode flags */
unsigned short c_cflag; /* control mode flags */
unsigned short c_lflag; /* local mode flags */
unsigned char c_line; /* line discipline */
unsigned char c_cc[NCC]; /* control characters */
};
#define NCCS 19
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
/* c_cc characters */
#define VINTR 0
#define VQUIT 1
#define VERASE 2
#define VKILL 3
#define VEOF 4
#define VTIME 5
#define VMIN 6
#define VSWTC 7
#define VSTART 8
#define VSTOP 9
#define VSUSP 10
#define VEOL 11
#define VREPRINT 12
#define VDISCARD 13
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
/* c_iflag bits */
#define IGNBRK 0000001
#define BRKINT 0000002
#define IGNPAR 0000004
#define PARMRK 0000010
#define INPCK 0000020
#define ISTRIP 0000040
#define INLCR 0000100
#define IGNCR 0000200
#define ICRNL 0000400
#define IUCLC 0001000
#define IXON 0002000
#define IXANY 0004000
#define IXOFF 0010000
#define IMAXBEL 0020000
/* c_oflag bits */
#define OPOST 0000001
#define OLCUC 0000002
#define ONLCR 0000004
#define OCRNL 0000010
#define ONOCR 0000020
#define ONLRET 0000040
#define OFILL 0000100
#define OFDEL 0000200
#define NLDLY 0000400
#define NL0 0000000
#define NL1 0000400
#define CRDLY 0003000
#define CR0 0000000
#define CR1 0001000
#define CR2 0002000
#define CR3 0003000
#define TABDLY 0014000
#define TAB0 0000000
#define TAB1 0004000
#define TAB2 0010000
#define TAB3 0014000
#define XTABS 0014000
#define BSDLY 0020000
#define BS0 0000000
#define BS1 0020000
#define VTDLY 0040000
#define VT0 0000000
#define VT1 0040000
#define FFDLY 0100000
#define FF0 0000000
#define FF1 0100000
/* c_cflag bit meaning */
#define CBAUD 0010017
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#define EXTA B19200
#define EXTB B38400
#define CSIZE 0000060
#define CS5 0000000
#define CS6 0000020
#define CS7 0000040
#define CS8 0000060
#define CSTOPB 0000100
#define CREAD 0000200
#define PARENB 0000400
#define PARODD 0001000
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
#define XCASE 0000004
#define ECHO 0000010
#define ECHOE 0000020
#define ECHOK 0000040
#define ECHONL 0000100
#define NOFLSH 0000200
#define TOSTOP 0000400
#define ECHOCTL 0001000
#define ECHOPRT 0002000
#define ECHOKE 0004000
#define FLUSHO 0010000
#define PENDIN 0040000
#define IEXTEN 0100000
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
/* tcflow() and TCXONC use these */
#define TCOOFF 0
#define TCOON 1
#define TCIOFF 2
#define TCION 3
/* tcflush() and TCFLSH use these */
#define TCIFLUSH 0
#define TCOFLUSH 1
#define TCIOFLUSH 2
/* tcsetattr uses these */
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
/* line disciplines */
#define N_TTY 0
#define N_SLIP 1
#define N_MOUSE 2
#define N_PPP 3
#endif #endif
...@@ -15,20 +15,13 @@ struct timezone { ...@@ -15,20 +15,13 @@ struct timezone {
#ifdef __KERNEL__ #ifdef __KERNEL__
void do_gettimeofday(struct timeval *tv); void do_gettimeofday(struct timeval *tv);
#include <asm/bitops.h> #endif
#include <linux/string.h>
#define FD_SETSIZE __FD_SETSIZE
#define FD_SET(fd,fdsetp) set_bit(fd,fdsetp)
#define FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp)
#define FD_ISSET(fd,fdsetp) (0 != test_bit(fd,fdsetp))
#define FD_ZERO(fdsetp) memset(fdsetp, 0, sizeof(struct fd_set))
#else
#define FD_SETSIZE __FD_SETSIZE #define FD_SETSIZE __FD_SETSIZE
#define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp) #define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp)
#define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp) #define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp)
#define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp) #define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO(fdsetp) #define FD_ZERO(fdsetp) __FD_ZERO(fdsetp)
#endif
/* /*
* Names of the interval timers, and structure * Names of the interval timers, and structure
......
...@@ -269,14 +269,6 @@ extern struct tty_ldisc ldiscs[]; ...@@ -269,14 +269,6 @@ extern struct tty_ldisc ldiscs[];
extern int fg_console; extern int fg_console;
extern struct wait_queue * keypress_wait; extern struct wait_queue * keypress_wait;
/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
reprint=^R discard=^U werase=^W lnext=^V
eol2=\0
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
extern long rs_init(long); extern long rs_init(long);
extern long lp_init(long); extern long lp_init(long);
extern long con_init(long); extern long con_init(long);
......
#ifndef _LINUX_TYPES_H #ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H #define _LINUX_TYPES_H
#include <asm/types.h>
#ifndef NULL
#define NULL ((void *) 0)
#endif
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define _LOFF_T
typedef long long loff_t;
#endif
/* bsd */
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
/* sysv */
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef char *caddr_t;
typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;
/* /*
* This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
* you'll have to change this too. But 256 fd's seem to be enough even for such * you'll have to change this too. But 256 fd's seem to be enough even for such
...@@ -46,7 +17,7 @@ typedef unsigned int tcflag_t; ...@@ -46,7 +17,7 @@ typedef unsigned int tcflag_t;
* use the ones here. * use the ones here.
*/ */
#undef __FDSET_LONGS #undef __FDSET_LONGS
#define __FDSET_LONGS 8 #define __FDSET_LONGS (256/(8*sizeof(unsigned long)))
typedef struct fd_set { typedef struct fd_set {
unsigned long fds_bits [__FDSET_LONGS]; unsigned long fds_bits [__FDSET_LONGS];
...@@ -58,30 +29,34 @@ typedef struct fd_set { ...@@ -58,30 +29,34 @@ typedef struct fd_set {
#undef __FD_SETSIZE #undef __FD_SETSIZE
#define __FD_SETSIZE (__FDSET_LONGS*__NFDBITS) #define __FD_SETSIZE (__FDSET_LONGS*__NFDBITS)
#undef __FD_SET #include <asm/types.h>
#define __FD_SET(fd,fdsetp) \
__asm__ __volatile__("btsl %1,%0": \
"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
#undef __FD_CLR #ifndef NULL
#define __FD_CLR(fd,fdsetp) \ #define NULL ((void *) 0)
__asm__ __volatile__("btrl %1,%0": \ #endif
"=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
#undef __FD_ISSET #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ #define _LOFF_T
unsigned char __result; \ typedef long long loff_t;
__asm__ __volatile__("btl %1,%2 ; setb %0" \ #endif
:"=q" (__result) :"r" ((int) (fd)), \
"m" (*(fd_set *) (fdsetp))); \
__result; }))
#undef __FD_ZERO /* bsd */
#define __FD_ZERO(fdsetp) \ typedef unsigned char u_char;
__asm__ __volatile__("cld ; rep ; stosl" \ typedef unsigned short u_short;
:"=m" (*(fd_set *) (fdsetp)) \ typedef unsigned int u_int;
:"a" (0), "c" (__FDSET_LONGS), \ typedef unsigned long u_long;
"D" ((fd_set *) (fdsetp)) :"cx","di")
/* sysv */
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef char *caddr_t;
typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;
struct ustat { struct ustat {
daddr_t f_tfree; daddr_t f_tfree;
......
...@@ -19,140 +19,7 @@ ...@@ -19,140 +19,7 @@
#define _CHECKSUM_H #define _CHECKSUM_H
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include "ip.h" #include <net/ip.h>
#include <asm/checksum.h>
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*
* By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
* Arnt Gulbrandsen.
*/
static inline unsigned short ip_fast_csum(unsigned char * iph,
unsigned int ihl) {
unsigned short int sum;
#ifdef __i386__
__asm__("
movl (%%esi), %%eax
andl $15, %%ecx
subl $4, %%ecx
jbe 2f
addl 4(%%esi), %%eax
adcl 8(%%esi), %%eax
adcl 12(%%esi), %%eax
1: adcl 16(%%esi), %%eax
lea 4(%%esi), %%esi
decl %%ecx
jne 1b
adcl $0, %%eax
movl %%eax, %%ecx
shrl $16, %%eax
addw %%ecx, %%eax
adcl $0, %%eax
notl %%eax
andl $65535, %%eax
2:
"
: "=a" (sum)
: "S" (iph), "c"(ihl)
: "ax", "cx", "si");
#else
#error Not implemented for this CPU
#endif
return(sum);
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
unsigned int sum) {
#ifdef __i386__
__asm__("
addl %2, %0
adcl %3, %0
adcl %4, %0
adcl $0, %0
movl %0, %2
shrl $16, %2
addw %2, %0
adcl $0, %0
notl %0
andl $65535, %0
"
: "=r" (sum)
: "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
: "si" );
#else
#error Not implemented for this CPU
#endif
return((unsigned short)sum);
}
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
/*
* the same as csum_partial, but copies from fs:src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
unsigned int csum_partial_copyffs( char *src, char *dst, int len, int sum);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
unsigned short int sum;
#ifdef __i386__
__asm__("
movl %%eax, %%ecx
shrl $16, %%ecx
addw %%cx, %%ax
adcl $0, %%eax
notl %%eax
andl $65535, %%eax
"
: "=a"(sum)
: "a" (csum_partial(buff, len, 0))
: "cx");
#else
#error Not implemented for this CPU
#endif
return(sum);
}
#endif #endif
...@@ -97,20 +97,19 @@ extern void time_init(void); ...@@ -97,20 +97,19 @@ extern void time_init(void);
static unsigned long memory_start = 0; static unsigned long memory_start = 0;
static unsigned long memory_end = 0; static unsigned long memory_end = 0;
static char term[21];
int rows, cols; int rows, cols;
int ramdisk_size; int ramdisk_size;
int root_mountflags = 0; int root_mountflags = 0;
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", term, NULL, }; static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static char * argv_rc[] = { "/bin/sh", NULL }; static char * argv_rc[] = { "/bin/sh", NULL };
static char * envp_rc[] = { "HOME=/", term, NULL }; static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL };
static char * argv[] = { "-/bin/sh",NULL }; static char * argv[] = { "-/bin/sh",NULL };
static char * envp[] = { "HOME=/usr/root", term, NULL }; static char * envp[] = { "HOME=/usr/root", "TERM=linux", NULL };
char *get_options(char *str, int *ints) char *get_options(char *str, int *ints)
{ {
...@@ -272,14 +271,14 @@ static void calibrate_delay(void) ...@@ -272,14 +271,14 @@ static void calibrate_delay(void)
static void parse_options(char *line) static void parse_options(char *line)
{ {
char *next; char *next;
char *devnames[] = { "hda", "hdb", "hdc", "hdd", "sda", "sdb", "sdc", "sdd", "sde", "fd", "xda", "xdb", NULL }; static char *devnames[] = { "hda", "hdb", "hdc", "hdd", "sda", "sdb", "sdc", "sdd", "sde", "fd", "xda", "xdb", NULL };
int devnums[] = { 0x300, 0x340, 0x1600, 0x1640, 0x800, 0x810, 0x820, 0x830, 0x840, 0x200, 0xD00, 0xD40, 0}; static int devnums[] = { 0x300, 0x340, 0x1600, 0x1640, 0x800, 0x810, 0x820, 0x830, 0x840, 0x200, 0xD00, 0xD40, 0};
int args, envs; int args, envs;
if (!*line) if (!*line)
return; return;
args = 0; args = 0;
envs = 1; /* TERM is set to 'console' by default */ envs = 1; /* TERM is set to 'linux' by default */
next = line; next = line;
while ((line = next) != NULL) { while ((line = next) != NULL) {
if ((next = strchr(line,' ')) != NULL) if ((next = strchr(line,' ')) != NULL)
...@@ -422,7 +421,6 @@ void init(void) ...@@ -422,7 +421,6 @@ void init(void)
int pid,i; int pid,i;
setup(); setup();
sprintf(term, "TERM=con%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);
#ifdef CONFIG_UMSDOS_FS #ifdef CONFIG_UMSDOS_FS
{ {
......
...@@ -36,7 +36,7 @@ void msg_init (void) ...@@ -36,7 +36,7 @@ void msg_init (void)
return; return;
} }
int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg) asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
{ {
int id, err; int id, err;
struct msqid_ds *msq; struct msqid_ds *msq;
...@@ -44,7 +44,7 @@ int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg) ...@@ -44,7 +44,7 @@ int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg)
struct msg *msgh; struct msg *msgh;
long mtype; long mtype;
if (msgsz > MSGMAX || msgsz < 0 || msqid < 0) if (msgsz > MSGMAX || (long) msgsz < 0 || msqid < 0)
return -EINVAL; return -EINVAL;
if (!msgp) if (!msgp)
return -EFAULT; return -EFAULT;
...@@ -108,7 +108,7 @@ int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg) ...@@ -108,7 +108,7 @@ int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg)
return msgsz; return msgsz;
} }
int sys_msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp,
int msgflg) int msgflg)
{ {
struct msqid_ds *msq; struct msqid_ds *msq;
...@@ -117,7 +117,7 @@ int sys_msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, ...@@ -117,7 +117,7 @@ int sys_msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp,
struct msg *nmsg = NULL; struct msg *nmsg = NULL;
int id, err; int id, err;
if (msqid < 0 || msgsz < 0) if (msqid < 0 || (long) msgsz < 0)
return -EINVAL; return -EINVAL;
if (!msgp || !msgp->mtext) if (!msgp || !msgp->mtext)
return -EFAULT; return -EFAULT;
...@@ -267,7 +267,7 @@ static int newque (key_t key, int msgflg) ...@@ -267,7 +267,7 @@ static int newque (key_t key, int msgflg)
return (unsigned int) msq->msg_perm.seq * MSGMNI + id; return (unsigned int) msq->msg_perm.seq * MSGMNI + id;
} }
int sys_msgget (key_t key, int msgflg) asmlinkage int sys_msgget (key_t key, int msgflg)
{ {
int id; int id;
struct msqid_ds *msq; struct msqid_ds *msq;
...@@ -316,7 +316,7 @@ static void freeque (int id) ...@@ -316,7 +316,7 @@ static void freeque (int id)
kfree(msq); kfree(msq);
} }
int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
{ {
int id, err; int id, err;
struct msqid_ds *msq; struct msqid_ds *msq;
......
...@@ -129,7 +129,7 @@ static int newary (key_t key, int nsems, int semflg) ...@@ -129,7 +129,7 @@ static int newary (key_t key, int nsems, int semflg)
return (unsigned int) sma->sem_perm.seq * SEMMNI + id; return (unsigned int) sma->sem_perm.seq * SEMMNI + id;
} }
int sys_semget (key_t key, int nsems, int semflg) asmlinkage int sys_semget (key_t key, int nsems, int semflg)
{ {
int id; int id;
struct semid_ds *sma; struct semid_ds *sma;
...@@ -357,7 +357,7 @@ static void freeary (int id) ...@@ -357,7 +357,7 @@ static void freeary (int id)
kfree(sma); kfree(sma);
} }
int sys_semctl (int semid, int semnum, int cmd, union semun arg) asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
{ {
struct semid_ds *buf = NULL; struct semid_ds *buf = NULL;
struct semid_ds tbuf; struct semid_ds tbuf;
...@@ -554,7 +554,7 @@ int sys_semctl (int semid, int semnum, int cmd, union semun arg) ...@@ -554,7 +554,7 @@ int sys_semctl (int semid, int semnum, int cmd, union semun arg)
return 0; return 0;
} }
int sys_semop (int semid, struct sembuf *tsops, unsigned nsops) asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
{ {
int i, id, size, error; int i, id, size, error;
struct semid_ds *sma; struct semid_ds *sma;
......
...@@ -129,7 +129,7 @@ static int newseg (key_t key, int shmflg, int size) ...@@ -129,7 +129,7 @@ static int newseg (key_t key, int shmflg, int size)
return (unsigned int) shp->shm_perm.seq * SHMMNI + id; return (unsigned int) shp->shm_perm.seq * SHMMNI + id;
} }
int sys_shmget (key_t key, int size, int shmflg) asmlinkage int sys_shmget (key_t key, int size, int shmflg)
{ {
struct shmid_ds *shp; struct shmid_ds *shp;
int id = 0; int id = 0;
...@@ -199,7 +199,7 @@ static void killseg (int id) ...@@ -199,7 +199,7 @@ static void killseg (int id)
return; return;
} }
int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
{ {
struct shmid_ds tbuf; struct shmid_ds tbuf;
struct shmid_ds *shp; struct shmid_ds *shp;
...@@ -392,7 +392,7 @@ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct * ...@@ -392,7 +392,7 @@ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct *
if (shmd->vm_next_share == shmd) { if (shmd->vm_next_share == shmd) {
if (shp->attaches != shmd) { if (shp->attaches != shmd) {
printk("shm_close: shm segment (id=%ld) attach list inconsistent\n", printk("shm_close: shm segment (id=%ld) attach list inconsistent\n",
(shmd->vm_pte >> SHM_ID_SHIFT) & SHM_ID_MASK); SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK);
printk("shm_close: %d %08lx-%08lx %c%c%c%c %08lx %08lx\n", printk("shm_close: %d %08lx-%08lx %c%c%c%c %08lx %08lx\n",
shmd->vm_task->pid, shmd->vm_start, shmd->vm_end, shmd->vm_task->pid, shmd->vm_start, shmd->vm_end,
shmd->vm_flags & VM_READ ? 'r' : '-', shmd->vm_flags & VM_READ ? 'r' : '-',
...@@ -429,9 +429,12 @@ static int shm_map (struct vm_area_struct *shmd) ...@@ -429,9 +429,12 @@ static int shm_map (struct vm_area_struct *shmd)
merge_segments(current, shmd->vm_start, shmd->vm_end); merge_segments(current, shmd->vm_start, shmd->vm_end);
/* map page range */ /* map page range */
shm_sgn = shmd->vm_pte + ((shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT); shm_sgn = shmd->vm_pte +
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE, SWP_ENTRY(0, (shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT);
shm_sgn += (1 << SHM_IDX_SHIFT)) { for (tmp = shmd->vm_start;
tmp < shmd->vm_end;
tmp += PAGE_SIZE, shm_sgn += SWP_ENTRY(0, 1 << SHM_IDX_SHIFT))
{
page_dir = pgd_offset(shmd->vm_task,tmp); page_dir = pgd_offset(shmd->vm_task,tmp);
page_middle = pmd_alloc(page_dir,tmp); page_middle = pmd_alloc(page_dir,tmp);
if (!page_middle) if (!page_middle)
...@@ -448,7 +451,7 @@ static int shm_map (struct vm_area_struct *shmd) ...@@ -448,7 +451,7 @@ static int shm_map (struct vm_area_struct *shmd)
/* /*
* Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists. * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
*/ */
int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
{ {
struct shmid_ds *shp; struct shmid_ds *shp;
struct vm_area_struct *shmd; struct vm_area_struct *shmd;
...@@ -478,7 +481,13 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -478,7 +481,13 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
else else
return -EINVAL; return -EINVAL;
} }
if ((addr > current->mm->start_stack - 16384 - PAGE_SIZE*shp->shm_npages)) { /*
* If shm segment goes below stack, make sure there is some
* space left for the stack to grow (presently 4 pages).
*/
if (addr < current->mm->start_stack &&
addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
{
/* printk("shmat() -> EINVAL because segment intersects stack\n"); */ /* printk("shmat() -> EINVAL because segment intersects stack\n"); */
return -EINVAL; return -EINVAL;
} }
...@@ -538,7 +547,7 @@ static void shm_open (struct vm_area_struct *shmd) ...@@ -538,7 +547,7 @@ static void shm_open (struct vm_area_struct *shmd)
unsigned int id; unsigned int id;
struct shmid_ds *shp; struct shmid_ds *shp;
id = (shmd->vm_pte >> SHM_ID_SHIFT) & SHM_ID_MASK; id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
shp = shm_segs[id]; shp = shm_segs[id];
if (shp == IPC_UNUSED) { if (shp == IPC_UNUSED) {
printk("shm_open: unused id=%d PANIC\n", id); printk("shm_open: unused id=%d PANIC\n", id);
...@@ -564,7 +573,7 @@ static void shm_close (struct vm_area_struct *shmd) ...@@ -564,7 +573,7 @@ static void shm_close (struct vm_area_struct *shmd)
unmap_page_range (shmd->vm_start, shmd->vm_end - shmd->vm_start); unmap_page_range (shmd->vm_start, shmd->vm_end - shmd->vm_start);
/* remove from the list of attaches of the shm segment */ /* remove from the list of attaches of the shm segment */
id = (shmd->vm_pte >> SHM_ID_SHIFT) & SHM_ID_MASK; id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
shp = shm_segs[id]; shp = shm_segs[id];
remove_attach(shp,shmd); /* remove from shp->attaches */ remove_attach(shp,shmd); /* remove from shp->attaches */
shp->shm_lpid = current->pid; shp->shm_lpid = current->pid;
...@@ -577,7 +586,7 @@ static void shm_close (struct vm_area_struct *shmd) ...@@ -577,7 +586,7 @@ static void shm_close (struct vm_area_struct *shmd)
* detach and kill segment if marked destroyed. * detach and kill segment if marked destroyed.
* The work is done in shm_close. * The work is done in shm_close.
*/ */
int sys_shmdt (char *shmaddr) asmlinkage int sys_shmdt (char *shmaddr)
{ {
struct vm_area_struct *shmd, *shmdnext; struct vm_area_struct *shmd, *shmdnext;
...@@ -599,10 +608,10 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns ...@@ -599,10 +608,10 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns
struct shmid_ds *shp; struct shmid_ds *shp;
unsigned int id, idx; unsigned int id, idx;
id = (code >> SHM_ID_SHIFT) & SHM_ID_MASK; id = SWP_OFFSET(code) & SHM_ID_MASK;
if (id != ((shmd->vm_pte >> SHM_ID_SHIFT) & SHM_ID_MASK)) { if (id != (SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK)) {
printk ("shm_swap_in: code id = %d and shmd id = %ld differ\n", printk ("shm_swap_in: code id = %d and shmd id = %ld differ\n",
id, (shmd->vm_pte >> SHM_ID_SHIFT) & SHM_ID_MASK); id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK);
return BAD_PAGE; return BAD_PAGE;
} }
if (id > max_shmid) { if (id > max_shmid) {
...@@ -614,7 +623,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns ...@@ -614,7 +623,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns
printk ("shm_swap_in: id=%d invalid. Race.\n", id); printk ("shm_swap_in: id=%d invalid. Race.\n", id);
return BAD_PAGE; return BAD_PAGE;
} }
idx = (code >> SHM_IDX_SHIFT) & SHM_IDX_MASK; idx = (SWP_OFFSET(code) >> SHM_IDX_SHIFT) & SHM_IDX_MASK;
if (idx != (offset >> PAGE_SHIFT)) { if (idx != (offset >> PAGE_SHIFT)) {
printk ("shm_swap_in: code idx = %u and shmd idx = %lu differ\n", printk ("shm_swap_in: code idx = %u and shmd idx = %lu differ\n",
idx, offset >> PAGE_SHIFT); idx, offset >> PAGE_SHIFT);
...@@ -719,8 +728,9 @@ int shm_swap (int prio) ...@@ -719,8 +728,9 @@ int shm_swap (int prio)
pte_t *page_table, pte; pte_t *page_table, pte;
unsigned long tmp; unsigned long tmp;
if ((shmd->vm_pte >> SHM_ID_SHIFT & SHM_ID_MASK) != id) { if (SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK != id) {
printk ("shm_swap: id=%ld does not match shmd->vm_pte.id=%ld\n", id, shmd->vm_pte >> SHM_ID_SHIFT & SHM_ID_MASK); printk ("shm_swap: id=%ld does not match shmd->vm_pte.id=%ld\n",
id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK);
continue; continue;
} }
tmp = shmd->vm_start + (idx << PAGE_SHIFT) - shmd->vm_offset; tmp = shmd->vm_start + (idx << PAGE_SHIFT) - shmd->vm_offset;
...@@ -750,7 +760,8 @@ int shm_swap (int prio) ...@@ -750,7 +760,8 @@ int shm_swap (int prio)
} }
if (pte_page(pte) != pte_page(page)) if (pte_page(pte) != pte_page(page))
printk("shm_swap_out: page and pte mismatch\n"); printk("shm_swap_out: page and pte mismatch\n");
pte_val(*page_table) = shmd->vm_pte | idx << SHM_IDX_SHIFT; pte_val(*page_table) =
shmd->vm_pte + SWP_ENTRY(0, idx << SHM_IDX_SHIFT);
mem_map[MAP_NR(pte_page(pte))]--; mem_map[MAP_NR(pte_page(pte))]--;
if (shmd->vm_task->mm->rss > 0) if (shmd->vm_task->mm->rss > 0)
shmd->vm_task->mm->rss--; shmd->vm_task->mm->rss--;
......
...@@ -13,25 +13,9 @@ ...@@ -13,25 +13,9 @@
#include <linux/shm.h> #include <linux/shm.h>
#include <linux/stat.h> #include <linux/stat.h>
void ipc_init (void);
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth);
#ifdef CONFIG_SYSVIPC #ifdef CONFIG_SYSVIPC
int ipcperms (struct ipc_perm *ipcp, short flag);
extern void sem_init (void), msg_init (void), shm_init (void); extern void sem_init (void), msg_init (void), shm_init (void);
extern int sys_semget (key_t key, int nsems, int semflg);
extern int sys_semop (int semid, struct sembuf *sops, unsigned nsops);
extern int sys_semctl (int semid, int semnum, int cmd, union semun arg);
extern int sys_msgget (key_t key, int msgflg);
extern int sys_msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
extern int sys_msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp,
int msgflg);
extern int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf);
extern int sys_shmget (key_t key, int size, int flag);
extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr);
extern int sys_shmdt (char *shmaddr);
extern int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
void ipc_init (void) void ipc_init (void)
{ {
...@@ -63,112 +47,75 @@ int ipcperms (struct ipc_perm *ipcp, short flag) ...@@ -63,112 +47,75 @@ int ipcperms (struct ipc_perm *ipcp, short flag)
return 0; return 0;
} }
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) #else
/*
* Dummy functions when SYSV IPC isn't configured
*/
void sem_exit (void)
{
return;
}
int shm_swap (int prio)
{ {
int version; return 0;
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
if (call <= SEMCTL)
switch (call) {
case SEMOP:
return sys_semop (first, (struct sembuf *)ptr, second);
case SEMGET:
return sys_semget (first, second, third);
case SEMCTL: {
union semun fourth;
int err;
if (!ptr)
return -EINVAL;
if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
return err;
fourth.__pad = (void *) get_fs_long(ptr);
return sys_semctl (first, second, third, fourth);
}
default:
return -EINVAL;
}
if (call <= MSGCTL)
switch (call) {
case MSGSND:
return sys_msgsnd (first, (struct msgbuf *) ptr,
second, third);
case MSGRCV:
switch (version) {
case 0: {
struct ipc_kludge tmp;
int err;
if (!ptr)
return -EINVAL;
if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
return err;
memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
sizeof (tmp));
return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
}
case 1: default:
return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
}
case MSGGET:
return sys_msgget ((key_t) first, second);
case MSGCTL:
return sys_msgctl (first, second, (struct msqid_ds *) ptr);
default:
return -EINVAL;
}
if (call <= SHMCTL)
switch (call) {
case SHMAT:
switch (version) {
case 0: default: {
ulong raddr;
int err;
if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
return err;
err = sys_shmat (first, (char *) ptr, second, &raddr);
if (err)
return err;
put_fs_long (raddr, (ulong *) third);
return 0;
}
case 1: /* iBCS2 emulator entry point */
if (get_fs() != get_ds())
return -EINVAL;
return sys_shmat (first, (char *) ptr, second, (ulong *) third);
}
case SHMDT:
return sys_shmdt ((char *)ptr);
case SHMGET:
return sys_shmget (first, second, third);
case SHMCTL:
return sys_shmctl (first, second, (struct shmid_ds *) ptr);
default:
return -EINVAL;
}
return -EINVAL;
} }
#else /* not CONFIG_SYSVIPC */ asmlinkage int sys_semget (key_t key, int nsems, int semflg)
{
return -ENOSYS;
}
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) asmlinkage int sys_semop (int semid, struct sembuf *sops, unsigned nsops)
{ {
return -ENOSYS; return -ENOSYS;
} }
void sem_exit (void) asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
{ {
return; return -ENOSYS;
} }
int shm_swap (int prio) asmlinkage int sys_msgget (key_t key, int msgflg)
{ {
return 0; return -ENOSYS;
} }
void shm_no_page (unsigned long *ptent) asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
{ {
return; return -ENOSYS;
}
asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp,
int msgflg)
{
return -ENOSYS;
}
asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
{
return -ENOSYS;
}
asmlinkage int sys_shmget (key_t key, int size, int flag)
{
return -ENOSYS;
}
asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *addr)
{
return -ENOSYS;
}
asmlinkage int sys_shmdt (char *shmaddr)
{
return -ENOSYS;
}
asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
return -ENOSYS;
} }
#endif /* CONFIG_SYSVIPC */ #endif /* CONFIG_SYSVIPC */
...@@ -258,7 +258,6 @@ struct symbol_table symbol_table = { ...@@ -258,7 +258,6 @@ struct symbol_table symbol_table = {
X(sys_call_table), X(sys_call_table),
/* Signal interfaces */ /* Signal interfaces */
X(do_signal),
X(send_sig), X(send_sig),
/* Program loader interfaces */ /* Program loader interfaces */
......
...@@ -741,17 +741,22 @@ static void show_task(int nr,struct task_struct * p) ...@@ -741,17 +741,22 @@ static void show_task(int nr,struct task_struct * p)
printk(stat_nam[p->state]); printk(stat_nam[p->state]);
else else
printk(" "); printk(" ");
#ifdef __i386__ #if ((~0UL) == 0xffffffff)
if (p == current) if (p == current)
printk(" current "); printk(" current ");
else else
printk(" %08lX ", ((unsigned long *)p->tss.esp)[3]); printk(" %08lX ", thread_saved_pc(&p->tss));
#else
if (p == current)
printk(" current task ");
else
printk(" %016lx ", thread_saved_pc(&p->tss));
#endif #endif
for (free = 1; free < 1024 ; free++) { for (free = 1; free < PAGE_SIZE/sizeof(long) ; free++) {
if (((unsigned long *)p->kernel_stack_page)[free]) if (((unsigned long *)p->kernel_stack_page)[free])
break; break;
} }
printk("%5lu %5d %6d ", free << 2, p->pid, p->p_pptr->pid); printk("%5lu %5d %6d ", free*sizeof(long), p->pid, p->p_pptr->pid);
if (p->p_cptr) if (p->p_cptr)
printk("%5d ", p->p_cptr->pid); printk("%5d ", p->p_cptr->pid);
else else
...@@ -770,8 +775,15 @@ void show_state(void) ...@@ -770,8 +775,15 @@ void show_state(void)
{ {
int i; int i;
printk(" free sibling\n"); #if ((~0UL) == 0xffffffff)
printk("\n"
" free sibling\n");
printk(" task PC stack pid father child younger older\n"); printk(" task PC stack pid father child younger older\n");
#else
printk("\n"
" free sibling\n");
printk(" task PC stack pid father child younger older\n");
#endif
for (i=0 ; i<NR_TASKS ; i++) for (i=0 ; i<NR_TASKS ; i++)
if (task[i]) if (task[i])
show_task(i,task[i]); show_task(i,task[i]);
......
...@@ -123,10 +123,9 @@ asmlinkage unsigned long sys_signal(int signum, void (*handler)(int)) ...@@ -123,10 +123,9 @@ asmlinkage unsigned long sys_signal(int signum, void (*handler)(int))
if (err) if (err)
return err; return err;
} }
memset(&tmp, 0, sizeof(tmp));
tmp.sa_handler = handler; tmp.sa_handler = handler;
tmp.sa_mask = 0;
tmp.sa_flags = SA_ONESHOT | SA_NOMASK; tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
tmp.sa_restorer = NULL;
handler = current->sigaction[signum-1].sa_handler; handler = current->sigaction[signum-1].sa_handler;
current->sigaction[signum-1] = tmp; current->sigaction[signum-1] = tmp;
check_pending(signum); check_pending(signum);
......
...@@ -439,8 +439,8 @@ asmlinkage unsigned long sys_brk(unsigned long brk) ...@@ -439,8 +439,8 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
} }
/* /*
* This needs some heave checking ... * This needs some heavy checking ...
* I just haven't get the stomach for it. I also don't fully * I just haven't the stomach for it. I also don't fully
* understand sessions/pgrp etc. Let somebody who does explain it. * understand sessions/pgrp etc. Let somebody who does explain it.
* *
* OK, I think I have the protection semantics right.... this is really * OK, I think I have the protection semantics right.... this is really
......
...@@ -103,6 +103,13 @@ void time_init(void) ...@@ -103,6 +103,13 @@ void time_init(void)
BCD_TO_BIN(mon); BCD_TO_BIN(mon);
BCD_TO_BIN(year); BCD_TO_BIN(year);
} }
#if defined(__alpha__) && defined(CONFIG_PCI)
/*
* The meaning of life, the universe, and everything. Plus
* this makes the year come out right.
*/
year -= 42;
#endif
if ((year += 1900) < 1970) if ((year += 1900) < 1970)
year += 100; year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
......
...@@ -103,6 +103,7 @@ void filemap_swapout(struct vm_area_struct * vma, ...@@ -103,6 +103,7 @@ void 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));
pte_val(*page_table) = entry; pte_val(*page_table) = entry;
invalidate();
filemap_sync_page(vma, offset, page); filemap_sync_page(vma, offset, page);
if (pte_val(*page_table) == entry) if (pte_val(*page_table) == entry)
pte_clear(page_table); pte_clear(page_table);
......
...@@ -504,10 +504,6 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned ...@@ -504,10 +504,6 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned
pte_clear(pte); pte_clear(pte);
if (offset >= high_memory || (mem_map[MAP_NR(offset)] & MAP_PAGE_RESERVED)) if (offset >= high_memory || (mem_map[MAP_NR(offset)] & MAP_PAGE_RESERVED))
*pte = mk_pte(offset, prot); *pte = mk_pte(offset, prot);
else if (mem_map[MAP_NR(offset)]) {
mem_map[MAP_NR(offset)]++;
*pte = mk_pte(offset, prot);
}
forget_pte(oldpage); forget_pte(oldpage);
address += PAGE_SIZE; address += PAGE_SIZE;
offset += PAGE_SIZE; offset += PAGE_SIZE;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/swap.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/dma.h> #include <asm/dma.h>
...@@ -33,17 +34,23 @@ int min_free_pages = 20; ...@@ -33,17 +34,23 @@ int min_free_pages = 20;
static int nr_swapfiles = 0; static int nr_swapfiles = 0;
static struct wait_queue * lock_queue = NULL; static struct wait_queue * lock_queue = NULL;
static struct {
int head; /* head of priority-ordered swapfile list */
int next; /* swapfile to be used next */
} swap_list = {-1, -1};
static struct swap_info_struct { static struct swap_info_struct {
unsigned long flags; unsigned int flags;
struct inode * swap_file;
unsigned int swap_device; unsigned int swap_device;
struct inode * swap_file;
unsigned char * swap_map; unsigned char * swap_map;
unsigned char * swap_lockmap; unsigned char * swap_lockmap;
int pages;
int lowest_bit; int lowest_bit;
int highest_bit; int highest_bit;
int prio; /* swap priority */
int pages;
unsigned long max; unsigned long max;
int next; /* next entry on swap list */
} swap_info[MAX_SWAPFILES]; } swap_info[MAX_SWAPFILES];
extern int shm_swap (int); extern int shm_swap (int);
...@@ -180,26 +187,47 @@ void rw_swap_page(int rw, unsigned long entry, char * buf) ...@@ -180,26 +187,47 @@ void rw_swap_page(int rw, unsigned long entry, char * buf)
unsigned long get_swap_page(void) unsigned long get_swap_page(void)
{ {
struct swap_info_struct * p; struct swap_info_struct * p;
unsigned long offset, type; unsigned long offset, entry;
int type, wrapped = 0;
p = swap_info;
for (type = 0 ; type < nr_swapfiles ; type++,p++) { type = swap_list.next;
if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK) if (type < 0)
continue; return 0;
for (offset = p->lowest_bit; offset <= p->highest_bit ; offset++) {
if (p->swap_map[offset]) while (1) {
continue; p = &swap_info[type];
if (test_bit(offset, p->swap_lockmap)) if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
continue; for (offset = p->lowest_bit; offset <= p->highest_bit ; offset++) {
p->swap_map[offset] = 1; if (p->swap_map[offset])
nr_swap_pages--; continue;
if (offset == p->highest_bit) if (test_bit(offset, p->swap_lockmap))
p->highest_bit--; continue;
p->lowest_bit = offset; p->swap_map[offset] = 1;
return SWP_ENTRY(type,offset); nr_swap_pages--;
if (offset == p->highest_bit)
p->highest_bit--;
p->lowest_bit = offset;
entry = SWP_ENTRY(type,offset);
type = swap_info[type].next;
if (type < 0 || p->prio != swap_info[type].prio) {
swap_list.next = swap_list.head;
} else {
swap_list.next = type;
}
return entry;
}
}
type = p->next;
if (!wrapped) {
if (type < 0 || p->prio != swap_info[type].prio) {
type = swap_list.head;
wrapped = 1;
}
} else if (type < 0) {
return 0; /* out of swap space */
} }
} }
return 0;
} }
void swap_duplicate(unsigned long entry) void swap_duplicate(unsigned long entry)
...@@ -263,6 +291,9 @@ void swap_free(unsigned long entry) ...@@ -263,6 +291,9 @@ void swap_free(unsigned long entry)
else else
if (!--p->swap_map[offset]) if (!--p->swap_map[offset])
nr_swap_pages++; nr_swap_pages++;
if (p->prio > swap_info[swap_list.next].prio) {
swap_list.next = swap_list.head;
}
} }
/* /*
...@@ -275,7 +306,7 @@ void swap_free(unsigned long entry) ...@@ -275,7 +306,7 @@ void swap_free(unsigned long entry)
void swap_in(struct vm_area_struct * vma, pte_t * page_table, void swap_in(struct vm_area_struct * vma, pte_t * page_table,
unsigned long entry, int write_access) unsigned long entry, int write_access)
{ {
unsigned long page = get_free_page(GFP_KERNEL); unsigned long page = __get_free_page(GFP_KERNEL);
if (pte_val(*page_table) != entry) { if (pte_val(*page_table) != entry) {
free_page(page); free_page(page);
...@@ -977,34 +1008,42 @@ asmlinkage int sys_swapoff(const char * specialfile) ...@@ -977,34 +1008,42 @@ asmlinkage int sys_swapoff(const char * specialfile)
{ {
struct swap_info_struct * p; struct swap_info_struct * p;
struct inode * inode; struct inode * inode;
unsigned int type;
struct file filp; struct file filp;
int i; int i, type, prev;
if (!suser()) if (!suser())
return -EPERM; return -EPERM;
i = namei(specialfile,&inode); i = namei(specialfile,&inode);
if (i) if (i)
return i; return i;
p = swap_info; prev = -1;
for (type = 0 ; type < nr_swapfiles ; type++,p++) { for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK) p = swap_info + type;
continue; if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
if (p->swap_file) { if (p->swap_file) {
if (p->swap_file == inode) if (p->swap_file == inode)
break; break;
} else { } else {
if (!S_ISBLK(inode->i_mode)) if (S_ISBLK(inode->i_mode)
continue; && (p->swap_device == inode->i_rdev))
if (p->swap_device == inode->i_rdev) break;
break; }
} }
prev = type;
} }
if (type < 0){
if (type >= nr_swapfiles){
iput(inode); iput(inode);
return -EINVAL; return -EINVAL;
} }
if (prev < 0) {
swap_list.head = p->next;
} else {
swap_info[prev].next = p->next;
}
if (type == swap_list.next) {
/* just pick something that's safe... */
swap_list.next = swap_list.head;
}
p->flags = SWP_USED; p->flags = SWP_USED;
i = try_to_unuse(type); i = try_to_unuse(type);
if (i) { if (i) {
...@@ -1043,14 +1082,15 @@ asmlinkage int sys_swapoff(const char * specialfile) ...@@ -1043,14 +1082,15 @@ asmlinkage int sys_swapoff(const char * specialfile)
* *
* The swapon system call * The swapon system call
*/ */
asmlinkage int sys_swapon(const char * specialfile) asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
{ {
struct swap_info_struct * p; struct swap_info_struct * p;
struct inode * swap_inode; struct inode * swap_inode;
unsigned int type; unsigned int type;
int i,j; int i, j, prev;
int error; int error;
struct file filp; struct file filp;
static int least_priority = 0;
memset(&filp, 0, sizeof(filp)); memset(&filp, 0, sizeof(filp));
if (!suser()) if (!suser())
...@@ -1071,6 +1111,13 @@ asmlinkage int sys_swapon(const char * specialfile) ...@@ -1071,6 +1111,13 @@ asmlinkage int sys_swapon(const char * specialfile)
p->lowest_bit = 0; p->lowest_bit = 0;
p->highest_bit = 0; p->highest_bit = 0;
p->max = 1; p->max = 1;
p->next = -1;
if (swap_flags & SWAP_FLAG_PREFER) {
p->prio =
(swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;
} else {
p->prio = --least_priority;
}
error = namei(specialfile,&swap_inode); error = namei(specialfile,&swap_inode);
if (error) if (error)
goto bad_swap_2; goto bad_swap_2;
...@@ -1149,6 +1196,21 @@ asmlinkage int sys_swapon(const char * specialfile) ...@@ -1149,6 +1196,21 @@ asmlinkage int sys_swapon(const char * specialfile)
p->pages = j; p->pages = j;
nr_swap_pages += j; nr_swap_pages += j;
printk("Adding Swap: %dk swap-space\n",j<<(PAGE_SHIFT-10)); printk("Adding Swap: %dk swap-space\n",j<<(PAGE_SHIFT-10));
/* insert swap space into swap_list: */
prev = -1;
for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
if (p->prio >= swap_info[i].prio) {
break;
}
prev = i;
}
p->next = i;
if (prev < 0) {
swap_list.head = swap_list.next = p - swap_info;
} else {
swap_info[prev].next = p - swap_info;
}
return 0; return 0;
bad_swap: bad_swap:
if(filp.f_op && filp.f_op->release) if(filp.f_op && filp.f_op->release)
......
...@@ -20,15 +20,11 @@ SUBOBJS := $(foreach f,$(SUBDIRS),$f/$f.o) ...@@ -20,15 +20,11 @@ SUBOBJS := $(foreach f,$(SUBDIRS),$f/$f.o)
OBJS = socket.o protocols.o OBJS = socket.o protocols.o
all: net.o all: network.a
net.o: $(OBJS) network.a network.a: subdirs $(OBJS)
$(LD) -u _eth_setup -r -o net.o $(OBJS) network.a
network.a: subdirs
rm -f $@ rm -f $@
ar rc $@ $(SUBOBJS) ar rcs $@ $(OBJS) $(SUBOBJS)
ranlib $@
subdirs: dummy subdirs: dummy
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
OBJS := utils.o route.o proc.o timer.o protocol.o packet.o \ OBJS := utils.o route.o proc.o timer.o protocol.o packet.o \
arp.o ip.o raw.o icmp.o tcp.o udp.o devinet.o af_inet.o \ arp.o ip.o raw.o icmp.o tcp.o udp.o devinet.o af_inet.o \
igmp.o ip_fw.o checksum.o ipip.o igmp.o ip_fw.o ipip.o
ifdef CONFIG_INET_RARP ifdef CONFIG_INET_RARP
......
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
* Alan Cox : routing cache support * Alan Cox : routing cache support
* Alan Cox : memzero the socket structure for compactness. * Alan Cox : memzero the socket structure for compactness.
* Matt Day : nonblock connect error handler * Matt Day : nonblock connect error handler
* Alan Cox : Allow large numbers of pending sockets
* (eg for big web sites), but only if
* specifically application requested.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -485,9 +488,10 @@ static int inet_listen(struct socket *sock, int backlog) ...@@ -485,9 +488,10 @@ static int inet_listen(struct socket *sock, int backlog)
* note that the backlog is "unsigned char", so truncate it * note that the backlog is "unsigned char", so truncate it
* somewhere. We might as well truncate it to what everybody * somewhere. We might as well truncate it to what everybody
* else does.. * else does..
* Now truncate to 128 not 5.
*/ */
if (backlog > 5) if ((unsigned) backlog > 128)
backlog = 5; backlog = 128;
sk->max_ack_backlog = backlog; sk->max_ack_backlog = backlog;
if (sk->state != TCP_LISTEN) if (sk->state != TCP_LISTEN)
{ {
......
...@@ -126,7 +126,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, s ...@@ -126,7 +126,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, s
*/ */
atype=ip_chk_addr(iph->daddr); atype=ip_chk_addr(iph->daddr);
if(atype==IS_BROADCAST || IN_MULTICAST(iph->daddr)) if(atype==IS_BROADCAST || atype==IS_MULTICAST)
return; return;
/* /*
......
...@@ -618,7 +618,7 @@ static struct sk_buff *ip_glue(struct ipq *qp) ...@@ -618,7 +618,7 @@ static struct sk_buff *ip_glue(struct ipq *qp)
if ((skb = alloc_skb(len,GFP_ATOMIC)) == NULL) if ((skb = alloc_skb(len,GFP_ATOMIC)) == NULL)
{ {
ip_statistics.IpReasmFails++; ip_statistics.IpReasmFails++;
NETDEBUG(printk("IP: queue_glue: no memory for gluing queue 0x%X\n", (int) qp)); NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp));
ip_free(qp); ip_free(qp);
return(NULL); return(NULL);
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <netinet/in.h> #include <linux/in.h>
#include <net/datalink.h> #include <net/datalink.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/ip.h> #include <net/ip.h>
......
...@@ -144,6 +144,13 @@ static void raw_getrawfrag(void *p, int saddr, char *to, unsigned int offset, un ...@@ -144,6 +144,13 @@ static void raw_getrawfrag(void *p, int saddr, char *to, unsigned int offset, un
struct iphdr *iph=(struct iphdr *)to; struct iphdr *iph=(struct iphdr *)to;
iph->saddr=saddr; iph->saddr=saddr;
iph->check=0; iph->check=0;
iph->tot_len=htons(fraglen); /* This is right as you cant frag
RAW packets */
/*
* Deliberate breach of modularity to keep
* ip_build_xmit clean (well less messy).
*/
iph->id = htons(ip_id_count++);
iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl); iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
} }
} }
......
...@@ -559,7 +559,7 @@ int sock_awaitconn(struct socket *mysock, struct socket *servsock, int flags) ...@@ -559,7 +559,7 @@ int sock_awaitconn(struct socket *mysock, struct socket *servsock, int flags)
* family, then create a fresh socket. * family, then create a fresh socket.
*/ */
static int sock_socket(int family, int type, int protocol) asmlinkage int sys_socket(int family, int type, int protocol)
{ {
int i, fd; int i, fd;
struct socket *sock; struct socket *sock;
...@@ -599,7 +599,7 @@ static int sock_socket(int family, int type, int protocol) ...@@ -599,7 +599,7 @@ static int sock_socket(int family, int type, int protocol)
if (!(sock = sock_alloc())) if (!(sock = sock_alloc()))
{ {
printk("NET: sock_socket: no more sockets\n"); printk("NET: sys_socket: no more sockets\n");
return(-ENOSR); /* Was: EAGAIN, but we are out of return(-ENOSR); /* Was: EAGAIN, but we are out of
system resources! */ system resources! */
} }
...@@ -625,7 +625,7 @@ static int sock_socket(int family, int type, int protocol) ...@@ -625,7 +625,7 @@ static int sock_socket(int family, int type, int protocol)
* Create a pair of connected sockets. * Create a pair of connected sockets.
*/ */
static int sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2]) asmlinkage int sys_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
{ {
int fd1, fd2, i; int fd1, fd2, i;
struct socket *sock1, *sock2; struct socket *sock1, *sock2;
...@@ -636,7 +636,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso ...@@ -636,7 +636,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso
* supports the socketpair call. * supports the socketpair call.
*/ */
if ((fd1 = sock_socket(family, type, protocol)) < 0) if ((fd1 = sys_socket(family, type, protocol)) < 0)
return(fd1); return(fd1);
sock1 = sockfd_lookup(fd1, NULL); sock1 = sockfd_lookup(fd1, NULL);
if (!sock1->ops->socketpair) if (!sock1->ops->socketpair)
...@@ -649,7 +649,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso ...@@ -649,7 +649,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso
* Now grab another socket and try to connect the two together. * Now grab another socket and try to connect the two together.
*/ */
if ((fd2 = sock_socket(family, type, protocol)) < 0) if ((fd2 = sys_socket(family, type, protocol)) < 0)
{ {
sys_close(fd1); sys_close(fd1);
return(-EINVAL); return(-EINVAL);
...@@ -690,7 +690,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso ...@@ -690,7 +690,7 @@ static int sock_socketpair(int family, int type, int protocol, unsigned long uso
* the protocol layer (having also checked the address is ok). * the protocol layer (having also checked the address is ok).
*/ */
static int sock_bind(int fd, struct sockaddr *umyaddr, int addrlen) asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen)
{ {
struct socket *sock; struct socket *sock;
int i; int i;
...@@ -720,7 +720,7 @@ static int sock_bind(int fd, struct sockaddr *umyaddr, int addrlen) ...@@ -720,7 +720,7 @@ static int sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
* ready for listening. * ready for listening.
*/ */
static int sock_listen(int fd, int backlog) asmlinkage int sys_listen(int fd, int backlog)
{ {
struct socket *sock; struct socket *sock;
...@@ -749,7 +749,7 @@ static int sock_listen(int fd, int backlog) ...@@ -749,7 +749,7 @@ static int sock_listen(int fd, int backlog)
* we open the socket then return an error. * we open the socket then return an error.
*/ */
static int sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen) asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
{ {
struct file *file; struct file *file;
struct socket *sock, *newsock; struct socket *sock, *newsock;
...@@ -811,7 +811,7 @@ static int sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrl ...@@ -811,7 +811,7 @@ static int sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrl
* is in user space so we verify it is OK and move it to kernel space. * is in user space so we verify it is OK and move it to kernel space.
*/ */
static int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen) asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -862,7 +862,7 @@ static int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen) ...@@ -862,7 +862,7 @@ static int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
* name to user space. * name to user space.
*/ */
static int sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len) asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
{ {
struct socket *sock; struct socket *sock;
char address[MAX_SOCK_ADDR]; char address[MAX_SOCK_ADDR];
...@@ -887,7 +887,7 @@ static int sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_l ...@@ -887,7 +887,7 @@ static int sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_l
* name to user space. * name to user space.
*/ */
static int sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len) asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
{ {
struct socket *sock; struct socket *sock;
char address[MAX_SOCK_ADDR]; char address[MAX_SOCK_ADDR];
...@@ -912,7 +912,7 @@ static int sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_l ...@@ -912,7 +912,7 @@ static int sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_l
* in user space. We check it can be read. * in user space. We check it can be read.
*/ */
static int sock_send(int fd, void * buff, int len, unsigned flags) asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -937,7 +937,7 @@ static int sock_send(int fd, void * buff, int len, unsigned flags) ...@@ -937,7 +937,7 @@ static int sock_send(int fd, void * buff, int len, unsigned flags)
* the protocol. * the protocol.
*/ */
static int sock_sendto(int fd, void * buff, int len, unsigned flags, asmlinkage int sys_sendto(int fd, void * buff, int len, unsigned flags,
struct sockaddr *addr, int addr_len) struct sockaddr *addr, int addr_len)
{ {
struct socket *sock; struct socket *sock;
...@@ -972,7 +972,7 @@ static int sock_sendto(int fd, void * buff, int len, unsigned flags, ...@@ -972,7 +972,7 @@ static int sock_sendto(int fd, void * buff, int len, unsigned flags,
* We check the buffer is writable and valid. * We check the buffer is writable and valid.
*/ */
static int sock_recv(int fd, void * buff, int len, unsigned flags) asmlinkage int sys_recv(int fd, void * buff, int len, unsigned flags)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -1001,7 +1001,7 @@ static int sock_recv(int fd, void * buff, int len, unsigned flags) ...@@ -1001,7 +1001,7 @@ static int sock_recv(int fd, void * buff, int len, unsigned flags)
* sender address from kernel to user space. * sender address from kernel to user space.
*/ */
static int sock_recvfrom(int fd, void * buff, int len, unsigned flags, asmlinkage int sys_recvfrom(int fd, void * buff, int len, unsigned flags,
struct sockaddr *addr, int *addr_len) struct sockaddr *addr, int *addr_len)
{ {
struct socket *sock; struct socket *sock;
...@@ -1038,7 +1038,7 @@ static int sock_recvfrom(int fd, void * buff, int len, unsigned flags, ...@@ -1038,7 +1038,7 @@ static int sock_recvfrom(int fd, void * buff, int len, unsigned flags,
* to pass the user mode parameter for the protocols to sort out. * to pass the user mode parameter for the protocols to sort out.
*/ */
static int sock_setsockopt(int fd, int level, int optname, char *optval, int optlen) asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -1056,7 +1056,7 @@ static int sock_setsockopt(int fd, int level, int optname, char *optval, int opt ...@@ -1056,7 +1056,7 @@ static int sock_setsockopt(int fd, int level, int optname, char *optval, int opt
* to pass a user mode parameter for the protocols to sort out. * to pass a user mode parameter for the protocols to sort out.
*/ */
static int sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen) asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -1076,7 +1076,7 @@ static int sock_getsockopt(int fd, int level, int optname, char *optval, int *op ...@@ -1076,7 +1076,7 @@ static int sock_getsockopt(int fd, int level, int optname, char *optval, int *op
* Shutdown a socket. * Shutdown a socket.
*/ */
static int sock_shutdown(int fd, int how) asmlinkage int sys_shutdown(int fd, int how)
{ {
struct socket *sock; struct socket *sock;
struct file *file; struct file *file;
...@@ -1139,61 +1139,61 @@ asmlinkage int sys_socketcall(int call, unsigned long *args) ...@@ -1139,61 +1139,61 @@ asmlinkage int sys_socketcall(int call, unsigned long *args)
switch(call) switch(call)
{ {
case SYS_SOCKET: case SYS_SOCKET:
return(sock_socket(a0,a1,get_fs_long(args+2))); return(sys_socket(a0,a1,get_fs_long(args+2)));
case SYS_BIND: case SYS_BIND:
return(sock_bind(a0,(struct sockaddr *)a1, return(sys_bind(a0,(struct sockaddr *)a1,
get_fs_long(args+2))); get_fs_long(args+2)));
case SYS_CONNECT: case SYS_CONNECT:
return(sock_connect(a0, (struct sockaddr *)a1, return(sys_connect(a0, (struct sockaddr *)a1,
get_fs_long(args+2))); get_fs_long(args+2)));
case SYS_LISTEN: case SYS_LISTEN:
return(sock_listen(a0,a1)); return(sys_listen(a0,a1));
case SYS_ACCEPT: case SYS_ACCEPT:
return(sock_accept(a0,(struct sockaddr *)a1, return(sys_accept(a0,(struct sockaddr *)a1,
(int *)get_fs_long(args+2))); (int *)get_fs_long(args+2)));
case SYS_GETSOCKNAME: case SYS_GETSOCKNAME:
return(sock_getsockname(a0,(struct sockaddr *)a1, return(sys_getsockname(a0,(struct sockaddr *)a1,
(int *)get_fs_long(args+2))); (int *)get_fs_long(args+2)));
case SYS_GETPEERNAME: case SYS_GETPEERNAME:
return(sock_getpeername(a0, (struct sockaddr *)a1, return(sys_getpeername(a0, (struct sockaddr *)a1,
(int *)get_fs_long(args+2))); (int *)get_fs_long(args+2)));
case SYS_SOCKETPAIR: case SYS_SOCKETPAIR:
return(sock_socketpair(a0,a1, return(sys_socketpair(a0,a1,
get_fs_long(args+2), get_fs_long(args+2),
(unsigned long *)get_fs_long(args+3))); (unsigned long *)get_fs_long(args+3)));
case SYS_SEND: case SYS_SEND:
return(sock_send(a0, return(sys_send(a0,
(void *)a1, (void *)a1,
get_fs_long(args+2), get_fs_long(args+2),
get_fs_long(args+3))); get_fs_long(args+3)));
case SYS_SENDTO: case SYS_SENDTO:
return(sock_sendto(a0,(void *)a1, return(sys_sendto(a0,(void *)a1,
get_fs_long(args+2), get_fs_long(args+2),
get_fs_long(args+3), get_fs_long(args+3),
(struct sockaddr *)get_fs_long(args+4), (struct sockaddr *)get_fs_long(args+4),
get_fs_long(args+5))); get_fs_long(args+5)));
case SYS_RECV: case SYS_RECV:
return(sock_recv(a0, return(sys_recv(a0,
(void *)a1, (void *)a1,
get_fs_long(args+2), get_fs_long(args+2),
get_fs_long(args+3))); get_fs_long(args+3)));
case SYS_RECVFROM: case SYS_RECVFROM:
return(sock_recvfrom(a0, return(sys_recvfrom(a0,
(void *)a1, (void *)a1,
get_fs_long(args+2), get_fs_long(args+2),
get_fs_long(args+3), get_fs_long(args+3),
(struct sockaddr *)get_fs_long(args+4), (struct sockaddr *)get_fs_long(args+4),
(int *)get_fs_long(args+5))); (int *)get_fs_long(args+5)));
case SYS_SHUTDOWN: case SYS_SHUTDOWN:
return(sock_shutdown(a0,a1)); return(sys_shutdown(a0,a1));
case SYS_SETSOCKOPT: case SYS_SETSOCKOPT:
return(sock_setsockopt(a0, return(sys_setsockopt(a0,
a1, a1,
get_fs_long(args+2), get_fs_long(args+2),
(char *)get_fs_long(args+3), (char *)get_fs_long(args+3),
get_fs_long(args+4))); get_fs_long(args+4)));
case SYS_GETSOCKOPT: case SYS_GETSOCKOPT:
return(sock_getsockopt(a0, return(sys_getsockopt(a0,
a1, a1,
get_fs_long(args+2), get_fs_long(args+2),
(char *)get_fs_long(args+3), (char *)get_fs_long(args+3),
......
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