Commit 8c78000c authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.3

parent aea252fa
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 2 SUBLEVEL = 3
ARCH = i386 ARCH = i386
......
...@@ -28,6 +28,7 @@ struct screen_info { ...@@ -28,6 +28,7 @@ struct screen_info {
unsigned short orig_video_ega_bx; unsigned short orig_video_ega_bx;
unsigned short orig_video_ega_cx; unsigned short orig_video_ega_cx;
unsigned char orig_video_lines; unsigned char orig_video_lines;
unsigned char orig_video_isVGA;
}; };
/* /*
......
...@@ -160,10 +160,12 @@ good_sig: ...@@ -160,10 +160,12 @@ good_sig:
int 0x10 int 0x10
mov bx,ax mov bx,ax
mov ax,#0x5019 mov ax,#0x5019
movb [15],#0 ! by default, no VGA
cmp bl,#0x1a ! 1a means VGA, anything else EGA or lower cmp bl,#0x1a ! 1a means VGA, anything else EGA or lower
jne novga jne novga
movb [15],#1 ! we've detected a VGA
call chsvga call chsvga
novga: mov [14],ax novga: mov [14],al
mov ah,#0x03 ! read cursor pos mov ah,#0x03 ! read cursor pos
xor bh,bh ! clear bh xor bh,bh ! clear bh
int 0x10 ! save it in known place, con_init fetches int 0x10 ! save it in known place, con_init fetches
......
...@@ -17,6 +17,8 @@ lib.a: $(OBJS) ...@@ -17,6 +17,8 @@ lib.a: $(OBJS)
dep: dep:
modules:
# #
# include a dependency file if one exists # include a dependency file if one exists
# #
......
This diff is collapsed.
...@@ -102,6 +102,9 @@ static int tty_ioctl(struct inode * inode, struct file * file, ...@@ -102,6 +102,9 @@ static int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int tty_fasync(struct inode * inode, struct file * filp, int on); static int tty_fasync(struct inode * inode, struct file * filp, int on);
extern void reset_palette(int currcons) ;
extern void set_palette(void) ;
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif #endif
...@@ -497,6 +500,7 @@ void reset_vc(unsigned int new_console) ...@@ -497,6 +500,7 @@ void reset_vc(unsigned int new_console)
vt_cons[new_console]->vt_mode.frsig = 0; vt_cons[new_console]->vt_mode.frsig = 0;
vt_cons[new_console]->vt_pid = -1; vt_cons[new_console]->vt_pid = -1;
vt_cons[new_console]->vt_newvt = -1; vt_cons[new_console]->vt_newvt = -1;
reset_palette (new_console) ;
} }
/* /*
...@@ -561,6 +565,10 @@ void complete_change_console(unsigned int new_console) ...@@ -561,6 +565,10 @@ void complete_change_console(unsigned int new_console)
do_blank_screen(1); do_blank_screen(1);
} }
/* Set the colour palette for this VT */
if (vt_cons[new_console]->vc_mode == KD_TEXT)
set_palette() ;
/* /*
* Wake anyone waiting for their VT to activate * Wake anyone waiting for their VT to activate
*/ */
......
...@@ -63,7 +63,8 @@ extern void do_unblank_screen(void); ...@@ -63,7 +63,8 @@ extern void do_unblank_screen(void);
extern unsigned int keymap_count; extern unsigned int keymap_count;
/* /*
* routines to load custom translation table and EGA/VGA font from console.c * routines to load custom translation table, EGA/VGA font and
* VGA colour palette from console.c
*/ */
extern int con_set_trans_old(char * table); extern int con_set_trans_old(char * table);
extern int con_get_trans_old(char * table); extern int con_get_trans_old(char * table);
...@@ -74,10 +75,14 @@ extern int con_set_unimap(ushort ct, struct unipair *list); ...@@ -74,10 +75,14 @@ extern int con_set_unimap(ushort ct, struct unipair *list);
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list); extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
extern int con_set_font(char * fontmap, int ch512); extern int con_set_font(char * fontmap, int ch512);
extern int con_get_font(char * fontmap); extern int con_get_font(char * fontmap);
extern int con_set_cmap(unsigned char *cmap);
extern int con_get_cmap(unsigned char *cmap);
extern void reset_palette(int currcons);
extern int con_adjust_height(unsigned long fontheight); extern int con_adjust_height(unsigned long fontheight);
extern int video_mode_512ch; extern int video_mode_512ch;
extern unsigned long video_font_height; extern unsigned long video_font_height;
extern unsigned long video_scan_lines;
/* /*
* these are the valid i/o ports we're allowed to change. they map all the * these are the valid i/o ports we're allowed to change. they map all the
...@@ -95,13 +100,13 @@ extern unsigned long video_font_height; ...@@ -95,13 +100,13 @@ extern unsigned long video_font_height;
* tty. * tty.
*/ */
static void static int
kd_size_changed(int row, int col) kd_size_changed(int row, int col)
{ {
struct task_struct *p; struct task_struct *p;
int i; int i;
if ( !row && !col ) return; if ( !row && !col ) return 0;
for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ ) for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
{ {
...@@ -120,6 +125,8 @@ kd_size_changed(int row, int col) ...@@ -120,6 +125,8 @@ kd_size_changed(int row, int col)
send_sig(SIGWINCH, p, 1); send_sig(SIGWINCH, p, 1);
} }
} }
return 0;
} }
/* /*
...@@ -864,7 +871,61 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -864,7 +871,61 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i; return i;
ll = get_fs_word(&vtsizes->v_rows); ll = get_fs_word(&vtsizes->v_rows);
cc = get_fs_word(&vtsizes->v_cols); cc = get_fs_word(&vtsizes->v_cols);
return vc_resize(ll, cc); i = vc_resize(ll, cc);
return i ? i : kd_size_changed(ll, cc);
}
case VT_RESIZEX:
{
struct vt_consize *vtconsize = (struct vt_consize *) arg;
ushort ll,cc,vlin,clin,vcol,ccol;
if (!perm)
return -EPERM;
i = verify_area(VERIFY_READ, (void *)vtconsize, sizeof(struct vt_consize));
if (i)
return i;
ll = get_fs_word(&vtconsize->v_rows);
cc = get_fs_word(&vtconsize->v_cols);
vlin = get_fs_word(&vtconsize->v_vlin);
clin = get_fs_word(&vtconsize->v_clin);
vcol = get_fs_word(&vtconsize->v_vcol);
ccol = get_fs_word(&vtconsize->v_ccol);
vlin = vlin ? vlin : video_scan_lines;
if ( clin )
{
if ( ll )
{
if ( ll != vlin/clin )
return EINVAL; /* Parameters don't add up */
}
else
ll = vlin/clin;
}
if ( vcol && ccol )
{
if ( cc )
{
if ( cc != vcol/ccol )
return EINVAL;
}
else
cc = vcol/ccol;
}
if ( clin > 32 )
return EINVAL;
if ( vlin )
video_scan_lines = vlin;
if ( clin )
video_font_height = clin;
i = vc_resize(ll, cc);
if (i)
return i;
kd_size_changed(ll, cc);
return 0;
} }
case PIO_FONT: case PIO_FONT:
...@@ -882,6 +943,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -882,6 +943,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return con_get_font((char *)arg); return con_get_font((char *)arg);
/* con_get_font() defined in console.c */ /* con_get_font() defined in console.c */
case PIO_CMAP:
if (!perm)
return -EPERM;
return con_set_cmap((char *)arg);
/* con_set_cmap() defined in console.c */
case GIO_CMAP:
return con_get_cmap((char *)arg);
/* con_get_cmap() defined in console.c */
case PIO_FONTX: case PIO_FONTX:
{ {
struct consolefontdesc cfdarg; struct consolefontdesc cfdarg;
...@@ -903,9 +974,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -903,9 +974,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (i) if (i)
return i; return i;
i = con_adjust_height(cfdarg.charheight); i = con_adjust_height(cfdarg.charheight);
if (i <= 0) return i; return (i <= 0) ? i : kd_size_changed(i, 0);
kd_size_changed(i, 0);
return 0;
} else } else
return -EINVAL; return -EINVAL;
} }
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
This is not a complete driver, it must be combined with board-specific This is not a complete driver, it must be combined with board-specific
code such as ne.c, wd.c, 3c503.c, etc. code such as ne.c, wd.c, 3c503.c, etc.
13/04/95 -- Don't blindly swallow ENISR_RDC interrupts for non-shared Changelog:
memory cards. We need to follow these closely for neX000 cards.
Plus other minor cleanups. -- Paul Gortmaker Paul Gortmaker : remove set_bit lock, other cleanups.
*/ */
...@@ -129,7 +129,6 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -129,7 +129,6 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
int e8390_base = dev->base_addr; int e8390_base = dev->base_addr;
struct ei_device *ei_local = (struct ei_device *) dev->priv; struct ei_device *ei_local = (struct ei_device *) dev->priv;
int length, send_length; int length, send_length;
unsigned long flags;
/* /*
* We normally shouldn't be called if dev->tbusy is set, but the * We normally shouldn't be called if dev->tbusy is set, but the
...@@ -177,22 +176,14 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) ...@@ -177,22 +176,14 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
if (skb->len <= 0) if (skb->len <= 0)
return 0; return 0;
save_flags(flags);
cli();
/* Block a timer-based transmit from overlapping. */
if ((set_bit(0, (void*)&dev->tbusy) != 0) || ei_local->irqlock) {
printk("%s: Tx access conflict. irq=%d lock=%d tx1=%d tx2=%d last=%d\n",
dev->name, dev->interrupt, ei_local->irqlock, ei_local->tx1,
ei_local->tx2, ei_local->lasttx);
restore_flags(flags);
return 1;
}
/* Mask interrupts from the ethercard. */ /* Mask interrupts from the ethercard. */
outb_p(0x00, e8390_base + EN0_IMR); outb_p(0x00, e8390_base + EN0_IMR);
if (dev->interrupt) {
printk("%s: Tx request while isr active.\n",dev->name);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
return 1;
}
ei_local->irqlock = 1; ei_local->irqlock = 1;
restore_flags(flags);
send_length = ETH_ZLEN < length ? length : ETH_ZLEN; send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
...@@ -314,17 +305,17 @@ void ei_interrupt(int irq, struct pt_regs * regs) ...@@ -314,17 +305,17 @@ void ei_interrupt(int irq, struct pt_regs * regs)
outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */ outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */
} }
/* Ignore any RDC interrupts that make it back to here. */
if (interrupts & ENISR_RDC) { if (interrupts & ENISR_RDC) {
if (dev->mem_start)
outb_p(ENISR_RDC, e8390_base + EN0_ISR); outb_p(ENISR_RDC, e8390_base + EN0_ISR);
} }
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
} }
if ((interrupts & ~ENISR_RDC) && ei_debug) { if (interrupts && ei_debug) {
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
if (nr_serviced == MAX_SERVICE) { if (nr_serviced >= MAX_SERVICE) {
printk("%s: Too much work at interrupt, status %#2.2x\n", printk("%s: Too much work at interrupt, status %#2.2x\n",
dev->name, interrupts); dev->name, interrupts);
outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
...@@ -501,7 +492,7 @@ static void ei_receive(struct device *dev) ...@@ -501,7 +492,7 @@ static void ei_receive(struct device *dev)
ei_local->current_page = next_frame; ei_local->current_page = next_frame;
outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
} }
/* If any worth-while packets have been received, dev_rint() /* If any worth-while packets have been received, netif_rx()
has done a mark_bh(NET_BH) for us and will work on them has done a mark_bh(NET_BH) for us and will work on them
when we get to the bottom-half routine. */ when we get to the bottom-half routine. */
......
...@@ -45,12 +45,12 @@ struct ei_device { ...@@ -45,12 +45,12 @@ struct ei_device {
unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */
unsigned txing:1; /* Transmit Active */ unsigned txing:1; /* Transmit Active */
unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ unsigned irqlock:1; /* 8390's intrs disabled when '1'. */
unsigned dmaing:1; /* Remote DMA Active */
unsigned pingpong:1; /* Using the ping-pong driver */ unsigned pingpong:1; /* Using the ping-pong driver */
unsigned char tx_start_page, rx_start_page, stop_page; unsigned char tx_start_page, rx_start_page, stop_page;
unsigned char current_page; /* Read pointer in buffer */ unsigned char current_page; /* Read pointer in buffer */
unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */
unsigned char txqueue; /* Tx Packet buffer queue length. */ unsigned char txqueue; /* Tx Packet buffer queue length. */
unsigned char dmaing; /* Remote DMA (Tx/Rx/Active) */
short tx1, tx2; /* Packet lengths for ping-pong tx. */ short tx1, tx2; /* Packet lengths for ping-pong tx. */
short lasttx; /* Alpha version consistency check. */ short lasttx; /* Alpha version consistency check. */
unsigned char reg0; /* Register '0' in a WD8013 */ unsigned char reg0; /* Register '0' in a WD8013 */
......
...@@ -16,12 +16,10 @@ ...@@ -16,12 +16,10 @@
boards. Currently it supports the NE1000, NE2000, many clones, boards. Currently it supports the NE1000, NE2000, many clones,
and some Cabletron products. and some Cabletron products.
13/04/95 -- Change in philosophy. We now monitor ENISR_RDC for Changelog:
handshaking the Tx PIO xfers. If we don't get a RDC within a
reasonable period of time, we know the 8390 has gone south, and we Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made
kick the board before it locks the system. Also use set_bit() to sanity checks and bad clone support optional.
create atomic locks on the PIO xfers, and added some defines
that the end user can play with to save memory. -- Paul Gortmaker
*/ */
...@@ -335,6 +333,7 @@ ne_reset_8390(struct device *dev) ...@@ -335,6 +333,7 @@ ne_reset_8390(struct device *dev)
if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies); if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
ei_status.txing = 0; ei_status.txing = 0;
ei_status.dmaing = 0;
outb_p(tmp, NE_BASE + NE_RESET); outb_p(tmp, NE_BASE + NE_RESET);
/* This check _should_not_ be necessary, omit eventually. */ /* This check _should_not_ be necessary, omit eventually. */
...@@ -343,10 +342,11 @@ ne_reset_8390(struct device *dev) ...@@ -343,10 +342,11 @@ ne_reset_8390(struct device *dev)
printk("%s: ne_reset_8390() did not complete.\n", dev->name); printk("%s: ne_reset_8390() did not complete.\n", dev->name);
break; break;
} }
outb_p(ENISR_RESET, NE_BASE + NE_RESET); /* Ack intr. */
} }
/* Block input and output, similar to the Crynwr packet driver. If you /* Block input and output, similar to the Crynwr packet driver. If you
porting to a new ethercard look at the packet driver source for hints. are porting to a new ethercard, look at the packet driver source for hints.
The NEx000 doesn't share it on-board packet memory -- you have to put The NEx000 doesn't share it on-board packet memory -- you have to put
the packet out through the "remote DMA" dataport using outb. */ the packet out through the "remote DMA" dataport using outb. */
...@@ -359,7 +359,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset) ...@@ -359,7 +359,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
int nic_base = dev->base_addr; int nic_base = dev->base_addr;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (set_bit(0,(void*)&ei_status.dmaing)) { if (ei_status.dmaing) {
if (ei_debug > 0) if (ei_debug > 0)
printk("%s: DMAing conflict in ne_block_input " printk("%s: DMAing conflict in ne_block_input "
"[DMAstat:%d][irqlock:%d][intr:%d].\n", "[DMAstat:%d][irqlock:%d][intr:%d].\n",
...@@ -367,7 +367,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset) ...@@ -367,7 +367,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
dev->interrupt); dev->interrupt);
return 0; return 0;
} }
ei_status.dmaing |= 0x02; ei_status.dmaing |= 0x01;
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
outb_p(count & 0xff, nic_base + EN0_RCNTLO); outb_p(count & 0xff, nic_base + EN0_RCNTLO);
outb_p(count >> 8, nic_base + EN0_RCNTHI); outb_p(count >> 8, nic_base + EN0_RCNTHI);
...@@ -409,7 +409,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset) ...@@ -409,7 +409,7 @@ ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
} }
#endif #endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x03; ei_status.dmaing &= ~0x01;
return ring_offset + count; return ring_offset + count;
} }
...@@ -430,7 +430,7 @@ ne_block_output(struct device *dev, int count, ...@@ -430,7 +430,7 @@ ne_block_output(struct device *dev, int count,
count++; count++;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (set_bit(0,(void*)&ei_status.dmaing)) { if (ei_status.dmaing) {
if (ei_debug > 0) if (ei_debug > 0)
printk("%s: DMAing conflict in ne_block_output." printk("%s: DMAing conflict in ne_block_output."
"[DMAstat:%d][irqlock:%d][intr:%d]\n", "[DMAstat:%d][irqlock:%d][intr:%d]\n",
...@@ -438,7 +438,7 @@ ne_block_output(struct device *dev, int count, ...@@ -438,7 +438,7 @@ ne_block_output(struct device *dev, int count,
dev->interrupt); dev->interrupt);
return; return;
} }
ei_status.dmaing |= 0x04; ei_status.dmaing |= 0x01;
/* We should already be in page 0, but to be safe... */ /* We should already be in page 0, but to be safe... */
outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
...@@ -510,7 +510,7 @@ ne_block_output(struct device *dev, int count, ...@@ -510,7 +510,7 @@ ne_block_output(struct device *dev, int count,
} }
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x05; ei_status.dmaing &= ~0x01;
return; return;
} }
......
...@@ -504,6 +504,9 @@ ppp_close(struct tty_struct *tty) ...@@ -504,6 +504,9 @@ ppp_close(struct tty_struct *tty)
ppp_release (ppp); ppp_release (ppp);
PRINTKN (2,(KERN_INFO "ppp: channel %s closing.\n", ppp->dev->name)); PRINTKN (2,(KERN_INFO "ppp: channel %s closing.\n", ppp->dev->name));
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
} }
} }
...@@ -612,9 +615,6 @@ ppp_dev_close(struct device *dev) ...@@ -612,9 +615,6 @@ ppp_dev_close(struct device *dev)
PRINTKN (2,(KERN_INFO "ppp: channel %s going down for IP packets!\n", PRINTKN (2,(KERN_INFO "ppp: channel %s going down for IP packets!\n",
dev->name)); dev->name));
CHECK_PPP(-ENXIO); CHECK_PPP(-ENXIO);
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
......
...@@ -78,7 +78,7 @@ static void padzero(unsigned long elf_bss) ...@@ -78,7 +78,7 @@ static void padzero(unsigned long elf_bss)
} }
} }
unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, int ibcs) unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, unsigned int interp_load_addr, int ibcs)
{ {
unsigned long *argv,*envp, *dlinfo; unsigned long *argv,*envp, *dlinfo;
unsigned long * sp; unsigned long * sp;
...@@ -129,11 +129,11 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe ...@@ -129,11 +129,11 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++); put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++);
put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++); put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++);
put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++); put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++);
put_fs_long(7,dlinfo++); put_fs_long(SHM_RANGE_START,dlinfo++); put_fs_long(7,dlinfo++); put_fs_long(interp_load_addr,dlinfo++);
put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++); put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++);
put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++); put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++);
put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++);
}; }
put_fs_long((unsigned long)argc,--sp); put_fs_long((unsigned long)argc,--sp);
current->mm->arg_start = (unsigned long) p; current->mm->arg_start = (unsigned long) p;
...@@ -159,7 +159,7 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe ...@@ -159,7 +159,7 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
an ELF header */ an ELF header */
static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
struct inode * interpreter_inode) struct inode * interpreter_inode, unsigned int *interp_load_addr)
{ {
struct file * file; struct file * file;
struct elf_phdr *elf_phdata = NULL; struct elf_phdr *elf_phdata = NULL;
...@@ -184,7 +184,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -184,7 +184,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
(!interpreter_inode->i_op || (!interpreter_inode->i_op ||
!interpreter_inode->i_op->default_file_ops->mmap)){ !interpreter_inode->i_op->default_file_ops->mmap)){
return 0xffffffff; return 0xffffffff;
}; }
/* Now read in all of the header information */ /* Now read in all of the header information */
...@@ -202,52 +202,32 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -202,52 +202,32 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
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) {
int elf_prot = (eppnt->p_flags & PF_R) ? PROT_READ : 0; int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
int elf_prot = 0;
unsigned long vaddr = 0;
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
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;
if (interp_elf_ex->e_type == ET_EXEC) {
elf_type |= MAP_FIXED;
vaddr = eppnt->p_vaddr;
}
error = do_mmap(file, error = do_mmap(file,
load_addr + (eppnt->p_vaddr & 0xfffff000), vaddr & 0xfffff000,
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), eppnt->p_filesz + (vaddr & 0xfff),
elf_prot, elf_prot,
MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED, elf_type,
eppnt->p_offset & 0xfffff000); eppnt->p_offset & 0xfffff000);
if(error < 0 && error > -1024) break; /* Real error */ if(error < 0 && error > -1024) break; /* Real error */
if(!load_addr && interp_elf_ex->e_type == ET_DYN)
load_addr = error;
/* /*
* Find the end of the file mapping for this phdr, and keep * Find the end of the file mapping for this phdr, and keep
* track of the largest address we see for this. * track of the largest address we see for this.
...@@ -265,7 +245,6 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -265,7 +245,6 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
/* 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);
...@@ -288,6 +267,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -288,6 +267,7 @@ static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
kfree(elf_phdata); kfree(elf_phdata);
*interp_load_addr = load_addr;
return ((unsigned int) interp_elf_ex->e_entry) + load_addr; return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
} }
...@@ -358,7 +338,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -358,7 +338,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
unsigned int elf_bss, k, elf_brk; unsigned int elf_bss, k, elf_brk;
int retval; int retval;
char * elf_interpreter; char * elf_interpreter;
unsigned int elf_entry; unsigned int elf_entry, interp_load_addr = 0;
int status; int status;
unsigned int start_code, end_code, end_data; unsigned int start_code, end_code, end_data;
unsigned int elf_stack; unsigned int elf_stack;
...@@ -385,7 +365,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -385,7 +365,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
!bprm->inode->i_op->default_file_ops->mmap)){ !bprm->inode->i_op->default_file_ops->mmap)){
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return -ENOEXEC; return -ENOEXEC;
}; }
/* Now read in all of the header information */ /* Now read in all of the header information */
...@@ -440,25 +420,30 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -440,25 +420,30 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
#if 0 #if 0
printk("Using ELF interpreter %s\n", elf_interpreter); printk("Using ELF interpreter %s\n", elf_interpreter);
#endif #endif
if(retval >= 0) if(retval >= 0) {
old_fs = get_fs(); /* This could probably be optimized */
set_fs(get_ds());
retval = namei(elf_interpreter, &interpreter_inode); retval = namei(elf_interpreter, &interpreter_inode);
set_fs(old_fs);
}
if(retval >= 0) if(retval >= 0)
retval = read_exec(interpreter_inode,0,bprm->buf,128, 1); 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 */
interp_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ interp_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
}; }
if(retval < 0) { if(retval < 0) {
kfree (elf_phdata); kfree (elf_phdata);
kfree(elf_interpreter); kfree(elf_interpreter);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
}; }
}; }
elf_ppnt++; elf_ppnt++;
}; }
/* Some simple consistency checks for the interpreter */ /* Some simple consistency checks for the interpreter */
if(elf_interpreter){ if(elf_interpreter){
...@@ -468,7 +453,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -468,7 +453,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
kfree(elf_phdata); kfree(elf_phdata);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return -ELIBACC; return -ELIBACC;
}; }
/* Now figure out which format our binary is */ /* Now figure out which format our binary is */
if((N_MAGIC(interp_ex) != OMAGIC) && if((N_MAGIC(interp_ex) != OMAGIC) &&
(N_MAGIC(interp_ex) != ZMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
...@@ -485,7 +470,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -485,7 +470,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
kfree(elf_phdata); kfree(elf_phdata);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return -ELIBBAD; return -ELIBBAD;
}; }
} }
/* OK, we are done with that, now set up the arg stuff, /* OK, we are done with that, now set up the arg stuff,
...@@ -501,8 +486,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -501,8 +486,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if(elf_interpreter) { if(elf_interpreter) {
bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2); bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
bprm->argc++; bprm->argc++;
}; }
}; }
if (!bprm->p) { if (!bprm->p) {
if(elf_interpreter) { if(elf_interpreter) {
kfree(elf_interpreter); kfree(elf_interpreter);
...@@ -548,7 +533,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -548,7 +533,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_aout_interp(&interp_ex, interpreter_inode); load_aout_interp(&interp_ex, interpreter_inode);
if(interpreter_type & 2) elf_entry = if(interpreter_type & 2) elf_entry =
load_elf_interp(&interp_elf_ex, interpreter_inode); load_elf_interp(&interp_elf_ex, interpreter_inode, &interp_load_addr);
old_fs = get_fs(); old_fs = get_fs();
set_fs(get_ds()); set_fs(get_ds());
...@@ -562,8 +547,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -562,8 +547,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
send_sig(SIGSEGV, current, 0); send_sig(SIGSEGV, current, 0);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return 0; return 0;
}; }
}; }
if(elf_ppnt->p_type == PT_LOAD) { if(elf_ppnt->p_type == PT_LOAD) {
...@@ -593,9 +578,9 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -593,9 +578,9 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if(end_data < k) end_data = k; if(end_data < k) end_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
if(k > elf_brk) elf_brk = k; if(k > elf_brk) elf_brk = k;
}; }
elf_ppnt++; elf_ppnt++;
}; }
set_fs(old_fs); set_fs(old_fs);
kfree(elf_phdata); kfree(elf_phdata);
...@@ -627,7 +612,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -627,7 +612,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
bprm->argc, bprm->argc,
bprm->envc, bprm->envc,
(interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL), (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
load_addr, load_addr,
interp_load_addr,
(interpreter_type == INTERPRETER_AOUT ? 0 : 1)); (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
if(interpreter_type == INTERPRETER_AOUT) if(interpreter_type == INTERPRETER_AOUT)
current->mm->arg_start += strlen(passed_fileno) + 1; current->mm->arg_start += strlen(passed_fileno) + 1;
...@@ -714,7 +700,7 @@ load_elf_library(int fd){ ...@@ -714,7 +700,7 @@ load_elf_library(int fd){
(!inode->i_op || !inode->i_op->default_file_ops->mmap)){ (!inode->i_op || !inode->i_op->default_file_ops->mmap)){
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return -ENOEXEC; return -ENOEXEC;
}; }
/* Now read in all of the header information */ /* Now read in all of the header information */
...@@ -737,7 +723,7 @@ load_elf_library(int fd){ ...@@ -737,7 +723,7 @@ load_elf_library(int fd){
kfree(elf_phdata); kfree(elf_phdata);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return -ENOEXEC; return -ENOEXEC;
}; }
while(elf_phdata->p_type != PT_LOAD) elf_phdata++; while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
......
...@@ -45,11 +45,11 @@ static int fillonedir(void * __buf, char * name, int namlen, off_t offset, ino_t ...@@ -45,11 +45,11 @@ static int fillonedir(void * __buf, char * name, int namlen, off_t offset, ino_t
return -EINVAL; return -EINVAL;
buf->count++; buf->count++;
dirent = buf->dirent; dirent = buf->dirent;
put_fs_long(ino, &dirent->d_ino); put_user(ino, &dirent->d_ino);
put_fs_long(offset, &dirent->d_offset); put_user(offset, &dirent->d_offset);
put_fs_word(namlen, &dirent->d_namlen); put_user(namlen, &dirent->d_namlen);
memcpy_tofs(dirent->d_name, name, namlen); memcpy_tofs(dirent->d_name, name, namlen);
put_fs_byte(0, dirent->d_name + namlen); put_user(0, dirent->d_name + namlen);
return 0; return 0;
} }
...@@ -106,10 +106,10 @@ static int filldir(void * __buf, char * name, int namlen, off_t offset, ino_t in ...@@ -106,10 +106,10 @@ static int filldir(void * __buf, char * name, int namlen, off_t offset, ino_t in
put_user(offset, &dirent->d_off); put_user(offset, &dirent->d_off);
dirent = buf->current; dirent = buf->current;
buf->previous = dirent; buf->previous = dirent;
put_fs_long(ino, &dirent->d_ino); put_user(ino, &dirent->d_ino);
put_fs_word(reclen, &dirent->d_reclen); put_user(reclen, &dirent->d_reclen);
memcpy_tofs(dirent->d_name, name, namlen); memcpy_tofs(dirent->d_name, name, namlen);
put_fs_byte(0, dirent->d_name + namlen); put_user(0, dirent->d_name + namlen);
((char *) dirent) += reclen; ((char *) dirent) += reclen;
buf->current = dirent; buf->current = dirent;
buf->count -= reclen; buf->count -= reclen;
......
...@@ -15,6 +15,9 @@ struct consolefontdesc { ...@@ -15,6 +15,9 @@ struct consolefontdesc {
char *chardata; /* font data in expanded form */ char *chardata; /* font data in expanded form */
}; };
#define GIO_CMAP 0x4B70 /* gets colour palette on VGA+ */
#define PIO_CMAP 0x4B71 /* sets colour palette on VGA+ */
#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */ #define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
#define KDMKTONE 0x4B30 /* generate tone */ #define KDMKTONE 0x4B30 /* generate tone */
...@@ -129,6 +132,6 @@ struct kbkeycode { ...@@ -129,6 +132,6 @@ struct kbkeycode {
/* note: 0x4B00-0x4B4E all have had a value at some time; /* note: 0x4B00-0x4B4E all have had a value at some time;
don't reuse for the time being */ don't reuse for the time being */
/* note: 0x4B60-0x4B6C used above */ /* note: 0x4B60-0x4B6C, 0x4B70, 0x4B71 used above */
#endif /* _LINUX_KD_H */ #endif /* _LINUX_KD_H */
...@@ -44,6 +44,7 @@ struct screen_info { ...@@ -44,6 +44,7 @@ struct screen_info {
unsigned short orig_video_ega_bx; unsigned short orig_video_ega_bx;
unsigned short orig_video_ega_cx; unsigned short orig_video_ega_cx;
unsigned char orig_video_lines; unsigned char orig_video_lines;
unsigned char orig_video_isVGA;
unsigned short orig_video_points; unsigned short orig_video_points;
}; };
...@@ -58,12 +59,14 @@ extern struct screen_info screen_info; ...@@ -58,12 +59,14 @@ extern struct screen_info screen_info;
#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx) #define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
#define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx) #define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx)
#define ORIG_VIDEO_LINES (screen_info.orig_video_lines) #define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
#define ORIG_VIDEO_POINTS (screen_info.orig_video_points) #define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
#define VIDEO_TYPE_CGA 0x11 /* CGA Display */ #define VIDEO_TYPE_CGA 0x11 /* CGA Display */
#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ #define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
#define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */ #define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
/* /*
* This character is the same as _POSIX_VDISABLE: it cannot be used as * This character is the same as _POSIX_VDISABLE: it cannot be used as
......
...@@ -39,4 +39,14 @@ struct vt_sizes { ...@@ -39,4 +39,14 @@ struct vt_sizes {
}; };
#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ #define VT_RESIZE 0x5609 /* set kernel's idea of screensize */
struct vt_consize {
ushort v_rows; /* number of rows */
ushort v_cols; /* number of columns */
ushort v_vlin; /* number of pixel rows on screen */
ushort v_clin; /* number of pixel rows per character */
ushort v_vcol; /* number of pixel columns on screen */
ushort v_ccol; /* number of pixel columns per character */
};
#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
#endif /* _LINUX_VT_H */ #endif /* _LINUX_VT_H */
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#ifdef CONFIG_INET #ifdef CONFIG_INET
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/etherdevice.h>
#include <net/protocol.h> #include <net/protocol.h>
#include <net/arp.h> #include <net/arp.h>
#include <net/tcp.h> #include <net/tcp.h>
...@@ -303,6 +304,7 @@ struct symbol_table symbol_table = { ...@@ -303,6 +304,7 @@ struct symbol_table symbol_table = {
X(register_netdev), X(register_netdev),
X(unregister_netdev), X(unregister_netdev),
X(ether_setup), X(ether_setup),
X(eth_type_trans),
X(alloc_skb), X(alloc_skb),
X(kfree_skb), X(kfree_skb),
X(dev_kfree_skb), X(dev_kfree_skb),
......
...@@ -30,3 +30,12 @@ NORET_TYPE void panic(const char * fmt, ...) ...@@ -30,3 +30,12 @@ NORET_TYPE void panic(const char * fmt, ...)
sys_sync(); sys_sync();
for(;;); for(;;);
} }
/*
* GCC 2.5.8 doesn't always optimize correctly; see include/asm/segment.h
*/
int bad_user_access_length(void)
{
panic("bad_user_access_length executed (not cool, dude)");
}
...@@ -831,10 +831,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -831,10 +831,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
if (pte_dirty(from)) { if (pte_dirty(from)) {
if (!(from_area->vm_flags & VM_SHARED)) if (!(from_area->vm_flags & VM_SHARED))
return 0; return 0;
if (pte_write(from)) {
printk("nonwritable, but dirty, shared page\n");
return 0;
}
} }
/* is the page reasonable at all? */ /* is the page reasonable at all? */
if (pte_page(from) >= high_memory) if (pte_page(from) >= high_memory)
...@@ -869,10 +865,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are ...@@ -869,10 +865,6 @@ static int try_to_share(unsigned long to_address, struct vm_area_struct * to_are
if (in_swap_cache(pte_page(from))) { if (in_swap_cache(pte_page(from))) {
if (!(from_area->vm_flags & VM_SHARED)) if (!(from_area->vm_flags & VM_SHARED))
return 0; return 0;
if (!pte_write(from)) {
printk("nonwritable, but dirty, shared page\n");
return 0;
}
} }
copy_page(pte_page(from), newpage); copy_page(pte_page(from), newpage);
*to_table = mk_pte(newpage, to_area->vm_page_prot); *to_table = mk_pte(newpage, to_area->vm_page_prot);
......
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