diff -u --recursive --new-file v1.3.2/linux/Makefile linux/Makefile --- v1.3.2/linux/Makefile Fri Jun 16 22:02:54 1995 +++ linux/Makefile Sun Jun 18 18:15:08 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 2 +SUBLEVEL = 3 ARCH = i386 diff -u --recursive --new-file v1.3.2/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c --- v1.3.2/linux/arch/i386/boot/compressed/misc.c Sun Feb 19 11:15:16 1995 +++ linux/arch/i386/boot/compressed/misc.c Sun Jun 18 18:11:37 1995 @@ -28,6 +28,7 @@ unsigned short orig_video_ega_bx; unsigned short orig_video_ega_cx; unsigned char orig_video_lines; + unsigned char orig_video_isVGA; }; /* diff -u --recursive --new-file v1.3.2/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S --- v1.3.2/linux/arch/i386/boot/setup.S Tue Jun 13 15:40:16 1995 +++ linux/arch/i386/boot/setup.S Sun Jun 18 18:11:37 1995 @@ -160,10 +160,12 @@ int 0x10 mov bx,ax mov ax,#0x5019 + movb [15],#0 ! by default, no VGA 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 -novga: mov [14],ax +novga: mov [14],al mov ah,#0x03 ! read cursor pos xor bh,bh ! clear bh int 0x10 ! save it in known place, con_init fetches diff -u --recursive --new-file v1.3.2/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile --- v1.3.2/linux/arch/i386/lib/Makefile Fri Jun 16 22:02:54 1995 +++ linux/arch/i386/lib/Makefile Sun Jun 18 18:11:36 1995 @@ -17,6 +17,8 @@ dep: +modules: + # # include a dependency file if one exists # diff -u --recursive --new-file v1.3.2/linux/drivers/char/console.c linux/drivers/char/console.c --- v1.3.2/linux/drivers/char/console.c Tue Jun 13 15:40:16 1995 +++ linux/drivers/char/console.c Sun Jun 18 18:11:37 1995 @@ -37,6 +37,12 @@ * 'int con_set_font(char *data, int ch512)' * 'int con_adjust_height(int fontheight)' * + * 'int con_get_cmap(char *)' + * 'int con_set_cmap(char *)' + * + * 'int reset_palette(int currcons)' + * 'void set_palette(void)' + * * 'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)' * 'int mouse_reporting(void)' * @@ -67,10 +73,14 @@ * * Improved loadable font/UTF-8 support by H. Peter Anvin, Feb 1995 * + * improved scrollback, plus colour palette handling, by Simon Tatham + * 17-Jun-95 + * */ #define BLANK 0x0020 #define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */ +#define CAN_LOAD_PALETTE /* undefine if the user must not do this */ /* A bitmap for codes <32. A bit of 1 indicates that the code * corresponding to that bit number invokes some special action @@ -145,6 +155,8 @@ extern void vesa_unblank(void); extern void compute_shiftstate(void); extern int conv_uni_to_pc(long ucs); +extern void reset_palette (int currcons) ; +extern void set_palette (void) ; /* Description of the hardware situation */ static unsigned char video_type; /* Type of display being used */ @@ -164,7 +176,7 @@ /* these two also used in in vt.c */ int video_mode_512ch = 0; /* 512-character mode */ unsigned long video_font_height; /* Height of current screen font */ -static unsigned long video_scan_lines; /* Number of scan lines on screen */ + unsigned long video_scan_lines; /* Number of scan lines on screen */ static unsigned short console_charmask = 0x0ff; static unsigned short *vc_scrbuf[MAX_NR_CONSOLES]; @@ -224,6 +236,7 @@ unsigned char vc_utf_count; long vc_utf_char; unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */ + unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */ unsigned short * vc_translate; unsigned char vc_G0_charset; unsigned char vc_G1_charset; @@ -296,6 +309,7 @@ #define ulcolor (vc_cons[currcons].d->vc_ulcolor) #define halfcolor (vc_cons[currcons].d->vc_halfcolor) #define tab_stop (vc_cons[currcons].d->vc_tab_stop) +#define palette (vc_cons[currcons].d->vc_palette) #define vcmode (vt_cons[currcons]->vc_mode) #define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct)) @@ -490,6 +504,14 @@ static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15 }; +/* the default colour table, for VGA+ colour systems */ +static int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, + 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff}; +static int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, + 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff}; +static int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, + 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; + /* * gotoxy() must verify all boundaries, because the arguments * might also be negative. If the given position is out of @@ -523,10 +545,14 @@ } /* - * *Very* limited hardware scrollback support.. + * Hardware scrollback support */ static unsigned short __real_origin; -static unsigned short __origin; /* offset of currently displayed screen */ +static unsigned short __origin; /* offset of currently displayed screen */ +#define last_lpos (((video_mem_term-video_mem_base)/video_num_columns/2)-video_num_lines+1) +#define last_origin_rel ( last_lpos * video_num_columns ) +#define last_origin ( video_mem_base + last_origin_rel * 2 ) +static unsigned short __scrollback_mode; /* 1 means scrollback can wrap */ static inline void __set_origin(unsigned short offset) { @@ -549,8 +575,27 @@ lines = video_num_lines/2; lines *= video_num_columns; lines = __origin - lines; - if (lines < 0) - lines = 0; + if (__scrollback_mode == 0) { + if (lines < 0) + lines = 0; + } else { + int s_top = __real_origin+video_num_lines*video_num_columns ; + if (lines < 0) { + int count ; + unsigned short * d = (unsigned short *) video_mem_base; + unsigned short * s = (unsigned short *) last_origin; + + lines += last_origin_rel; + /* in case the top part of the screen has been modified since + * the scroll wrapped, copy the top bit back to the bottom */ + count = (video_num_lines-1)*video_num_columns; + while (count) { + count--; + scr_writew(scr_readw(d++),s++); + } + } else if (__origin > __real_origin && lines < s_top) + lines = s_top ; + } __set_origin(lines); } @@ -559,15 +604,26 @@ if (!lines) lines = video_num_lines/2; lines *= video_num_columns; - lines = __origin + lines; - if (lines > __real_origin) - lines = __real_origin; + if (__origin > __real_origin) { + /* assume __scrollback_mode == 1 */ + lines += __origin; + if (lines >= last_origin_rel) { + lines -= last_origin_rel ; + if (lines > __real_origin) + lines = __real_origin; + } + } else { + lines += __origin; + if (lines > __real_origin) + lines = __real_origin; + } __set_origin(lines); } static void set_origin(int currcons) { - if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) + if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC + && video_type != VIDEO_TYPE_EGAM) return; if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS) return; @@ -614,7 +670,8 @@ if (b > video_num_lines || t >= b) return; - if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) + if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC + && video_type != VIDEO_TYPE_EGAM) hardscroll = 0; else if (t || b != video_num_lines) hardscroll = 0; @@ -622,7 +679,7 @@ origin += video_size_row; pos += video_size_row; scr_end += video_size_row; - if (scr_end > video_mem_end) { + if (origin >= last_origin) { unsigned short * d = (unsigned short *) video_mem_start; unsigned short * s = (unsigned short *) origin; unsigned int count; @@ -641,6 +698,8 @@ pos -= origin-video_mem_start; origin = video_mem_start; has_scrolled = 1; + if (currcons == fg_console) + __scrollback_mode = 1; } else { unsigned short * d; unsigned int count; @@ -651,6 +710,8 @@ count--; scr_writew(video_erase_char, d++); } + if (scr_end > last_origin) /* we've wrapped into kept region */ + __scrollback_mode = 0; } set_origin(currcons); } else { @@ -1266,7 +1327,8 @@ } enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, - EShash, ESsetG0, ESsetG1, ESpercent, ESignore }; + EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd, + ESpalette }; static void reset_terminal(int currcons, int do_clear) { @@ -1515,6 +1577,9 @@ case '[': vc_state = ESsquare; continue; + case ']': + vc_state = ESnonstd; + continue; case '%': vc_state = ESpercent; continue; @@ -1560,6 +1625,36 @@ continue; } continue; + case ESnonstd: + if (c=='P') { /* palette escape sequence */ + for (npar=0; npar='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) { + par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ; + if (npar==7) { + int i = par[0]*3, j = 1; + palette[i] = 16*par[j++]; + palette[i++] += par[j++]; + palette[i] = 16*par[j++]; + palette[i++] += par[j++]; + palette[i] = 16*par[j++]; + palette[i] += par[j]; + set_palette() ; + vc_state = ESnormal; + } + } else + vc_state = ESnormal; + continue; case ESsquare: for(npar = 0 ; npar < NPAR ; npar++) par[npar] = 0; @@ -1853,6 +1948,7 @@ static void vc_init(unsigned int currcons, unsigned long rows, unsigned long cols, int do_clear) { long base = (long) vc_scrbuf[currcons]; + int j, k ; video_num_columns = cols; video_num_lines = rows; @@ -1863,6 +1959,11 @@ scr_end = base + video_screen_size; video_mem_end = base + video_screen_size; reset_vc(currcons); + for (j=k=0; j<16; j++) { + vc_cons[currcons].d->vc_palette[k++] = default_red[j] ; + vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ; + vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ; + } def_color = 0x07; /* white */ ulcolor = 0x0f; /* bold white */ halfcolor = 0x08; /* grey */ @@ -1925,6 +2026,7 @@ con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS); video_page = ORIG_VIDEO_PAGE; /* never used */ + __scrollback_mode = 0 ; timer_table[BLANK_TIMER].fn = blank_screen; timer_table[BLANK_TIMER].expires = 0; @@ -1943,16 +2045,14 @@ video_type = VIDEO_TYPE_EGAM; video_mem_term = 0xb8000; display_desc = "EGA+"; - request_region(0x3b4,2,"ega+"); + request_region(0x3b0,16,"ega"); } else { video_type = VIDEO_TYPE_MDA; video_mem_term = 0xb2000; display_desc = "*MDA"; - request_region(0x3b4,2,"mda"); - request_region(0x3b8,1,"mda"); - request_region(0x3bf,1,"mda"); + request_region(0x3b0,16,"mda"); } } else /* If not, it is color. */ @@ -1963,10 +2063,44 @@ video_port_val = 0x3d5; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { - video_type = VIDEO_TYPE_EGAC; - video_mem_term = 0xc0000; - display_desc = "EGA+"; - request_region(0x3d4,2,"ega+"); + int i ; + + video_mem_term = 0xc0000; + + if (!ORIG_VIDEO_ISVGA) { + video_type = VIDEO_TYPE_EGAC; + display_desc = "EGA"; + request_region(0x3c0,32,"ega"); + } else { + video_type = VIDEO_TYPE_VGAC; + display_desc = "VGA+"; + request_region(0x3c0,32,"vga+"); + + /* get 64K rather than 32K of video RAM */ + video_mem_base = 0xa0000 ; + video_mem_term = 0xb0000 ; + outb_p (6, 0x3ce) ; + outb_p (6, 0x3cf) ; + + /* normalise the palette registers, to point the * 16 screen colours to the first 16 DAC entries */ + + for (i=0; i<16; i++) { + inb_p (0x3da) ; + outb_p (i, 0x3c0) ; + outb_p (i, 0x3c0) ; + } + outb_p (0x20, 0x3c0) ; + + /* now set the DAC registers back to their default + * values */ + + for (i=0; i<16; i++) { + outb_p (color_table[i], 0x3c8) ; + outb_p (default_red[i], 0x3c9) ; + outb_p (default_grn[i], 0x3c9) ; + outb_p (default_blu[i], 0x3c9) ; + } + } } else { @@ -1982,6 +2116,8 @@ /* Due to kmalloc roundup allocating statically is more efficient - so provide MIN_NR_CONSOLES for people with very little memory */ for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { + int j, k ; + vc_cons[currcons].d = (struct vc_data *) kmem_start; kmem_start += sizeof(struct vc_data); vt_cons[currcons] = (struct vt_struct *) kmem_start; @@ -1990,7 +2126,12 @@ kmem_start += video_screen_size; kmalloced = 0; screenbuf_size = video_screen_size; - vc_init(currcons, video_num_lines, video_num_columns, currcons); + vc_init(currcons, video_num_lines, video_num_columns, currcons); + for (j=k=0; j<16; j++) { + vc_cons[currcons].d->vc_palette[k++] = default_red[j] ; + vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ; + vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ; + } } currcons = fg_console = 0; @@ -2008,7 +2149,8 @@ can figure out the appropriate screen size should we load a different font */ - if ( video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM ) + if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC + || video_type == VIDEO_TYPE_EGAM ) { video_font_height = ORIG_VIDEO_POINTS; /* This may be suboptimal but is a safe bet - go with it */ @@ -2031,6 +2173,7 @@ { memcpyw((unsigned short *)vc_scrbuf[currcons], (unsigned short *)origin, video_screen_size); + __scrollback_mode = 0 ; origin = video_mem_start = (unsigned long)vc_scrbuf[currcons]; scr_end = video_mem_end = video_mem_start + video_screen_size; pos = origin + y*video_size_row + (x<<1); @@ -2098,7 +2241,8 @@ set_origin(fg_console); get_scrmem(fg_console); unblank_origin = origin; - memsetw((void *)blank_origin, BLANK, video_mem_term-blank_origin); + memsetw((void *)blank_origin, BLANK, + 2*video_num_lines*video_num_columns); hide_cursor(); console_blanked = fg_console + 1; @@ -2247,9 +2391,9 @@ /* no use to "load" CGA... */ - if (video_type == VIDEO_TYPE_EGAC) { + if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_VGAC) { charmap = colourmap; - beg = 0x0e; + beg = (video_type == VIDEO_TYPE_VGAC ? 0x06 : 0x0e) ; } else if (video_type == VIDEO_TYPE_EGAM) { charmap = blackwmap; beg = 0x0a; @@ -2344,6 +2488,94 @@ #endif } +#define dac_reg (0x3c8) +#define dac_val (0x3c9) + +static int set_get_cmap(unsigned char * arg, int set) { +#ifdef CAN_LOAD_PALETTE + int i; + + /* no use to set colourmaps in less than colour VGA */ + + if (video_type != VIDEO_TYPE_VGAC) + return -EINVAL; + + i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, 16*3); + if (i) + return i; + + for (i=0; i<16; i++) { + if (set) { + default_red[i] = get_user(arg++) ; + default_grn[i] = get_user(arg++) ; + default_blu[i] = get_user(arg++) ; + } else { + put_user (default_red[i], arg++) ; + put_user (default_grn[i], arg++) ; + put_user (default_blu[i], arg++) ; + } + } + if (set) { + for (i=0; ivc_palette[k++] = default_red[j]; + vc_cons[i].d->vc_palette[k++] = default_grn[j]; + vc_cons[i].d->vc_palette[k++] = default_blu[j]; + } + } + set_palette() ; + } + + return 0; +#else + return -EINVAL; +#endif +} + +/* + * Load palette into the EGA/VGA DAC registers. arg points to a colour + * map, 3 bytes per colour, 16 colours, range from 0 to 255. + */ + +int con_set_cmap (unsigned char *arg) +{ + return set_get_cmap (arg,1); +} + +int con_get_cmap (unsigned char *arg) +{ + return set_get_cmap (arg,0); +} + +void reset_palette (int currcons) +{ + int j, k ; + for (j=k=0; j<16; j++) { + palette[k++] = default_red[j]; + palette[k++] = default_grn[j]; + palette[k++] = default_blu[j]; + } + set_palette() ; +} + +void set_palette (void) +{ + int i, j ; + + if (video_type != VIDEO_TYPE_VGAC || console_blanked || + vt_cons[fg_console]->vc_mode == KD_GRAPHICS) + return ; + + for (i=j=0; i<16; i++) { + outb_p (color_table[i], dac_reg) ; + outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ; + outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ; + outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ; + } +} + /* * Load font into the EGA/VGA character generator. arg points to a 8192 * byte map, 32 bytes per character. Only first H of them are used for @@ -2379,9 +2611,9 @@ int rows, maxscan; unsigned char ovr, vde, fsr, curs, cure; - if (fontheight > 32 || - (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)) - return -EINVAL; + if (fontheight > 32 || (video_type != VIDEO_TYPE_VGAC && + video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)) + return -EINVAL; if ( fontheight == video_font_height || fontheight == 0 ) return 0; diff -u --recursive --new-file v1.3.2/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v1.3.2/linux/drivers/char/tty_io.c Tue Jun 6 11:22:06 1995 +++ linux/drivers/char/tty_io.c Sun Jun 18 18:11:37 1995 @@ -102,6 +102,9 @@ unsigned int cmd, unsigned long arg); 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 #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif @@ -497,6 +500,7 @@ vt_cons[new_console]->vt_mode.frsig = 0; vt_cons[new_console]->vt_pid = -1; vt_cons[new_console]->vt_newvt = -1; + reset_palette (new_console) ; } /* @@ -561,6 +565,10 @@ 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 */ diff -u --recursive --new-file v1.3.2/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v1.3.2/linux/drivers/char/vt.c Tue Jun 13 15:40:16 1995 +++ linux/drivers/char/vt.c Sun Jun 18 18:11:37 1995 @@ -63,7 +63,8 @@ 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_get_trans_old(char * table); @@ -74,10 +75,14 @@ extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list); extern int con_set_font(char * fontmap, int ch512); 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 video_mode_512ch; 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 @@ -95,13 +100,13 @@ * tty. */ -static void +static int kd_size_changed(int row, int col) { struct task_struct *p; int i; - if ( !row && !col ) return; + if ( !row && !col ) return 0; for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ ) { @@ -120,6 +125,8 @@ send_sig(SIGWINCH, p, 1); } } + + return 0; } /* @@ -864,7 +871,61 @@ return i; ll = get_fs_word(&vtsizes->v_rows); 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: @@ -882,6 +943,16 @@ return con_get_font((char *)arg); /* 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: { struct consolefontdesc cfdarg; @@ -903,9 +974,7 @@ if (i) return i; i = con_adjust_height(cfdarg.charheight); - if (i <= 0) return i; - kd_size_changed(i, 0); - return 0; + return (i <= 0) ? i : kd_size_changed(i, 0); } else return -EINVAL; } diff -u --recursive --new-file v1.3.2/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v1.3.2/linux/drivers/net/8390.c Fri Jun 16 22:02:54 1995 +++ linux/drivers/net/8390.c Sun Jun 18 18:11:37 1995 @@ -16,9 +16,9 @@ This is not a complete driver, it must be combined with board-specific code such as ne.c, wd.c, 3c503.c, etc. - 13/04/95 -- Don't blindly swallow ENISR_RDC interrupts for non-shared - memory cards. We need to follow these closely for neX000 cards. - Plus other minor cleanups. -- Paul Gortmaker + Changelog: + + Paul Gortmaker : remove set_bit lock, other cleanups. */ @@ -129,7 +129,6 @@ int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int length, send_length; - unsigned long flags; /* * We normally shouldn't be called if dev->tbusy is set, but the @@ -177,22 +176,14 @@ if (skb->len <= 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. */ 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; - restore_flags(flags); send_length = ETH_ZLEN < length ? length : ETH_ZLEN; @@ -314,17 +305,17 @@ 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 (dev->mem_start) outb_p(ENISR_RDC, e8390_base + EN0_ISR); } 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); - if (nr_serviced == MAX_SERVICE) { + if (nr_serviced >= MAX_SERVICE) { printk("%s: Too much work at interrupt, status %#2.2x\n", dev->name, interrupts); outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ @@ -501,7 +492,7 @@ ei_local->current_page = next_frame; 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 when we get to the bottom-half routine. */ diff -u --recursive --new-file v1.3.2/linux/drivers/net/8390.h linux/drivers/net/8390.h --- v1.3.2/linux/drivers/net/8390.h Tue May 2 08:01:57 1995 +++ linux/drivers/net/8390.h Sun Jun 18 18:11:37 1995 @@ -45,12 +45,12 @@ unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ unsigned txing:1; /* Transmit Active */ unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ + unsigned dmaing:1; /* Remote DMA Active */ unsigned pingpong:1; /* Using the ping-pong driver */ unsigned char tx_start_page, rx_start_page, stop_page; unsigned char current_page; /* Read pointer in buffer */ unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ 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 lasttx; /* Alpha version consistency check. */ unsigned char reg0; /* Register '0' in a WD8013 */ diff -u --recursive --new-file v1.3.2/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v1.3.2/linux/drivers/net/ne.c Tue May 2 08:02:12 1995 +++ linux/drivers/net/ne.c Sun Jun 18 18:12:25 1995 @@ -16,12 +16,10 @@ boards. Currently it supports the NE1000, NE2000, many clones, and some Cabletron products. - 13/04/95 -- Change in philosophy. We now monitor ENISR_RDC for - 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 - kick the board before it locks the system. Also use set_bit() to - create atomic locks on the PIO xfers, and added some defines - that the end user can play with to save memory. -- Paul Gortmaker + Changelog: + + Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made + sanity checks and bad clone support optional. */ @@ -335,6 +333,7 @@ if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies); ei_status.txing = 0; + ei_status.dmaing = 0; outb_p(tmp, NE_BASE + NE_RESET); /* This check _should_not_ be necessary, omit eventually. */ @@ -343,10 +342,11 @@ printk("%s: ne_reset_8390() did not complete.\n", dev->name); break; } + outb_p(ENISR_RESET, NE_BASE + NE_RESET); /* Ack intr. */ } /* 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 packet out through the "remote DMA" dataport using outb. */ @@ -359,7 +359,7 @@ int nic_base = dev->base_addr; /* 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) printk("%s: DMAing conflict in ne_block_input " "[DMAstat:%d][irqlock:%d][intr:%d].\n", @@ -367,7 +367,7 @@ dev->interrupt); return 0; } - ei_status.dmaing |= 0x02; + ei_status.dmaing |= 0x01; outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); outb_p(count & 0xff, nic_base + EN0_RCNTLO); outb_p(count >> 8, nic_base + EN0_RCNTHI); @@ -409,7 +409,7 @@ } #endif outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x03; + ei_status.dmaing &= ~0x01; return ring_offset + count; } @@ -430,7 +430,7 @@ count++; /* 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) printk("%s: DMAing conflict in ne_block_output." "[DMAstat:%d][irqlock:%d][intr:%d]\n", @@ -438,7 +438,7 @@ dev->interrupt); return; } - ei_status.dmaing |= 0x04; + ei_status.dmaing |= 0x01; /* We should already be in page 0, but to be safe... */ outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); @@ -510,7 +510,7 @@ } outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x05; + ei_status.dmaing &= ~0x01; return; } diff -u --recursive --new-file v1.3.2/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v1.3.2/linux/drivers/net/ppp.c Tue Jun 6 11:22:10 1995 +++ linux/drivers/net/ppp.c Sun Jun 18 18:11:36 1995 @@ -504,6 +504,9 @@ ppp_release (ppp); PRINTKN (2,(KERN_INFO "ppp: channel %s closing.\n", ppp->dev->name)); +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } } @@ -612,9 +615,6 @@ PRINTKN (2,(KERN_INFO "ppp: channel %s going down for IP packets!\n", dev->name)); CHECK_PPP(-ENXIO); -#ifdef MODULE - MOD_DEC_USE_COUNT; -#endif return 0; } diff -u --recursive --new-file v1.3.2/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v1.3.2/linux/fs/binfmt_elf.c Fri Jun 16 22:02:55 1995 +++ linux/fs/binfmt_elf.c Sun Jun 18 18:09:21 1995 @@ -78,7 +78,7 @@ } } -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 * sp; @@ -129,11 +129,11 @@ 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(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(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++); put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++); - }; + } put_fs_long((unsigned long)argc,--sp); current->mm->arg_start = (unsigned long) p; @@ -159,7 +159,7 @@ an ELF header */ 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 elf_phdr *elf_phdata = NULL; @@ -184,7 +184,7 @@ (!interpreter_inode->i_op || !interpreter_inode->i_op->default_file_ops->mmap)){ return 0xffffffff; - }; + } /* Now read in all of the header information */ @@ -202,52 +202,32 @@ if (elf_exec_fileno < 0) return 0xffffffff; 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; ie_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; for(i=0; ie_phnum; i++, eppnt++) 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_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, - load_addr + (eppnt->p_vaddr & 0xfffff000), - eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), + vaddr & 0xfffff000, + eppnt->p_filesz + (vaddr & 0xfff), elf_prot, - MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED, + elf_type, eppnt->p_offset & 0xfffff000); 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 * track of the largest address we see for this. @@ -265,7 +245,6 @@ /* Now use mmap to map the library into memory. */ -oops: SYS(close)(elf_exec_fileno); if(error < 0 && error > -1024) { kfree(elf_phdata); @@ -288,6 +267,7 @@ MAP_FIXED|MAP_PRIVATE, 0); kfree(elf_phdata); + *interp_load_addr = load_addr; return ((unsigned int) interp_elf_ex->e_entry) + load_addr; } @@ -358,7 +338,7 @@ unsigned int elf_bss, k, elf_brk; int retval; char * elf_interpreter; - unsigned int elf_entry; + unsigned int elf_entry, interp_load_addr = 0; int status; unsigned int start_code, end_code, end_data; unsigned int elf_stack; @@ -385,7 +365,7 @@ !bprm->inode->i_op->default_file_ops->mmap)){ MOD_DEC_USE_COUNT; return -ENOEXEC; - }; + } /* Now read in all of the header information */ @@ -440,25 +420,30 @@ #if 0 printk("Using ELF interpreter %s\n", elf_interpreter); #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); + set_fs(old_fs); + } + if(retval >= 0) 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_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ - }; + } if(retval < 0) { - kfree (elf_phdata); - kfree(elf_interpreter); - MOD_DEC_USE_COUNT; - return retval; - }; - }; + kfree (elf_phdata); + kfree(elf_interpreter); + MOD_DEC_USE_COUNT; + return retval; + } + } elf_ppnt++; - }; + } /* Some simple consistency checks for the interpreter */ if(elf_interpreter){ @@ -468,7 +453,7 @@ kfree(elf_phdata); MOD_DEC_USE_COUNT; return -ELIBACC; - }; + } /* Now figure out which format our binary is */ if((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) && @@ -485,7 +470,7 @@ kfree(elf_phdata); MOD_DEC_USE_COUNT; return -ELIBBAD; - }; + } } /* OK, we are done with that, now set up the arg stuff, @@ -501,8 +486,8 @@ if(elf_interpreter) { bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2); bprm->argc++; - }; - }; + } + } if (!bprm->p) { if(elf_interpreter) { kfree(elf_interpreter); @@ -548,7 +533,7 @@ load_aout_interp(&interp_ex, interpreter_inode); 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(); set_fs(get_ds()); @@ -562,8 +547,8 @@ send_sig(SIGSEGV, current, 0); MOD_DEC_USE_COUNT; return 0; - }; - }; + } + } if(elf_ppnt->p_type == PT_LOAD) { @@ -593,9 +578,9 @@ if(end_data < k) end_data = k; k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; if(k > elf_brk) elf_brk = k; - }; + } elf_ppnt++; - }; + } set_fs(old_fs); kfree(elf_phdata); @@ -627,7 +612,8 @@ bprm->argc, bprm->envc, (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL), - load_addr, + load_addr, + interp_load_addr, (interpreter_type == INTERPRETER_AOUT ? 0 : 1)); if(interpreter_type == INTERPRETER_AOUT) current->mm->arg_start += strlen(passed_fileno) + 1; @@ -714,7 +700,7 @@ (!inode->i_op || !inode->i_op->default_file_ops->mmap)){ MOD_DEC_USE_COUNT; return -ENOEXEC; - }; + } /* Now read in all of the header information */ @@ -737,7 +723,7 @@ kfree(elf_phdata); MOD_DEC_USE_COUNT; return -ENOEXEC; - }; + } while(elf_phdata->p_type != PT_LOAD) elf_phdata++; diff -u --recursive --new-file v1.3.2/linux/fs/readdir.c linux/fs/readdir.c --- v1.3.2/linux/fs/readdir.c Thu Jun 8 17:27:33 1995 +++ linux/fs/readdir.c Sun Jun 18 17:05:52 1995 @@ -45,11 +45,11 @@ return -EINVAL; buf->count++; dirent = buf->dirent; - put_fs_long(ino, &dirent->d_ino); - put_fs_long(offset, &dirent->d_offset); - put_fs_word(namlen, &dirent->d_namlen); + put_user(ino, &dirent->d_ino); + put_user(offset, &dirent->d_offset); + put_user(namlen, &dirent->d_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; } @@ -106,10 +106,10 @@ put_user(offset, &dirent->d_off); dirent = buf->current; buf->previous = dirent; - put_fs_long(ino, &dirent->d_ino); - put_fs_word(reclen, &dirent->d_reclen); + put_user(ino, &dirent->d_ino); + put_user(reclen, &dirent->d_reclen); 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; buf->current = dirent; buf->count -= reclen; diff -u --recursive --new-file v1.3.2/linux/include/linux/kd.h linux/include/linux/kd.h --- v1.3.2/linux/include/linux/kd.h Tue Jun 13 15:40:17 1995 +++ linux/include/linux/kd.h Sun Jun 18 18:11:37 1995 @@ -15,6 +15,9 @@ 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 KDMKTONE 0x4B30 /* generate tone */ @@ -129,6 +132,6 @@ /* note: 0x4B00-0x4B4E all have had a value at some time; don't reuse for the time being */ -/* note: 0x4B60-0x4B6C used above */ +/* note: 0x4B60-0x4B6C, 0x4B70, 0x4B71 used above */ #endif /* _LINUX_KD_H */ diff -u --recursive --new-file v1.3.2/linux/include/linux/tty.h linux/include/linux/tty.h --- v1.3.2/linux/include/linux/tty.h Fri Jun 16 22:02:56 1995 +++ linux/include/linux/tty.h Sun Jun 18 18:11:37 1995 @@ -44,6 +44,7 @@ unsigned short orig_video_ega_bx; unsigned short orig_video_ega_cx; unsigned char orig_video_lines; + unsigned char orig_video_isVGA; unsigned short orig_video_points; }; @@ -58,12 +59,14 @@ #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_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 VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ #define VIDEO_TYPE_CGA 0x11 /* CGA Display */ #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 diff -u --recursive --new-file v1.3.2/linux/include/linux/vt.h linux/include/linux/vt.h --- v1.3.2/linux/include/linux/vt.h Thu Oct 13 14:07:09 1994 +++ linux/include/linux/vt.h Sun Jun 18 18:11:38 1995 @@ -39,4 +39,14 @@ }; #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 */ diff -u --recursive --new-file v1.3.2/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.3.2/linux/kernel/ksyms.c Fri Jun 16 22:02:56 1995 +++ linux/kernel/ksyms.c Sun Jun 18 18:11:36 1995 @@ -39,6 +39,7 @@ #include #ifdef CONFIG_INET #include +#include #include #include #include @@ -303,6 +304,7 @@ X(register_netdev), X(unregister_netdev), X(ether_setup), + X(eth_type_trans), X(alloc_skb), X(kfree_skb), X(dev_kfree_skb), diff -u --recursive --new-file v1.3.2/linux/kernel/panic.c linux/kernel/panic.c --- v1.3.2/linux/kernel/panic.c Wed Mar 1 13:31:54 1995 +++ linux/kernel/panic.c Sun Jun 18 18:11:38 1995 @@ -30,3 +30,12 @@ sys_sync(); 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)"); +} diff -u --recursive --new-file v1.3.2/linux/mm/memory.c linux/mm/memory.c --- v1.3.2/linux/mm/memory.c Fri Jun 16 22:02:56 1995 +++ linux/mm/memory.c Sat Jun 17 10:32:08 1995 @@ -831,10 +831,6 @@ if (pte_dirty(from)) { if (!(from_area->vm_flags & VM_SHARED)) return 0; - if (pte_write(from)) { - printk("nonwritable, but dirty, shared page\n"); - return 0; - } } /* is the page reasonable at all? */ if (pte_page(from) >= high_memory) @@ -869,10 +865,6 @@ if (in_swap_cache(pte_page(from))) { if (!(from_area->vm_flags & VM_SHARED)) return 0; - if (!pte_write(from)) { - printk("nonwritable, but dirty, shared page\n"); - return 0; - } } copy_page(pte_page(from), newpage); *to_table = mk_pte(newpage, to_area->vm_page_prot);