N: Dario Ballabio
E: dario@milano.europe.dg.com
D: Author and maintainer of the Ultrastor 14F/34F SCSI driver
-D: Author and maintainer of the EATA ISA/EISA SCSI driver
+D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver
S: Data General Corporation
S: Milano
S: Italy
UltraStor 14F/34F support
CONFIG_SCSI_U14_34F
- This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
- adaptor family. The source at drivers/scsi/u14-34f.c contains some
- information about this hardware. If the driver doesn't work out of
- the box, you may have to change some settings in
- drivers/scsi/u14-34f.h. Read the SCSI-HOWTO, available via ftp
- (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note
- that there is also another driver for the same hardware: "UltraStor
- SCSI support", below. You should only enable one of them. This
+ This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
+ The source at drivers/scsi/u14-34f.c contains some information about
+ this hardware. If the driver doesn't work out of the box, you may have
+ to change some settings in drivers/scsi/u14-34f.c.
+ Read the SCSI-HOWTO, available via ftp (user: anonymous) at
+ sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that there is also another
+ driver for the same hardware: "UltraStor SCSI support", below.
+ You should enable both only if you want 24F support as well. This
driver is also available as a module ( = code which can be inserted
in and removed from the running kernel whenever you want). If you
want to compile it as a module, say M here and read
drivers/scsi/ultrastor.h. If you want to compile this as a module (
= code which can be inserted in and removed from the running kernel
whenever you want), say M here and read Documentation/modules.txt.
- Note that there is also another driver for the same hardware:
- "UltraStor 14F/34F support", above. You should only enable one of
- them.
+ Note that there is also another driver for UltraStor hardware:
+ "UltraStor 14F/34F support", above.
7000FASST SCSI support
CONFIG_SCSI_7000FASST
want to compile it as a module, say M here and read
Documentation/modules.txt.
-EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support
+EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support
CONFIG_SCSI_EATA
- This driver supports all the DPT SCSI host adapters, such as
- PM2011B/9X, PM2021A/9X, PM2012A, PM1012B, PM2022A/9X, PM2122A/9X and
- PM2322A/9X. Note that the PM2001 is not supported by this
- driver. You want to read the start of drivers/scsi/eata.c and the
+ This driver supports all the EATA/DMA-compliant SCSI host adapters
+ and does not need any BIOS32 or PCI BIOS service.
+ Only ISA (0x1F0, 0x170, 0x230, 0x330) and EISA (0x1C88 through 0xFC88)
+ addresses are probed. In order to detect a generic EATA PCI board you
+ can force on it any unused EISA address.
+ Note that there is also another driver for the same hardware:
+ "EATA-DMA support". You should enable only one of them.
+ You want to read the start of drivers/scsi/eata.c and the
SCSI-HOWTO, available via ftp (user: anonymous) at
sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you want to compile this
as a module ( = code which can be inserted in and removed from the
- Java(tm) Binary Kernel Support for Linux v1.01
+ Java(tm) Binary Kernel Support for Linux v1.02
----------------------------------------------
Linux beats them ALL! While all other OS's are TALKING about direct
ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
- If you install the JDK in a location other than the suggested
- directory of /usr/local/java, then you will need to tell the
- kernel where you put the Java interpreter.
+ If you install the JDK in a location other than /usr/bin/java,
+ then you will need to tell the kernel where you put the Java
+ interpreter.
There are two ways to do this.
One, edit fs/binfmt_java.c file and make the needed change to
the _PATH_JAVA definition at the top of that file.
as a loadable module. If a module, load it with insmod or
kerneld.
+ 5) A caveat. When executing a java file, the java interpreter is
+ invoked only with the class name, not with the complete file path.
+ Therefore it is possible that the file the shell finds with PATH
+ is not the same file the java interpreter finds with CLASSPATH.
+ The recommended solution is to make symbolic links from a directory
+ in PATH to the actual class file in CLASSPATH, e.g.,
+ /usr/local/bin/myapp -> /usr/local/java/classes/myapp.class.
+
To test your new setup, enter in the following simple Java app, and name
it "HelloWorld.java":
Java Applet support, so the modified file can still be used
with all known browsers.
- 2) If you install the JDK in a location other than the suggested
- directory of /usr/local/java, then you will need to tell the
+ 2) If you install the applet viewer in a location other than
+ /usr/bin/appletviewer, then you will need to tell the
kernel where you put the Java appletviewer.
There are two ways to do this.
One, edit fs/binfmt_java.c file and make the needed change to
W: http://www.cyclades.com/
S: Supported
-EATA ISA/EISA SCSI DRIVER
+EATA ISA/EISA/PCI SCSI DRIVER
P: Dario Ballabio
M: dario@milano.europe.dg.com
-L: linux-kernel@vger.rutgers.edu
+L: linux-scsi@vger.rutgers.edu
S: Maintained
U14-34F SCSI DRIVER
P: Dario Ballabio
M: dario@milano.europe.dg.com
-L: linux-kernel@vger.rutgers.edu
+L: linux-scsi@vger.rutgers.edu
S: Maintained
EATA-DMA SCSI DRIVER
VERSION = 2
PATCHLEVEL = 1
-SUBLEVEL = 11
+SUBLEVEL = 12
ARCH = i386
# Copyright (C) 1994 by Hamish Macdonald
#
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
# override top level makefile
+AS += -m68020
ifdef CONFIG_KERNEL_ELF
-AS = as -m68020
-LD = ld -m m68kelf
-CC := $(CC)
-# set up for cross compiling
-COMPILE_ARCH = $(shell uname -m)
+LD += -m m68kelf
ifneq ($(COMPILE_ARCH),$(ARCH))
- CROSSDIR=/usr/$(ARCH)-linux/bin
- CC := $(CROSSDIR)/$(CC)
- AS := $(CROSSDIR)/$(AS)
- LD := $(CROSSDIR)/$(LD)
- AR := $(CROSSDIR)/$(AR)
- NM := $(CROSSDIR)/$(NM)
- STRIP := $(CROSSDIR)/$(STRIP)
+ # prefix for cross-compiling binaries
+ CROSS_COMPILE = m68k-linux-
endif
else
-AS = /usr/m68k-linuxaout/bin/as -m68020
-CC := $(CC) -pipe -b m68k-linuxaout
-LD = ld -m m68klinux
+LD += -m m68klinux
+ifneq ($(COMPILE_ARCH),$(ARCH))
+ # prefix for cross-compiling binaries
+ CROSS_COMPILE = m68k-linuxaout-
+endif
endif
#
CFLAGS := $(CFLAGS) -m68040
endif
+ifdef CONFIG_OPTIMIZE_060
+CFLAGS := $(CFLAGS) -m68020-40 -Wa,-m68060
+endif
+
HEAD := arch/m68k/kernel/head.o
SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib
#include <linux/config.h>
#include <linux/interrupt.h>
#include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
- hsstop: End of horizontal synchronization pulse
- htotal: Last value on the line (i.e. line length = htotal+1)
- vsstrt: Start of vertical synchronization pulse
- - vsstop: Start of vertical synchronization pulse
+ - vsstop: End of vertical synchronization pulse
- vtotal: Last line value (i.e. number of lines = vtotal+1)
- hcenter: Start of vertical retrace for interlace
- hbstrt: Start of horizontal blank
- hbstop: End of horizontal blank
- vbstrt: Start of vertical blank
- - vbstop: Start of vertical blank
+ - vbstop: End of vertical blank
Horizontal values are in color clock cycles (280 ns), vertical values are in
scanlines.
i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix));
if (!i) {
i = amiga_fb_get_fix_cursorinfo(&crsrfix, con);
- memcpy_tofs((void *)arg, &crsrfix, sizeof(crsrfix));
+ copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix));
}
return i;
}
if (!i) {
i = amiga_fb_get_var_cursorinfo(&crsrvar,
((struct fb_var_cursorinfo *)arg)->data, con);
- memcpy_tofs((void *)arg, &crsrvar, sizeof(crsrvar));
+ copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar));
}
return i;
}
i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar));
if (!i) {
- memcpy_fromfs(&crsrvar, (void *)arg, sizeof(crsrvar));
+ copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar));
i = amiga_fb_set_var_cursorinfo(&crsrvar,
((struct fb_var_cursorinfo *)arg)->data, con);
}
i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate));
if (!i) {
i = amiga_fb_get_cursorstate(&crsrstate, con);
- memcpy_tofs((void *)arg, &crsrstate, sizeof(crsrstate));
+ copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate));
}
return i;
}
i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate));
if (!i) {
- memcpy_fromfs(&crsrstate, (void *)arg, sizeof(crsrstate));
+ copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate));
i = amiga_fb_set_cursorstate(&crsrstate, con);
}
return i;
i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amiga_fb_par));
if (!i) {
ami_get_par(&par);
- memcpy_tofs((void *)arg, &par, sizeof(struct amiga_fb_par));
+ copy_to_user((void *)arg, &par, sizeof(struct amiga_fb_par));
}
return i;
}
i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amiga_fb_par));
if (!i) {
- memcpy_fromfs(&par, (void *)arg, sizeof(struct amiga_fb_par));
+ copy_from_user(&par, (void *)arg, sizeof(struct amiga_fb_par));
ami_set_par(&par);
}
return i;
if (transp)
*transp = htransp;
} else {
- put_fs_word(hred, red);
- put_fs_word(hgreen, green);
- put_fs_word(hblue, blue);
+ put_user(hred, red);
+ put_user(hgreen, green);
+ put_user(hblue, blue);
if (transp)
- put_fs_word(htransp, transp);
+ put_user(htransp, transp);
}
red++;
green++;
hblue = *blue;
htransp = transp ? *transp : 0;
} else {
- hred = get_fs_word(red);
- hgreen = get_fs_word(green);
- hblue = get_fs_word(blue);
- htransp = transp ? get_fs_word(transp) : 0;
+ get_user(hred, red);
+ get_user(hgreen, green);
+ get_user(hblue, blue);
+ if (transp)
+ get_user(htransp, transp);
+ else
+ htransp = 0;
}
hred = CNVT_TOHW(hred, var->red.length);
hgreen = CNVT_TOHW(hgreen, var->green.length);
memcpy(to, from, len);
return;
case 1:
- memcpy_fromfs(to, from, len);
+ copy_from_user(to, from, len);
return;
case 2:
- memcpy_tofs(to, from, len);
+ copy_to_user(to, from, len);
return;
}
}
}
/*
- * Get a Video Modes
+ * Get a Video Mode
*/
static void get_video_mode(const char *name)
"clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
"swap %1 ; lslw #1,%1 ; roxlb #1,%0"
: "=d" (color), "=d" (datawords) : "1" (datawords));
- put_fs_byte(color, data++);
+ put_user(color, data++);
}
if (bits > 0) {
--words; ++lspr;
for (height = (short)var->height-1; height >= 0; height--) {
bits = 16; words = delta; datawords = 0;
for (width = (short)var->width-1; width >= 0; width--) {
+ unsigned long tdata = 0;
+ get_user(tdata, (char *)data);
+ data++;
asm volatile (
"lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
"lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
- : "=d" (datawords) : "0" (datawords), "d" ((u_long)(get_fs_byte(data++))));
+ : "=d" (datawords)
+ : "0" (datawords), "d" (tdata));
if (--bits == 0) {
bits = 16; --words;
asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
}
/* enable the interrupt */
- if (irq < IRQ_IDX(IRQ_AMIGA_PORTS))
+ if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq])
custom.intena = IF_SETCLR | ami_intena_vals[irq];
return 0;
return;
}
- if (ami_ablecount[irq]++)
+ if (--ami_ablecount[irq])
return;
if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
return;
}
- if (--ami_ablecount[irq])
+ if (ami_ablecount[irq]++)
return;
if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
base->icr_data &= ~mask;
if (base->icr_data & base->icr_mask)
custom.intreq = IF_SETCLR | base->int_mask;
- return (old & base->icr_mask);
+ return old & base->icr_mask;
}
/*
base->icr_mask &= ~mask;
base->icr_mask &= CIA_ICR_ALL;
for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
- if ((tmp & base->icr_mask) && !base->irq_list[i].handler)
+ if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
base->icr_mask &= ~tmp;
- }
+ base->cia->icr = tmp;
+ }
+ }
if (base->icr_data & base->icr_mask)
custom.intreq = IF_SETCLR | base->int_mask;
- return (old);
+ return old;
}
int cia_request_irq(struct ciabase *base, unsigned int irq,
mach_gettimeoffset = amiga_gettimeoffset;
if (AMIGAHW_PRESENT(A3000_CLK)){
mach_gettod = a3000_gettod;
- mach_max_dma_address = 0xffffffff; /*
- * default MAX_DMA 0xffffffff
- * on Z3 machines - we should
- * consider adding something
- * like a dma_mask in kmalloc
- * later on, so people using Z2
- * boards in Z3 machines won't
- * get into trouble - Jes
- */
}
else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
mach_gettod = a2000_gettod;
- mach_max_dma_address = 0x00ffffff; /*
- * default MAX_DMA 0x00ffffff
- * on Z2 machines.
- */
}
+
+ mach_max_dma_address = 0xffffffff; /*
+ * default MAX_DMA=0xffffffff
+ * on all machines. If we don't
+ * do so, the SCSI code will not
+ * be able to allocate any mem
+ * for transfers, unless we are
+ * dealing with a Z2 mem only
+ * system. /Jes
+ */
+
mach_hwclk = amiga_hwclk;
mach_set_clock_mmss = amiga_set_clock_mmss;
mach_mksound = amiga_mksound;
*yearp = tod->year1 * 10 + tod->year2;
if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
- if ((!tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
+ if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
*hourp = 0;
else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
*hourp += 12;
t->year = tod->year1 * 10 + tod->year2;
if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
- if ((!tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
+ if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
t->hour = 0;
else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
t->hour += 12;
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/delay.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/zorro.h>
if (transp)
*transp = htransp;
} else {
- put_fs_word(hred, red);
- put_fs_word(hgreen, green);
- put_fs_word(hblue, blue);
+ put_user(hred, red);
+ put_user(hgreen, green);
+ put_user(hblue, blue);
if (transp)
- put_fs_word(htransp, transp);
+ put_user(htransp, transp);
}
red++;
green++;
hblue = *blue;
htransp = transp ? *transp : 0;
} else {
- hred = get_fs_word(red);
- hgreen = get_fs_word(green);
- hblue = get_fs_word(blue);
- htransp = transp ? get_fs_word(transp) : 0;
+ get_user(hred, red);
+ get_user(hgreen, green);
+ get_user(hblue, blue);
+ if (transp)
+ get_user(htransp, transp);
+ else
+ htransp = 0;
}
hred = CNVT_TOHW(hred, var->red.length);
hgreen = CNVT_TOHW(hgreen, var->green.length);
#include <asm/zorro.h>
#include <asm/amigatypes.h>
#include <asm/amigahw.h>
+#include <asm/amigatypes.h>
+
+extern volatile u_short amiga_audio_min_period;
+extern u_short amiga_audio_period;
static struct symbol_table mach_amiga_symbol_table = {
#include <linux/symtab_begin.h>
X(amiga_chip_alloc),
X(amiga_chip_free),
X(amiga_chip_avail),
+ X(amiga_audio_period),
+ X(amiga_audio_min_period),
X(zorro_find),
X(zorro_get_board),
PROD("Blizzard 1230-III Turbo Board", BLIZZARD_1230_III)
PROD("Blizzard 1230-IV/1260 Turbo Board", BLIZZARD_1230_IV)
PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI)
- PROD("CyberStorm", CYBERSTORM)
+ PROD("CyberStorm Mk II", CYBERSTORM_II)
PROD("CyberVision64 Graphics Board", CYBERVISION)
END
#include <linux/delay.h>
#include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
static struct atari_fb_par {
unsigned long screen_base;
- int vyres;
+ int yres_virtual;
union {
struct {
int mode;
};
struct fb_var_screeninfo atari_fb_predefined[] = {
+ /*
+ * yres_virtual==0 means use hw-scrolling if possible, else yres
+ */
{ /* autodetect */
0, 0, 0, 0, 0, 0, 0, 0, /* xres-grayscale */
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, /* red green blue tran*/
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* st low */
- 320, 200, 320, 200, 0, 0, 4, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 320, 200, 320, 0, 0, 0, 4, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* st mid */
- 640, 200, 640, 200, 0, 0, 2, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 200, 640, 0, 0, 0, 2, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* st high */
- 640, 400, 640, 400, 0, 0, 1, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 400, 640, 0, 0, 0, 1, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* tt low */
- 320, 480, 320, 480, 0, 0, 8, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 320, 480, 320, 0, 0, 0, 8, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* tt mid */
- 640, 480, 640, 480, 0, 0, 4, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 480, 640, 0, 0, 0, 4, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* tt high */
- 1280, 960, 1280, 960, 0, 0, 1, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 1280, 960, 1280, 0, 0, 0, 1, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* vga2 */
- 640, 480, 640, 480, 0, 0, 1, 0, /* xres-grayscale */
- {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 480, 640, 0, 0, 0, 1, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* vga4 */
- 640, 480, 640, 480, 0, 0, 2, 0, /* xres-grayscale */
- {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 480, 640, 0, 0, 0, 2, 0,
+ {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* vga16 */
- 640, 480, 640, 480, 0, 0, 4, 0, /* xres-grayscale */
- {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 480, 640, 0, 0, 0, 4, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* vga256 */
- 640, 480, 640, 480, 0, 0, 8, 0, /* xres-grayscale */
- {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, /* red green blue tran*/
+ 640, 480, 640, 0, 0, 0, 8, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* falh2 */
- 896, 608, 896, 608, 0, 0, 1, 0, /* xres-grayscale */
- {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, /* red green blue tran*/
+ 896, 608, 896, 0, 0, 0, 1, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ /* falh16 */
- 896, 608, 896, 608, 0, 0, 4, 0, /* xres-grayscale */
- {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, /* red green blue tran*/
+ 896, 608, 896, 0, 0, 0, 4, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
/* Minor 14..23 free for more standard video modes */
{ 0, },
return -EINVAL;
if (var->yoffset + yres > yres_virtual && yres_virtual)
return -EINVAL;
- par->vyres = yres_virtual;
+ par->yres_virtual = yres_virtual;
par->screen_base = screen_base + var->yoffset * linelen;
return 0;
}
if (! use_hwscroll)
var->yres_virtual=var->yres;
else if (screen_len)
- if (par->vyres)
- var->yres_virtual = par->vyres;
+ if (par->yres_virtual)
+ var->yres_virtual = par->yres_virtual;
else
- /* vyres==0 means use maximum */
+ /* yres_virtual==0 means use maximum */
var->yres_virtual = screen_len / linelen;
else {
if (hwscroll < 0)
static int vdl_prescale[4][3] = {{4,2,1}, {4,2,1}, {4,2,2}, {4,2,1}};
/* Default hsync timing [mon_type] in picoseconds */
-static long h_syncs[4] = {3000000, 4700000, 4000000, 4700000};
+static long h_syncs[4] = {3000000, 4875000, 4000000, 4875000};
static inline int hxx_prescale(struct falcon_hw *hw)
return -EINVAL;
par->hw.falcon.bpp = bpp;
- if (mon_type != F_MON_VGA || DontCalcRes) {
- /* Skip all calculations, VGA multisync only yet */
+ if (mon_type == F_MON_SM || DontCalcRes) {
+ /* Skip all calculations. VGA/TV/SC1224 only supported. */
struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
if (bpp > myvar->bits_per_pixel ||
goto set_screen_base; /* Don't forget this */
}
- /* Only some fixed resolutions < 640x480 */
+ /* Only some fixed resolutions < 640x400 */
if (xres <= 320)
xres = 320;
else if (xres <= 640 && bpp != 16)
yres = 240;
else if (yres <= 400)
yres = 400;
- else if (yres <= 480)
- yres = 480;
/* 2 planes must use STE compatibility mode */
par->hw.falcon.ste_mode = bpp==2;
/* Total and visible scanline length must be a multiple of one longword,
* this and the console fontwidth yields the alignment for xres and
* xres_virtual.
+ * TODO: this way "odd" fontheights are not supported
*
* Special case in STE mode: blank and graphic positions don't align,
* avoid trash at right margin
par->hw.falcon.line_offset = bpp * (xres_virtual - xres) / 16;
/* single or double pixel width */
- xstretch = (xres == 320) ? 2 : 1;
+ xstretch = (xres < 640) ? 2 : 1;
-#if 0 /* currently unused */
+#if 0 /* SM124 supports only 640x400, this is rejected above */
if (mon_type == F_MON_SM) {
if (xres != 640 && yres != 400)
return -EINVAL;
right_margin = 0;
/* TODO set all margins */
}
- else if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
+ else
+#endif
+ if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
plen = 2 * xstretch;
+ if (var->pixclock > f32.t * plen)
+ return -EINVAL;
pclock = &f32;
- hsync_len = 150 / plen;
if (yres > 240)
interlace = 1;
- /* TODO set margins */
+ if (var->pixclock == 0) {
+ /* set some minimal margins which center the screen */
+ left_margin = 32;
+ right_margin = 18;
+ hsync_len = pclock->hsync / plen;
+ upper_margin = 31;
+ lower_margin = 14;
+ vsync_len = interlace ? 3 : 4;
+ } else {
+ left_margin = var->left_margin;
+ right_margin = var->right_margin;
+ hsync_len = var->hsync_len;
+ upper_margin = var->upper_margin;
+ lower_margin = var->lower_margin;
+ vsync_len = var->vsync_len;
+ if (var->vmode & FB_VMODE_INTERLACED) {
+ upper_margin = (upper_margin + 1) / 2;
+ lower_margin = (lower_margin + 1) / 2;
+ vsync_len = (vsync_len + 1) / 2;
+ } else if (var->vmode & FB_VMODE_DOUBLE) {
+ upper_margin *= 2;
+ lower_margin *= 2;
+ vsync_len *= 2;
+ }
+ }
}
else
-#endif
{ /* F_MON_VGA */
if (bpp == 16)
- xstretch = 2; /* hicolor only double pixel width */
+ xstretch = 2; /* Double pixel width only for hicolor */
/* Default values are used for vert./hor. timing if no pixelclock given. */
if (var->pixclock == 0) {
int linesize;
upper_margin = var->upper_margin;
lower_margin = var->lower_margin;
vsync_len = var->vsync_len;
+ /* Internal unit is [single lines per (half-)frame] */
if (var->vmode & FB_VMODE_INTERLACED) {
/* # lines in half frame */
+ /* External unit is [lines per full frame] */
upper_margin = (upper_margin + 1) / 2;
lower_margin = (lower_margin + 1) / 2;
vsync_len = (vsync_len + 1) / 2;
}
+ else if (var->vmode & FB_VMODE_DOUBLE) {
+ /* External unit is [double lines per frame] */
+ upper_margin *= 2;
+ lower_margin *= 2;
+ vsync_len *= 2;
+ }
}
if (pclock == &fext)
longoffset = 1; /* VIDEL doesn't synchronize on short offset */
lower_margin += lines;
goto again;
}
+ else if (vfreq > vfmax && doubleline) {
+ /* Doubleline too high -> enlarge margins */
+ int lines;
+ for (lines=0; (hfreq*2)/(par->VFT+1+4*lines)>vfmax; lines+=2)
+ ;
+ upper_margin += lines;
+ lower_margin += lines;
+ goto again;
+ }
else if (vfreq > vfmax && interlace) {
/* Interlace, too high -> enlarge margins */
int lines;
return -EINVAL;
if (var->yoffset + yres > yres_virtual && yres_virtual)
return -EINVAL;
- par->vyres = yres_virtual;
+ par->yres_virtual = yres_virtual;
par->screen_base = screen_base + var->yoffset * linelen;
par->hw.falcon.xoffset = 0;
linelen = var->xres_virtual * var->bits_per_pixel / 8;
if (screen_len)
- if (par->vyres)
- var->yres_virtual = par->vyres;
+ if (par->yres_virtual)
+ var->yres_virtual = par->yres_virtual;
else
- /* vyres==0 means use maximum */
+ /* yres_virtual==0 means use maximum */
var->yres_virtual = screen_len / linelen;
else {
if (hwscroll < 0)
var->lower_margin *= 2;
var->vsync_len *= 2;
}
+ else if (var->vmode & FB_VMODE_DOUBLE) {
+ var->upper_margin = (var->upper_margin + 1) / 2;
+ var->lower_margin = (var->lower_margin + 1) / 2;
+ var->vsync_len = (var->vsync_len + 1) / 2;
+ }
var->pixclock *= plen;
var->left_margin /= plen;
break;
case F_MON_SC:
case F_MON_TV:
- vfmin = 50;
+ /* PAL...NTSC */
+ vfmin = 49; /* not 50, since TOS defaults to 49.9x Hz */
vfmax = 60;
- hfmin = 15624;
- hfmax = 15626;
+ hfmin = 15620;
+ hfmax = 15755;
break;
}
/* initialize hsync-len */
return -EINVAL;
if (var->yoffset + yres > yres_virtual && yres_virtual)
return -EINVAL;
- par->vyres = yres_virtual;
+ par->yres_virtual = yres_virtual;
par->screen_base=screen_base+ var->yoffset*linelen;
return 0;
}
if (! use_hwscroll)
var->yres_virtual=var->yres;
else if (screen_len)
- if (par->vyres)
- var->yres_virtual = par->vyres;
+ if (par->yres_virtual)
+ var->yres_virtual = par->yres_virtual;
else
- /* vyres==0 means use maximum */
+ /* yres_virtual==0 means use maximum */
var->yres_virtual = screen_len / linelen;
else {
if (hwscroll < 0)
if (transp) *transp=htransp;
}
else {
- put_fs_word(hred, red);
- put_fs_word(hgreen, green);
- put_fs_word(hblue, blue);
- if (transp) put_fs_word(htransp, transp);
+ put_user(hred, red);
+ put_user(hgreen, green);
+ put_user(hblue, blue);
+ if (transp) put_user(htransp, transp);
}
red++;
green++;
htransp=(transp) ? *transp : 0;
}
else {
- hred=get_fs_word(red);
- hgreen=get_fs_word(green);
- hblue=get_fs_word(blue);
- htransp=(transp)?get_fs_word(transp):0;
+ get_user(hred, red);
+ get_user(hgreen, green);
+ get_user(hblue, blue);
+ if (transp)
+ get_user(htransp, transp);
+ else
+ htransp = 0;
}
hred=CNVT_TOHW(hred,var->red.length);
hgreen=CNVT_TOHW(hgreen,var->green.length);
memcpy(to,from,len);
return;
case 1:
- memcpy_fromfs(to,from,len);
+ copy_from_user(to,from,len);
return;
case 2:
- memcpy_tofs(to,from,len);
+ copy_to_user(to,from,len);
return;
}
}
atari_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg, int con)
{
- int i;
-
switch (cmd) {
#ifdef FBCMD_GET_CURRENTPAR
case FBCMD_GET_CURRENTPAR:
- if ((i = verify_area(VERIFY_WRITE, (void *)arg,
- sizeof(struct atari_fb_par))))
- return i;
- memcpy_tofs((void *)arg, (void *)¤t_par,
- sizeof(struct atari_fb_par));
+ if (copy_to_user((void *)arg, (void *)¤t_par,
+ sizeof(struct atari_fb_par)))
+ return -EFAULT;
return 0;
#endif
#ifdef FBCMD_SET_CURRENTPAR
case FBCMD_SET_CURRENTPAR:
- if ((i = verify_area(VERIFY_READ, (void *)arg,
- sizeof(struct atari_fb_par))))
- return i;
- memcpy_fromfs((void *)¤t_par, (void *)arg,
- sizeof(struct atari_fb_par));
+ if (copy_from_user((void *)¤t_par, (void *)arg,
+ sizeof(struct atari_fb_par)))
+ return -EFAULT;
atari_fb_set_par(¤t_par);
return 0;
#endif
for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {
len += sprintf(buf+len, "%s\n", p->devname);
if (p->next)
- len += sprintf( buf+len, " " );
+ len += sprintf( buf+len, " " );
}
}
}
void atari_mste_gettod (int *yearp, int *monp, int *dayp,
int *hourp, int *minp, int *secp)
{
- int hr24=0;
+ int hr24=0, hour;
struct MSTE_RTC val;
mste_rtc.mode=(mste_rtc.mode | 1);
mste_read(&val);
*secp = val.sec_ones + val.sec_tens * 10;
*minp = val.min_ones + val.min_tens * 10;
- if (hr24)
- *hourp = val.hr_ones + val.hr_tens * 10;
- else {
- *hourp = val.hr_ones + (val.hr_tens & 1) * 10;
- if (val.hr_tens & 2)
- *hourp += 12;
+ hour = val.hr_ones + val.hr_tens * 10;
+ if (!hr24) {
+ if (hour == 12 || hour == 12 + 20)
+ hour -= 12;
+ if (hour >= 20)
+ hour += 12 - 20;
}
+ *hourp = hour;
*dayp = val.day_ones + val.day_tens * 10;
*monp = val.mon_ones + val.mon_tens * 10;
*yearp = val.year_ones + val.year_tens * 10 + 80;
{
unsigned char ctrl;
unsigned short tos_version;
-
+ int hour, pm;
+
while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
*secp = RTC_READ(RTC_SECONDS);
*minp = RTC_READ(RTC_MINUTES);
- *hourp = RTC_READ(RTC_HOURS);
+ hour = RTC_READ(RTC_HOURS);
*dayp = RTC_READ(RTC_DAY_OF_MONTH);
*monp = RTC_READ(RTC_MONTH);
*yearp = RTC_READ(RTC_YEAR);
+ pm = hour & 0x80;
+ hour &= ~0x80;
ctrl = RTC_READ(RTC_CONTROL);
if (!(ctrl & RTC_DM_BINARY)) {
BCD_TO_BIN(*secp);
BCD_TO_BIN(*minp);
- BCD_TO_BIN(*hourp);
+ BCD_TO_BIN(hour);
BCD_TO_BIN(*dayp);
BCD_TO_BIN(*monp);
BCD_TO_BIN(*yearp);
}
if (!(ctrl & RTC_24H)) {
- if (*hourp & 0x80) {
- *hourp &= ~0x80;
- *hourp += 12;
- }
+ if (!pm && hour == 12)
+ hour = 0;
+ else if (pm && hour != 12)
+ hour += 12;
}
+ *hourp = hour;
+
/* Adjust values (let the setup valid) */
/* Fetch tos version at Physical 2 */
val.min_ones = t->min % 10;
val.min_tens = t->min / 10;
hour = t->hour;
+ if (!hr24) {
+ if (hour > 11)
+ hour += 20 - 12;
+ if (hour == 0 || hour == 20)
+ hour += 12;
+ }
val.hr_ones = hour % 10;
val.hr_tens = hour / 10;
- if (!hr24 && hour > 11) {
- hour -= 12;
- val.hr_ones = hour % 10;
- val.hr_tens = (hour / 10) | 2;
- }
val.day_ones = t->day % 10;
val.day_tens = t->day / 10;
val.mon_ones = (t->mon+1) % 10;
mste_read(&val);
t->sec = val.sec_ones + val.sec_tens * 10;
t->min = val.min_ones + val.min_tens * 10;
- if (hr24)
- t->hour = val.hr_ones + val.hr_tens * 10;
- else {
- t->hour = val.hr_ones + (val.hr_tens & 1) * 10;
- if (val.hr_tens & 2)
- t->hour += 12;
+ hour = val.hr_ones + val.hr_tens * 10;
+ if (!hr24) {
+ if (hour == 12 || hour == 12 + 20)
+ hour -= 12;
+ if (hour >= 20)
+ hour += 12 - 20;
}
+ t->hour = hour;
t->day = val.day_ones + val.day_tens * 10;
t->mon = val.mon_ones + val.mon_tens * 10 - 1;
t->year = val.year_ones + val.year_tens * 10 + 80;
unsigned long flags;
unsigned short tos_version;
unsigned char ctrl;
+ int pm = 0;
/* Tos version at Physical 2. See above for explanation why we
cannot use PTOV(2). */
year = t->year - ((tos_version < 0x306) ? 70 : 68);
wday = t->wday + (t->wday >= 0);
- if (!(ctrl & RTC_24H) && hour > 11) {
- hour -= 12;
- hour |= 0x80;
+ if (!(ctrl & RTC_24H)) {
+ if (hour > 11) {
+ pm = 0x80;
+ if (hour != 12)
+ hour -= 12;
+ }
+ else if (hour == 0)
+ hour = 12;
}
if (!(ctrl & RTC_DM_BINARY)) {
else {
RTC_WRITE( RTC_SECONDS, sec );
RTC_WRITE( RTC_MINUTES, min );
- RTC_WRITE( RTC_HOURS, hour );
+ RTC_WRITE( RTC_HOURS, hour + pm);
RTC_WRITE( RTC_DAY_OF_MONTH, day );
RTC_WRITE( RTC_MONTH, mon );
RTC_WRITE( RTC_YEAR, year );
if (!op) {
/* read: adjust values */
- if (!(ctrl & RTC_DM_BINARY)) {
+ if (hour & 0x80) {
+ hour &= ~0x80;
+ pm = 1;
+ }
+
+ if (!(ctrl & RTC_DM_BINARY)) {
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hour);
}
if (!(ctrl & RTC_24H)) {
- if (hour & 0x80) {
- hour &= ~0x80;
- hour += 12;
- }
+ if (!pm && hour == 12)
+ hour = 0;
+ else if (pm && hour != 12)
+ hour += 12;
}
t->sec = sec;
#include <asm/atarikb.h>
#include <asm/atari_joystick.h>
#include <asm/atari_mouse.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#define MAJOR_NR JOYSTICK_MAJOR
return 0;
}
-static int write_joystick(struct inode *inode, struct file *file,
- const char *buffer, int count)
+static long write_joystick(struct inode *inode, struct file *file,
+ const char *buffer, unsigned long count)
{
return -EINVAL;
}
-static int read_joystick(struct inode *inode, struct file *file,
- char *buffer, int count)
+static long read_joystick(struct inode *inode, struct file *file,
+ char *buffer, unsigned long count)
{
int minor = DEVICE_NR(inode->i_rdev);
int i;
#include <asm/atari_joystick.h>
#include <asm/atari_stdma.h>
+extern void atari_microwire_cmd( int cmd );
+
static struct symbol_table mach_atari_symbol_table = {
#include <linux/symtab_begin.h>
X(ikbd_mouse_rel_pos),
X(ikbd_mouse_disable),
+ X(atari_microwire_cmd),
+
#include <linux/symtab_end.h>
};
bool '68020 support' CONFIG_M68020
bool '68030 support' CONFIG_M68030
bool '68040 support' CONFIG_M68040
-if [ "$CONFIG_M68040" = "y" ]; then
- bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
-fi
bool '68060 support' CONFIG_M68060
-if [ "$CONFIG_M68060" = "y" ]; then
- bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+if [ "$CONFIG_M68020" = "n" -a "$CONFIG_M68030" = "n" ]; then
+ if [ "$CONFIG_M68040" = "y" -a "$CONFIG_M68060" = "n" ]; then
+ bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
+ fi
+ if [ "$CONFIG_M68040" = "n" -a "$CONFIG_M68060" = "y" ]; then
+ bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+ fi
fi
bool 'Advanced processor options' CONFIG_ADVANCED_CPU
if [ "$CONFIG_ADVANCED_CPU" = "y" ]; then
bool 'Amiga ECS chipset support' CONFIG_AMIFB_ECS
bool 'Amiga AGA chipset support' CONFIG_AMIFB_AGA
bool 'Amiga Cybervision support' CONFIG_FB_CYBER
- bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
- if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
- bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
+# bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
+# if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
+# bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
# bool 'A2410 support' CONFIG_GSP_A2410
- fi
+# fi
fi
endmenu
tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
fi
if [ "$CONFIG_ATARI" = "y" ]; then
-bool 'Atari ACSI support' CONFIG_ATARI_ACSI
-if [ "$CONFIG_ATARI_ACSI" = "y" ]; then
+tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
+if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
-bool 'Atari SLM laser printer support' CONFIG_ATARI_SLM
+dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
fi
fi
comment 'SCSI low-level drivers'
if [ "$CONFIG_AMIGA" = "y" ]; then
-bool 'A3000 WD33C93A support' CONFIG_A3000_SCSI
-bool 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-bool 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
+tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
+tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
+bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI
+bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
+bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
fi
if [ "$CONFIG_ATARI" = "y" ]; then
dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
mainmenu_option next_comment
comment 'Character devices'
-bool 'Parallel printer support' CONFIG_PRINTER
+tristate 'Parallel printer support' CONFIG_PRINTER
if [ "$CONFIG_AMIGA" = "y" ]; then
+ dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
fi
if [ "$CONFIG_ATARI" = "y" ]; then
mainmenu_option next_comment
comment 'Sound support'
-bool 'Sound support' CONFIG_SOUND y
+tristate 'Sound support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
- bool 'Amiga or Atari DMA sound support' CONFIG_DMASOUND y
+ dep_tristate 'Amiga or Atari DMA sound support' CONFIG_DMASOUND $CONFIG_SOUND
fi
endmenu
#include <asm/machdep.h>
#include <asm/system.h>
+#include <asm/uaccess.h>
#include "../../../drivers/char/vt_kern.h" /* vt_cons and vc_resize_con() */
* Internal routines
*/
-static void fbcon_setup(int con, int setcol, int cls);
+static void fbcon_setup(int con, int setcol, int init);
static __inline__ void *mymemclear_small(void *s, size_t count);
static __inline__ void *mymemclear(void *s, size_t count);
static __inline__ void *mymemset(void *s, size_t count);
if (unit)
disp[unit] = disp[0];
disp[unit].conp = conp;
- fbcon_setup(unit, 1, 0);
+ fbcon_setup(unit, 1, 1);
}
static int fbcon_changevar(int con)
{
- fbcon_setup(con, 1, 1);
+ fbcon_setup(con, 1, 0);
return(0);
}
-static void fbcon_setup(int con, int setcol, int cls)
+static void fbcon_setup(int con, int setcol, int init)
{
struct display *p = &disp[con];
struct vc_data *conp = p->conp;
+ int nr_rows, nr_cols;
p->var.xoffset = p->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
else
p->scrollmode = SCROLL_YMOVE;
- conp->vc_cols = p->var.xres/p->fontwidth;
- conp->vc_rows = p->var.yres/p->fontheight;
+ nr_cols = p->var.xres/p->fontwidth;
+ nr_rows = p->var.yres/p->fontheight;
+ /* ++guenther: console.c:vc_allocate() relies on initializing vc_{cols,rows},
+ * but we must not set those if we are only resizing the console.
+ */
+ if (init) {
+ conp->vc_cols = nr_cols;
+ conp->vc_rows = nr_rows;
+ }
p->vrows = p->var.yres_virtual/p->fontheight;
conp->vc_can_do_color = p->var.bits_per_pixel != 1;
p->bgcol = 0;
}
- if (cls)
- vc_resize_con(conp->vc_rows, conp->vc_cols, con);
+ if (!init)
+ vc_resize_con(nr_rows, nr_cols, con);
}
int unit = conp->vc_num;
struct display *p = &disp[unit];
+ /* Avoid flickering if there's no real change. */
+ if (p->cursor_x == conp->vc_x && p->cursor_y == conp->vc_y &&
+ (mode == CM_ERASE) == !cursor_on)
+ return 0;
if (CURSOR_UNDRAWN ())
p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
p->cursor_x = conp->vc_x;
if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
return i;
- memcpy_fromfs( name, data, MAX_FONT_NAME );
+ copy_from_user( name, data, MAX_FONT_NAME );
name[sizeof(name)-1] = 0;
if (!findsoftfont( name, &w, &h, (u_char **)&data ))
CONFIG_M68020=y
CONFIG_M68030=y
CONFIG_M68040=y
-# CONFIG_OPTIMIZE_040 is not set
# CONFIG_M68060 is not set
+# CONFIG_OPTIMIZE_040 is not set
# CONFIG_OPTIMIZE_060 is not set
# CONFIG_ADVANCED_CPU is not set
# CONFIG_RMW_INSNS is not set
CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_AMIGA_Z2RAM is not set
# CONFIG_ATARI_ACSI is not set
# CONFIG_ACSI_MULTI_LUN is not set
# CONFIG_TCP_NAGLE_OFF is not set
CONFIG_IP_NOSR=y
# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
#
#
# CONFIG_A2091_SCSI is not set
# CONFIG_GVP11_SCSI is not set
# CONFIG_CYBERSTORM_SCSI is not set
-# CONFIG_ATARI_SCSI is not set
+# CONFIG_CYBERSTORMII_SCSI is not set
+# CONFIG_BLZ2060_SCSI is not set
+# CONFIG_BLZ1230_SCSI is not set
+CONFIG_ATARI_SCSI=y
#
# Network device support
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_LOCK_MANDATORY is not set
CONFIG_MINIX_FS=y
# CONFIG_EXT_FS is not set
CONFIG_EXT2_FS=y
CONFIG_MSDOS_FS=y
# CONFIG_VFAT_FS is not set
# CONFIG_UMSDOS_FS is not set
+# CONFIG_MSDOS_PARTITION is not set
CONFIG_PROC_FS=y
CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
#
# CONFIG_PRINTER is not set
CONFIG_AMIGAMOUSE=y
-# CONFIG_ATARIMOUSE is not set
+CONFIG_ATARIMOUSE=y
CONFIG_AMIGA_BUILTIN_SERIAL=y
# CONFIG_GVPIOEXT is not set
# CONFIG_MULTIFACE_III_TTY is not set
#include <linux/ioport.h>
#include <asm/io.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
if (on_off)
set_kbd(decckm);
else
- clr_kbd(decckm);
+ clr_kbd(decckm);
break;
case 3: /* 80/132 mode switch unimplemented */
deccolm = on_off;
need_wrap = 0;
}
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
ESpalette };
set_leds();
}
-static int con_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count)
+static void con_flush_chars(struct tty_struct *tty)
+{
+ unsigned int currcons;
+ struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+ currcons = vt->vc_num;
+ if (vcmode != KD_GRAPHICS)
+ set_cursor(currcons);
+}
+
+static int do_con_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
{
int c, tc, ok, n = 0;
unsigned int currcons;
disable_bh(CONSOLE_BH);
while (count) {
enable_bh(CONSOLE_BH);
- c = from_user ? get_user(buf) : *buf;
+ if (from_user)
+ get_user(c, buf);
+ else
+ c = *buf;
buf++; n++; count--;
disable_bh(CONSOLE_BH);
ok = tc && (c >= 32 ||
(!utf && !(((disp_ctrl ? CTRL_ALWAYS
: CTRL_ACTION) >> c) & 1)))
- && (c != 127 || disp_ctrl);
+ && (c != 127 || disp_ctrl)
+ && (c != 128+27);
if (vc_state == ESnormal && ok) {
/* Now try to find out how to display it */
cr(currcons);
lf(currcons);
}
-
+
#if 1 /* XXX */
/* DPC: 1994-04-12
* Speed up overstrike mode, using new putcs.
*p++ = tc;
*pos++ = tc | (attr << 8);
-
+
if (nextx == cols) {
sw->con_putc(vc_cons[currcons].d,
*putcs_buf, y, x);
}
/* TAB TAB TAB - Arghh!!!! */
-
+
while (count)
{
enable_bh(CONSOLE_BH);
- c = from_user ? get_user(buf) : *buf;
+ if (from_user)
+ get_user(c, buf);
+ else
+ c = *buf;
disable_bh(CONSOLE_BH);
tc = translate[toggle_meta ? (c|0x80) : c];
if (!tc ||
* of an escape sequence.
*/
switch (c) {
+ case 0:
+ continue;
case 7:
if (bell_duration)
kd_mksound(bell_pitch, bell_duration);
vc_state = ESnormal;
}
}
- if (vcmode != KD_GRAPHICS)
- set_cursor(currcons);
enable_bh(CONSOLE_BH);
return n;
}
+static int con_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
+{
+ int retval;
+
+ retval = do_con_write(tty, from_user, buf, count);
+ con_flush_chars(tty);
+
+ return retval;
+}
+
+static void con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ do_con_write(tty, 0, &ch, 1);
+}
+
static int con_write_room(struct tty_struct *tty)
{
if (tty->stopped)
console_driver.open = con_open;
console_driver.write = con_write;
console_driver.write_room = con_write_room;
+ console_driver.put_char = con_put_char;
+ console_driver.flush_chars = con_flush_chars;
console_driver.chars_in_buffer = con_chars_in_buffer;
console_driver.ioctl = vt_ioctl;
console_driver.stop = con_stop;
int i, unit, size;
char *charmap;
- if (arg){
- i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
- (void *)arg, ch512 ? 2*cmapsz : cmapsz);
- if (i)
- return i;
- }else
+ if (!arg)
return -EINVAL;
charmap = (char *)kmalloc(size, GFP_USER);
if (set){
- memcpy_fromfs(charmap, arg, size);
+ if (copy_from_user(charmap, arg, size)) {
+ kfree(charmap);
+ return -EFAULT;
+ }
for (unit = 32; unit > 0; unit--)
for (i = 0; i < (ch512 ? 512 : 256); i++)
memset(charmap, 0, size);
i = conswitchp->con_get_font(vc_cons[fg_console].d,
&unit, &unit, charmap);
- memcpy_tofs(arg, charmap, size);
+ if (i == 0 && copy_to_user(arg, charmap, size))
+ i = -EFAULT;
}
kfree(charmap);
void set_vesa_blanking(int arg)
{
char *argp = (char *)arg + 1;
- unsigned int mode = get_fs_byte(argp);
+ unsigned int mode;
+ get_user(mode, argp);
vesa_blank_mode = (mode < 4) ? mode : 0;
}
LTSS_USP = 4
LTSS_SR = 8
LTSS_FS = 10
-LTSS_CRP = 20
-LTSS_FPCTXT = 32
+LTSS_CRP = 12
+LTSS_FPCTXT = 24
SYMBOL_NAME_LABEL(resume)
/*
movec %cacr,%d0
oriw #LFLUSH_I_AND_D,%d0
movec %d0,%cacr
-
+
/* switch the root pointer */
pmove %a1@(LTSS_CRP),%crp
#endif
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
- .space (NR_syscalls-163)*4
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid)
+ .space (NR_syscalls-165)*4
lea %pc@(SYMBOL_NAME(kpt)),%a1
movel %a3,%a1@ /* save address of page table */
movel %a3,%a1
- addql #_PAGE_TABLE,%a1 /* descriptor type */
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* descriptor type */
movel #PAGE_TABLE_SIZE<<2,%d2 /* increment */
2: movel %a1,%a0@+
movel %a3,%a0
movel %d5,%a1
- addw #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT,%a1
+ addw #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
movew #(PAGE_TABLE_SIZE*TABLENR_4MB)-1,%d1
movel #PAGESIZE,%d2
1: movel %a1,%a0@+
putc('I')
- moveq #_PAGE_NOCACHE030+_PAGE_PRESENT,%d0
+ movel #_PAGE_NOCACHE030+_PAGE_PRESENT+_PAGE_ACCESSED,%d0
movel %d0,%a5@(0x40<<2)
jra Lmapphys
/* initialize the pointer table */
movel %a4,%a0
movel %a3,%a1
- addql #_PAGE_TABLE,%a1 /* base descriptor */
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* base descriptor */
movel #PAGE_TABLE_SIZE<<2,%d2 /* increment */
moveq #TABLENR_16MB-1,%d1
/* ensure that the root table points to the pointer table */
movel %a4,%a0
- addql #_PAGE_TABLE,%a0
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
movel %a0,%a5@(0x40<<2)
/*
* descriptor bits include noncachable/serialized and global bits.
*/
movel %a3,%a0
- movew #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+ movew #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
movel #PAGESIZE,%d2
movew #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
/* Let the root table point to the new pointer table */
lea %a4@(PTR_TABLE_SIZE<<2),%a4
movel %a4,%a0
- addl #_PAGE_TABLE,%a0
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
movel %a0,%a5@(0x7f<<2) /* 0xFE000000 - 0xFFFFFFFF */
/* clear lower half of the pointer table (0xfexxxxxx) */
movel #PAGE_TABLE_SIZE*PAGESIZE,%d1
movel #(PTR_TABLE_SIZE/2)-1,%d2
movel %d3,%d0
- addl #_PAGE_PRESENT,%d0
+ orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d0
1: movel %d0,%a0@+
addl %d1,%d0
dbra %d2,1b
/* Initialize the upper half of the pointer table (a0 is still valid) */
movel %a3,%a1
- addql #_PAGE_TABLE,%a1
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1
movel #PAGE_TABLE_SIZE<<2,%d2
moveq #TABLENR_16MB-1,%d1
1: movel %a1,%a0@+
/* Initialize the page tables as noncacheable/serialized! */
movel %a3,%a0
movel %d3,%a1
- addw #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+ addw #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
movel #PAGESIZE,%d2
movew #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
1: movel %a1,%a0@+
lsrl %d2,%d0
movel %d0,%d1
lsll %d2,%d1
- addql #_PAGE_PRESENT,%d1
+ orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
lsll #2,%d0
movel %a5@(%d0:w),%d2
movel %d1,%a5@(%d0:w)
lsrl %d0,%d1
lea %a1@(%d1:l:4),%a1
movel %d5,%d1
- addql #_PAGE_PRESENT,%d1
+ orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
movel %a1@,%d2
movel %d1,%a1@
lea 5f:w,%a0
X(cache_clear),
X(mm_vtop),
X(mm_ptov),
+ X(mm_end_of_chunk),
X(m68k_debug_device),
X(request_irq),
X(free_irq),
X(dump_fpu),
X(dump_thread),
X(strnlen),
+ X(strrchr),
/* The following are special because they're not called
explicitly (the C compiler generates them). Fortunately,
XNOVERS(memcpy),
XNOVERS(memset),
- XNOVERS(down_failed),
- XNOVERS(up_wakeup),
+ XNOVERS(__down_failed),
+ XNOVERS(__up_wakeup),
#include <linux/symtab_end.h>
};
#include <linux/user.h>
#include <linux/a.out.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/traps.h>
#include <asm/machdep.h>
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
+ struct switch_stack *sw;
+
/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = 0;
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump)));
- dump->regs = *regs;
- dump->regs2 = ((struct switch_stack *)regs)[-1];
+ sw = ((struct switch_stack *)regs) - 1;
+ dump->regs.d1 = regs->d1;
+ dump->regs.d2 = regs->d2;
+ dump->regs.d3 = regs->d3;
+ dump->regs.d4 = regs->d4;
+ dump->regs.d5 = regs->d5;
+ dump->regs.d6 = sw->d6;
+ dump->regs.d7 = sw->d7;
+ dump->regs.a0 = regs->a0;
+ dump->regs.a1 = regs->a1;
+ dump->regs.a2 = sw->a2;
+ dump->regs.a3 = sw->a3;
+ dump->regs.a4 = sw->a4;
+ dump->regs.a5 = sw->a5;
+ dump->regs.a6 = sw->a6;
+ dump->regs.d0 = regs->d0;
+ dump->regs.orig_d0 = regs->orig_d0;
+ dump->regs.stkadj = regs->stkadj;
+ dump->regs.sr = regs->sr;
+ dump->regs.pc = regs->pc;
+ dump->regs.fmtvec = (regs->format << 12) | regs->vector;
/* dump floating point stuff */
dump->u_fpvalid = dump_fpu (&dump->m68kfp);
}
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
}
page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */
- if (page >= high_memory)
+ if (MAP_NR(page) >= max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
return *(unsigned long *) page;
goto repeat;
}
/* this is a hack for non-kernel-mapped video buffers and similar */
- if (page < high_memory) {
+ if (MAP_NR(page) < max_mapnr) {
*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
flush_page_to_ram (page);
}
res = read_long(child, addr, &tmp);
if (res < 0)
return res;
- res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
- if (!res)
- put_user(tmp, (unsigned long *) data);
- return res;
+ return put_user(tmp, (unsigned long *) data);
}
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
- int res;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
return -EIO;
- res = verify_area(VERIFY_WRITE, (void *) data,
- sizeof(long));
- if (res)
- return res;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
if (addr < 19) {
tmp = child->tss.fp[addr - 21];
else
return -EIO;
- put_user(tmp,(unsigned long *) data);
- return 0;
+ return put_user(tmp,(unsigned long *) data);
}
/* when I and D space are separate, this will have to be fixed. */
#include <linux/unistd.h>
#include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/traps.h>
asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs);
-static const int extra_sizes[16] = {
+const int frame_extra_sizes[16] = {
0,
-1, /* sizeof(((struct frame *)0)->un.fmt1), */
sizeof(((struct frame *)0)->un.fmt2),
asmlinkage int do_sigreturn(unsigned long __unused)
{
- struct sigcontext_struct context;
+ struct sigcontext context;
struct pt_regs *regs;
struct switch_stack *sw;
int fsize = 0;
regs = (struct pt_regs *) (sw + 1);
/* get previous context (including pointer to possible extra junk) */
- if (verify_area(VERIFY_READ, (void *)usp, sizeof(context)))
- goto badframe;
-
- memcpy_fromfs(&context,(void *)usp, sizeof(context));
+ if (copy_from_user(&context,(void *)usp, sizeof(context)))
+ goto badframe;
fp = usp + sizeof (context);
}
__asm__ volatile ("frestore %0" : : "m" (*context.sc_fpstate));
- fsize = extra_sizes[regs->format];
+ fsize = frame_extra_sizes[regs->format];
if (fsize < 0) {
/*
* user process trying to return with weird frame format
*/
if (fsize) {
- if (verify_area(VERIFY_READ, (void *)fp, fsize))
- goto badframe;
-
#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
__asm__ __volatile__
- ("movel %0,%/a0\n\t"
- "subl %1,%/a0\n\t" /* make room on stack */
- "movel %/a0,%/sp\n\t" /* set stack pointer */
+ (" movel %0,%/a0\n\t"
+ " subl %1,%/a0\n\t" /* make room on stack */
+ " movel %/a0,%/sp\n\t" /* set stack pointer */
/* move switch_stack and pt_regs */
"1: movel %0@+,%/a0@+\n\t"
" dbra %2,1b\n\t"
- "lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt stuff */
- "lsrl #2,%1\n\t"
- "subql #1,%1\n\t"
+ " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+ " lsrl #2,%1\n\t"
+ " subql #1,%1\n\t"
"2: movesl %4@+,%2\n\t"
- " movel %2,%/a0@+\n\t"
+ "3: movel %2,%/a0@+\n\t"
" dbra %1,2b\n\t"
- "bral " SYMBOL_NAME_STR(ret_from_signal)
+ " bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+ "4:\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 2b,4b\n"
+ " .long 3b,4b\n"
+ ".text"
: /* no outputs, it doesn't ever return */
: "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
"n" (frame_offset), "a" (fp)
: "a0");
#undef frame_offset
+ /*
+ * If we ever get here an exception occured while
+ * building the above stack-frame.
+ */
goto badframe;
- /* NOTREACHED */
}
return regs->d0;
* longwords for format "B".
*/
-#define UFRAME_SIZE(fs) (sizeof(struct sigcontext_struct)/4 + 6 + fs/4)
+#define UFRAME_SIZE(fs) (sizeof(struct sigcontext)/4 + 6 + fs/4)
static void setup_frame (struct sigaction * sa, struct pt_regs *regs,
int signr, unsigned long oldmask)
{
- struct sigcontext_struct context;
+ struct sigcontext context;
unsigned long *frame, *tframe;
- int fsize = extra_sizes[regs->format];
+ int fsize = frame_extra_sizes[regs->format];
if (fsize < 0) {
printk ("setup_frame: Unknown frame format %#x\n",
}
frame -= UFRAME_SIZE(fsize);
- if (verify_area(VERIFY_WRITE,frame,UFRAME_SIZE(fsize)*4))
- do_exit(SIGSEGV);
if (fsize) {
- memcpy_tofs (frame + UFRAME_SIZE(0), regs + 1, fsize);
+ if (copy_to_user (frame + UFRAME_SIZE(0), regs + 1, fsize))
+ do_exit(SIGSEGV);
regs->stkadj = fsize;
}
"m" (*context.sc_fpcntl)
: "memory");
}
- memcpy_tofs (tframe, &context, sizeof(context));
+ if (copy_to_user (tframe, &context, sizeof(context)))
+ do_exit(SIGSEGV);
/*
* no matter what frame format we were using before, we
isn't restarted (only needed on the
68030). */
if (regs->format == 10 || regs->format == 11) {
- regs->stkadj = extra_sizes[regs->format];
+ regs->stkadj = frame_extra_sizes[regs->format];
regs->format = 0;
}
continue;
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/mman.h>
+#include <linux/file.h>
#include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/cachectl.h>
#include <asm/traps.h>
+#include <asm/ipc.h>
/*
* sys_pipe() is the normal C calling standard for creating
* used a memory block for parameter passing..
*/
-asmlinkage int old_mmap(unsigned long *buffer)
+struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ unsigned long fd;
+ unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
int error;
- unsigned long flags;
struct file * file = NULL;
+ struct mmap_arg_struct a;
- error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
+ error = verify_area(VERIFY_READ, arg, sizeof(*arg));
if (error)
return error;
- flags = get_user(buffer+3);
- if (!(flags & MAP_ANONYMOUS)) {
- unsigned long fd = get_user(buffer+4);
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ copy_from_user(&a, arg, sizeof(a));
+ if (!(a.flags & MAP_ANONYMOUS)) {
+ if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
return -EBADF;
}
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- return do_mmap(file, get_user(buffer), get_user(buffer+1),
- get_user(buffer+2), flags, get_user(buffer+5));
+ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+ return error;
}
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 sel_arg_struct {
+ unsigned long n;
+ fd_set *inp, *outp, *exp;
struct timeval *tvp;
+};
- n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
- if (n)
- return n;
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+ struct sel_arg_struct a;
- 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);
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
/*
return -EINVAL;
if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
return err;
- fourth.__pad = get_user((void **)ptr);
+ get_user(fourth.__pad, (void **)ptr);
return sys_semctl (first, second, third, fourth);
}
default:
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));
+ if (copy_from_user (&tmp, ptr, sizeof (tmp)))
+ return -EFAULT;
return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
}
case 1: default:
#include <linux/mm.h>
#include <asm/machdep.h>
-#include <asm/segment.h>
#include <asm/io.h>
#include <linux/timex.h>
#include <asm/setup.h>
#include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/traps.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
vectors[VEC_FPNAN] = snan_vec;
vectors[VEC_FPOE] = operr_vec;
vectors[VEC_FPBRUC] = bsun_vec;
- vectors[VEC_FPBRUC] = bsun_vec;
vectors[VEC_LINE11] = fline_vec;
vectors[VEC_FPUNSUP] = unsupp_vec;
}
"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
- "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15"
+ "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+ "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+ "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+ "FPCP UNSUPPORTED OPERATION",
+ "MMU CONFIGUATION ERROR"
};
char *space_names[] = {
#endif
if (fslw & MMU060_MA)
addr = PAGE_ALIGN(addr);
- do_page_fault( (struct pt_regs *)fp, addr, errorcode );
+ do_page_fault(&fp->ptregs, addr, errorcode);
}
else {
printk( "68060 access error, fslw=%lx\n", fslw );
mmusr = probe040 (1, wbs & WBTM_040, wba);
errorcode = (mmusr & MMU_R_040) ? 3 : 2;
- if (do_page_fault ((struct pt_regs *)fp, wba, errorcode))
+ if (do_page_fault (&fp->ptregs, wba, errorcode))
/* just return if we can't perform the writeback */
return;
set_fs (wbs & WBTM_040);
switch (wbs & WBSIZ_040) {
case BA_SIZE_BYTE:
- put_fs_byte (wbd & 0xff, (char *)wba);
+ put_user (wbd & 0xff, (char *)wba);
break;
case BA_SIZE_WORD:
- put_fs_word (wbd & 0xffff, (short *)wba);
+ put_user (wbd & 0xffff, (short *)wba);
break;
case BA_SIZE_LONG:
- put_fs_long (wbd, (int *)wba);
+ put_user (wbd, (int *)wba);
break;
}
set_fs (fs);
*/
errorcode = ((mmusr & MMU_R_040) ? 1 : 0) |
((ssw & RW_040) ? 0 : 2);
- do_page_fault ((struct pt_regs *)fp, addr, errorcode);
+ do_page_fault (&fp->ptregs, addr, errorcode);
} else {
printk ("68040 access error, ssw=%x\n", ssw);
trap_c (fp);
}
printk ("BAD KERNEL BUSERR\n");
die_if_kernel("Oops",&fp->ptregs,0);
- force_sig(SIGSEGV, current);
- user_space_fault = 0;
+ force_sig(SIGKILL, current);
+ return;
}
} else {
/* user fault */
if (!(ssw & RW) || ssw & RM)
errorcode |= 2;
- if (mmusr & (MMU_I | MMU_WP))
- do_page_fault ((struct pt_regs *)fp, addr, errorcode);
- else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+ if (mmusr & (MMU_I | MMU_WP)) {
+ /* Don't try to do anything further if an exception was
+ handled. */
+ if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
+ return;
+ } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk ("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
#endif
if (mmusr & MMU_I)
- do_page_fault ((struct pt_regs *)fp, addr, 0);
+ do_page_fault (&fp->ptregs, addr, 0);
else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk ("invalid insn access at %#lx from pc %#lx\n",
addr, fp->ptregs.pc);
stack = (unsigned long *)addr;
endstack = (unsigned long *)PAGE_ALIGN(addr);
- printk("Stack from %08lx:\n ", (unsigned long)stack);
+ printk("Stack from %08lx:", (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) {
if (stack + 1 > endstack)
break;
- if (i && ((i % 8) == 0))
+ if (i % 8 == 0)
printk("\n ");
- printk("%08lx ", *stack++);
+ printk(" %08lx", *stack++);
}
- printk ("\nCall Trace: ");
+ printk ("\nCall Trace:");
stack = (unsigned long *) addr;
- i = 1;
+ i = 0;
module_start = VMALLOC_START;
module_end = module_start + MODULE_RANGE;
while (stack + 1 <= endstack) {
if (((addr >= (unsigned long) &_start) &&
(addr <= (unsigned long) &_etext)) ||
((addr >= module_start) && (addr <= module_end))) {
- if (i && ((i % 8) == 0))
+ if (i % 4 == 0)
printk("\n ");
- printk("[<%08lx>] ", addr);
+ printk(" [<%08lx>]", addr);
i++;
}
}
void bad_super_trap (struct frame *fp)
{
console_verbose();
- if ((fp->ptregs.vector) < 48*4)
+ if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
printk ("*** %s *** FORMAT=%X\n",
vec_names[(fp->ptregs.vector) >> 2],
fp->ptregs.format);
/*
- * copy from fs while checksumming, otherwise like csum_partial
+ * copy from user space while checksumming, otherwise like csum_partial
*/
unsigned int
"jgt 1f\n\t"
"addql #2,%1\n\t" /* len was == 2, treat only rest */
"jra 4f\n"
- "1:\t"
+ "1:\n"
+ "10:\t"
"movesw %2@+,%4\n\t" /* add first word to sum */
"addw %4,%0\n\t"
"movew %4,%3@+\n\t"
"lsrl #5,%1\n\t" /* len/32 */
"jeq 2f\n\t" /* not enough... */
"subql #1,%1\n"
- "1:\t"
+ "1:\n"
+ "11:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "12:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "13:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "14:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "15:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "16:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "17:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
+ "18:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
"jeq 4f\n\t"
"lsrw #2,%4\n\t"
"subqw #1,%4\n"
- "3:\t"
+ "3:\n"
/* loop for rest longs */
+ "19:\t"
"movesl %2@+,%5\n\t"
"addxl %5,%0\n\t"
"movel %5,%3@+\n\t"
"clrl %5\n\t" /* clear tmp2 for rest bytes */
"subqw #2,%1\n\t"
"jlt 5f\n\t"
+ "20:\t"
"movesw %2@+,%5\n\t" /* have rest >= 2: get word */
"movew %5,%3@+\n\t"
"swap %5\n\t" /* into bits 16..31 */
"tstw %1\n\t" /* another byte? */
"jeq 6f\n"
- "5:\t"
+ "5:\n"
+ "21:\t"
"movesb %2@,%5\n\t" /* have odd rest: get byte */
"moveb %5,%3@+\n\t"
"lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */
"addl %5,%0\n\t" /* now add rest long to sum */
"clrl %5\n\t"
"addxl %5,%0\n" /* add X bit */
- "7:\t"
+ "7:\n"
+ ".section __ex_table,\"a\"\n"
+ ".long 10b,7b\n"
+ ".long 11b,7b\n"
+ ".long 12b,7b\n"
+ ".long 13b,7b\n"
+ ".long 14b,7b\n"
+ ".long 15b,7b\n"
+ ".long 16b,7b\n"
+ ".long 17b,7b\n"
+ ".long 18b,7b\n"
+ ".long 19b,7b\n"
+ ".long 20b,7b\n"
+ ".long 21b,7b\n"
+ ".text"
: "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
"=&d" (tmp1), "=&d" (tmp2)
: "0" (sum), "1" (len), "2" (src), "3" (dst)
return(sum);
}
/*
- * copy from ds while checksumming, otherwise like csum_partial
+ * copy from kernel space while checksumming, otherwise like csum_partial
*/
unsigned int
/*
* "down_failed" is called with the eventual return address
* in %a0, and the address of the semaphore in %a1. We need
- * to increment the number of waiters on the semaphore,
- * call "__down()", and then eventually return to try again.
+ * to call "__down()", and then re-try until we succeed..
*/
-ENTRY(down_failed)
- movel %a0,-(%sp)
- movel %a1,-(%sp)
+ENTRY(__down_failed)
+ moveml %a0/%d0/%d1,-(%sp)
+1: movel %a1,-(%sp)
jbsr SYMBOL_NAME(__down)
movel (%sp)+,%a1
+ subql #1,(%a1)
+ jmi 1b
+ movel (%sp)+,%d0
+ movel (%sp)+,%d1
rts
-ENTRY(up_wakeup)
- movel %a0,-(%sp)
+ENTRY(__up_wakeup)
+ moveml %a0/%d0/%d1,-(%sp)
movel %a1,-(%sp)
jbsr SYMBOL_NAME(__up)
movel (%sp)+,%a1
+ movel (%sp)+,%d0
+ movel (%sp)+,%d1
rts
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
-O_OBJS := init.o fault.o memory.o
+O_OBJS := init.o fault.o memory.o extable.o
include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * linux/arch/m68k/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
+{
+ while (first <= last) {
+ const struct exception_table_entry *mid;
+ long diff;
+
+ mid = (last - first) / 2 + first;
+ diff = value - mid->insn;
+ if (diff >= 0 && diff <= 2)
+ return mid->fixup;
+ else if (diff > 0)
+ first = mid+1;
+ else
+ last = mid-1;
+ }
+ return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+ unsigned long ret;
+#ifdef CONFIG_MODULES
+ struct module *mp;
+#endif
+
+ /* Search the kernel's table first. */
+ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_MODULES
+ for (mp = module_list; mp != NULL; mp = mp->next) {
+ if (mp->exceptinfo.start != NULL) {
+ ret = search_one_table(mp->exceptinfo.start,
+ mp->exceptinfo.stop-1, addr);
+ if (ret)
+ return ret;
+ }
+ }
+#endif
+ return 0;
+}
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
#include <asm/system.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
extern void die_if_kernel(char *, struct pt_regs *, long);
+extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
/*
* This routine handles page faults. It determines the problem, and
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
- struct vm_area_struct * vma;
+ void (*handler)(struct task_struct *,
+ struct vm_area_struct *,
+ unsigned long,
+ int);
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
+ struct vm_area_struct * vma;
+ unsigned long fixup, fault_pc;
+ int write;
#ifdef DEBUG
printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
regs->sr, regs->pc, address, error_code,
- tsk->tss.pagedir_v);
+ tsk->mm->pgd);
#endif
down(&mm->mmap_sem);
* we can handle it..
*/
good_area:
- /*
- * was it a write?
- */
- if (error_code & 2) {
- if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
- /* read with protection fault? */
- if (error_code & 1)
- goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto bad_area;
- }
- if (error_code & 1) {
- do_wp_page(tsk, vma, address, error_code & 2);
- up(&mm->mmap_sem);
- return 0;
+ write = 0;
+ handler = do_no_page;
+ switch (error_code & 3) {
+ default: /* 3: write, present */
+ handler = do_wp_page;
+ /* fall through */
+ case 2: /* write, not present */
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ write++;
+ break;
+ case 1: /* read, present */
+ goto bad_area;
+ case 0: /* read, not present */
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto bad_area;
}
- do_no_page(tsk, vma, address, error_code & 2);
+ handler(tsk, vma, address, write);
up(&mm->mmap_sem);
/* There seems to be a missing invalidate somewhere in do_no_page.
*/
bad_area:
up(&mm->mmap_sem);
+
+ /* Are we prepared to handle this fault? */
+ if (CPU_IS_060 && regs->format == 4)
+ fault_pc = ((struct frame *)regs)->un.fmt4.pc;
+ else
+ fault_pc = regs->pc;
+ if ((fixup = search_exception_table(fault_pc)) != 0) {
+ struct pt_regs *tregs;
+ printk("Exception at %lx (%lx)\n", fault_pc, fixup);
+ /* Create a new four word stack frame, discarding the old
+ one. */
+ regs->stkadj = frame_extra_sizes[regs->format];
+ tregs = (struct pt_regs *)((ulong)regs + regs->stkadj);
+ tregs->vector = regs->vector;
+ tregs->format = 0;
+ tregs->pc = fixup;
+ tregs->sr = regs->sr;
+ return -1;
+ }
+
if (user_mode(regs)) {
/* User memory access */
force_sig (SIGSEGV, tsk);
return 1;
}
-
#endif
#include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
printk("\nMem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- i = high_memory >> PAGE_SHIFT;
+ i = max_mapnr;
while (i-- > 0) {
total++;
if (PageReserved(mem_map+i))
#endif
}
+#ifndef mm_cachebits
/*
* Bits to add to page descriptors for "normal" caching mode.
* For 68020/030 this is 0.
* For 68040, this is _PAGE_CACHE040 (cachable, copyback)
*/
unsigned long mm_cachebits = 0;
+#endif
pte_t *kernel_page_table (unsigned long *memavailp)
{
*/
for (i = 0; i < 64; i++) {
pte_val(ktablep[i]) = physaddr | _PAGE_PRESENT
- | _PAGE_CACHE040 | _PAGE_GLOBAL040;
+ | _PAGE_CACHE040 | _PAGE_GLOBAL040
+ | _PAGE_ACCESSED;
physaddr += PAGE_SIZE;
}
ktablep += 64;
* 64 entry section of the page table.
*/
- kpointerp[pindex++] = ktable | _PAGE_TABLE;
+ kpointerp[pindex++] = ktable | _PAGE_TABLE | _PAGE_ACCESSED;
} else {
/*
* 68030, use early termination page descriptors.
tbl = (unsigned long *)get_kpointer_table();
- kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE;
+ kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE |_PAGE_ACCESSED;
for (i = 0; i < 64; i++, physaddr += PAGE_SIZE)
- tbl[i] = physaddr | _PAGE_PRESENT;
+ tbl[i] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
/* unmap the zero page */
tbl[0] = 0;
} else {
/* not the first 256K */
- kpointerp[pindex++] = physaddr | _PAGE_PRESENT;
+ kpointerp[pindex++] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
#ifdef DEBUG
printk ("%lx=%lx ", VTOP(&kpointerp[pindex-1]),
kpointerp[pindex-1]);
/* Fix the cache mode in the page descriptors for the 680[46]0. */
if (CPU_IS_040_OR_060) {
int i;
+#ifndef mm_cachebits
mm_cachebits = _PAGE_CACHE040;
+#endif
for (i = 0; i < 16; i++)
pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
}
#endif
memset (swapper_pg_dir, 0, sizeof(pgd_t)*PTRS_PER_PGD);
- task[0]->tss.pagedir_v = (unsigned long *)swapper_pg_dir;
- task[0]->tss.pagedir_p = VTOP (swapper_pg_dir);
+
+ /* setup CPU root pointer for swapper task */
+ task[0]->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+ task[0]->tss.crp[1] = VTOP (swapper_pg_dir);
#ifdef DEBUG
printk ("task 0 pagedir at %p virt, %#lx phys\n",
- task[0]->tss.pagedir_v, task[0]->tss.pagedir_p);
+ swapper_pg_dir, task[0]->tss.crp[1]);
#endif
- /* setup CPU root pointer for swapper task */
- task[0]->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
- task[0]->tss.crp[1] = task[0]->tss.pagedir_p;
-
if (CPU_IS_040_OR_060)
asm __volatile__ ("movel %0,%/d0\n\t"
".long 0x4e7b0806" /* movec d0,urp */
extern int _etext;
end_mem &= PAGE_MASK;
- high_memory = end_mem;
+ high_memory = (void *) end_mem;
+ max_mapnr = MAP_NR(end_mem);
start_mem = PAGE_ALIGN(start_mem);
- while (start_mem < high_memory) {
+ while (start_mem < end_mem) {
clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
start_mem += PAGE_SIZE;
}
}
}
-#endif
-#ifdef DEBUG
- printk ("task[0] root table is %p\n", task[0]->tss.pagedir_v);
#endif
for (tmp = 0 ; tmp < end_mem ; tmp += PAGE_SIZE) {
#endif
free_page(tmp);
}
- tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
- tmp >> 10,
- high_memory >> 10,
+ (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
}
{
unsigned long i;
- i = high_memory >> PAGE_SHIFT;
+ i = max_mapnr;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
dmesg: dmesg.c
$(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
-
-CC = m68k-cbm-amigados-gcc
-CFLAGS = -Wall -O2
-
-
-All: dmesg
-
-
-dmesg: dmesg.c
- $(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
-
sti();
ide_fix_driveid(id);
-#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO)
+#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
/*
* EATA SCSI controllers do a hardware ATA emulation:
* Ignore them if there is a driver for them available.
#include <linux/module.h>
#include <linux/md.h>
-#include <linux/linear.h>
#include <linux/malloc.h>
+#include "linear.h"
+
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
--- /dev/null
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct linear_hash
+{
+ struct real_dev *dev0, *dev1;
+};
+
+struct linear_data
+{
+ struct linear_hash *hash_table; /* Dynamically allocated */
+ struct real_dev *smallest;
+ int nr_zones;
+};
+
+#endif
endif
endif
-ifeq ($(CONFIG_BAYCOM),y)
-L_OBJS += baycom.o
-else
- ifeq ($(CONFIG_BAYCOM),m)
- M_OBJS += baycom.o
- endif
-endif
-
ifdef CONFIG_TGA_CONSOLE
L_OBJS += tga.o
else
if (status & TRING_RxFIFO) lp->stats.rx_fifo_errors++;
} else {
/* Malloc up new buffer, compatible with net-2e. */
- short pkt_len = lp->rx_ring[entry].status >> 16;
+ /* Omit the four octet CRC from the length. */
+ short pkt_len = (lp->rx_ring[entry].status >> 16) - 4;
struct sk_buff *skb;
skb = dev_alloc_skb(pkt_len + 2);
DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
DEVICE( S3, S3_ViRGE, "ViRGE"),
DEVICE( S3, S3_TRIO, "Trio32/Trio64"),
+ DEVICE( S3, S3_AURORA64VP, "Aurora64V+"),
+ DEVICE( S3, S3_TRIO64UVP, "Trio64UV+"),
DEVICE( S3, S3_ViRGE_VX, "ViRGE/VX"),
DEVICE( S3, S3_868, "Vision 868"),
DEVICE( S3, S3_928, "Vision 928-P"),
dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
dep_tristate 'EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
-dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA $CONFIG_SCSI
+dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI
dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI
if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
/*
* eata.c - Low-level driver for EATA/DMA SCSI host adapters.
*
+ * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ * Added support for EATA 2.0C, PCI, multichannel and wide SCSI.
+ *
* 27 Sep 1996 rev. 2.12 for linux 2.1.0
* Portability cleanups (virtual/bus addressing, little/big endian
* support).
*
* Here is a brief description of the DPT SCSI host adapters.
* All these boards provide an EATA/DMA compatible programming interface
- * and are fully supported by this driver:
+ * and are fully supported by this driver in any configuration, including
+ * multiple SCSI channels:
*
* PM2011B/9X - Entry Level ISA
* PM2021A/9X - High Performance ISA
* PM2022A/9X - Entry Level EISA
* PM2122A/9X - High Performance EISA
* PM2322A/9X - Extra High Performance EISA
+ * PM3021 - SmartRAID Adapter for ISA
+ * PM3222 - SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI)
+ * PM3224 - SmartRAID Adapter for PCI (PM3224W is 16-bit wide SCSI)
*
* The DPT PM2001 provides only the EATA/PIO interface and hence is not
* supported by this driver.
*
* This code has been tested with up to 3 Distributed Processing Technology
* PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) eisa controllers,
- * no on board cache and no RAID option.
- * BIOS must be enabled on the first board and must be disabled for all other
- * boards.
- * Support is provided for any number of DPT PM2122 eisa boards.
- * All boards should be configured at the same IRQ level.
- * Multiple IRQ configurations are supported too.
- * Boards can be located in any eisa slot (1-15) and are named EATA0,
- * EATA1,... in increasing eisa slot number. ISA boards are detected
- * after the eisa slot probes.
+ * in any combination of private and shared IRQ.
+ * PCI support has been tested using a DPT PM3224W (firmware v07G.0).
+ *
+ * Multiple ISA, EISA and PCI boards can be configured in the same system.
+ * It is suggested to put all the EISA boards on the same IRQ level, all
+ * the PCI boards on another IRQ level, while ISA boards cannot share
+ * interrupts.
*
- * The IRQ for EISA boards should be _level_ triggered (not _edge_ triggered).
- * This is a requirement in order to support multiple boards on the same IRQ.
+ * If you configure multiple boards on the same IRQ, the interrupt must
+ * be _level_ triggered (not _edge_ triggered).
*
- * Other eisa configuration parameters are:
+ * This driver detects EATA boards by probes at fixed port addresses,
+ * so no BIOS32 or PCI BIOS support is used or required.
+ * The suggested way to detect a generic EATA PCI board is to force on it
+ * any unused EISA address, even if there are other controllers on the EISA
+ * bus, or even if you system has no EISA bus at all.
+ * Do not force any ISA address on EATA PCI boards.
*
- * COMMAND QUEUING : ENABLED
- * COMMAND TIMEOUT : ENABLED
- * CACHE : DISABLED
+ * The sequence of detection probes is:
+ * - ISA 0x1F0;
+ * - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15);
+ * - ISA 0x170, 0x230, 0x330.
+ *
+ * The boards are named EATA0, EATA1,... according to the detection order.
*
* In order to support multiple ISA boards in a reliable way,
* the driver sets host->wish_block = TRUE for all ISA boards.
#undef DEBUG_STATISTICS
#undef DEBUG_RESET
-#define MAX_TARGET 8
+#define MAX_CHANNEL 4
+#define MAX_LUN 32
+#define MAX_TARGET 32
#define MAX_IRQ 16
#define MAX_BOARDS 18
#define MAX_MAILBOXES 64
#define MAX_SGLIST 64
+#define MAX_LARGE_SGLIST 252
#define MAX_INTERNAL_RETRIES 64
#define MAX_CMD_PER_LUN 2
#define REG_MID 4
#define REG_MSB 5
#define REGION_SIZE 9
-#define EISA_RANGE 0xf000
+#define EISA_RANGE 0x1000
#define BSY_ASSERTED 0x80
#define DRQ_ASSERTED 0x08
#define ABSY_ASSERTED 0x01
/* Number of valid bytes in the board config structure for EATA 2.0x */
#define EATA_2_0A_SIZE 28
#define EATA_2_0B_SIZE 30
+#define EATA_2_0C_SIZE 34
/* Board info structure */
struct eata_info {
ata:1, /* This is an ATA device */
haaval:1; /* Host Adapter Address Valid */
ushort cp_pad_len; /* Number of pad bytes after cp_len */
- unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
- unchar reserved;
+ unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
ulong cp_len; /* Number of valid bytes in cp */
ulong sp_len; /* Number of valid bytes in sp */
ushort queue_size; /* Max number of cp that can be queued */
unchar isaena:1, /* ISA i/o addressing is disabled/enabled */
forcaddr:1, /* Port address has been forced */
:6;
- unchar max_id:5, /* Max number of SCSI target IDs */
+ unchar max_id:5, /* Max SCSI target ID number */
max_chan:3; /* Max SCSI channel number on this board */
- ushort ipad[249];
+ /* Structure extension defined in EATA 2.0C */
+ unchar max_lun; /* Max SCSI LUN number */
+ unchar notused[3];
+
+ ushort ipad[247];
};
/* Board config structure */
unchar unused[4];
unchar phsunit:1, /* Send to Target Physical Unit (bypass RAID) */
notused:7;
- unchar target; /* SCSI Target ID */
- unchar lun:3, /* LUN */
- :2,
+ unchar target:5, /* SCSI target ID */
+ channel:3; /* SCSI channel number */
+ unchar lun:5, /* SCSI logical unit number */
luntar:1, /* This cp is for Target (not LUN) */
dispri:1, /* Disconnect Privilege granted */
one:1; /* 1 */
char board_name[16]; /* Name of this board */
char board_id[256]; /* data from INQUIRY on this board */
int in_reset; /* True if board is doing a reset */
- int target_time_out[MAX_TARGET]; /* N. of timeout errors on target */
- int target_reset[MAX_TARGET]; /* If TRUE redo operation on target */
+ int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+ int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
unsigned int retries; /* Number of internal retries */
unsigned long last_retried_pid; /* Pid of last retried command */
- unsigned char subversion; /* Bus type, either ISA or ESA */
+ unsigned char subversion; /* Bus type, either ISA or EISA/PCI */
unsigned char protocol_rev; /* EATA 2.0 rev., 'A' or 'B' or 'C' */
struct mssp sp[MAX_MAILBOXES]; /* Returned status for this board */
};
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "EATA";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "EATA";
static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
static void eata2x_interrupt_handler(int, void *, struct pt_regs *);
static int do_trace = FALSE;
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
unsigned int loop = MAXLOOP;
while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED)
return FALSE;
}
-static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
+static inline int do_dma(unsigned int iobase, unsigned int addr, unchar cmd) {
if (wait_on_busy(iobase)) return TRUE;
return FALSE;
}
-static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
+static inline int read_pio(unsigned int iobase, ushort *start, ushort *end) {
unsigned int loop = MAXLOOP;
ushort *p;
return FALSE;
}
-static inline int port_detect(ushort *port_base, unsigned int j,
- Scsi_Host_Template * tpnt) {
- unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j,
+ Scsi_Host_Template *tpnt) {
+ unsigned char irq, dma_channel, subversion, c;
unsigned char protocol_rev;
struct eata_info info;
- const char *board_status;
/* Allowed DMA channels for ISA (0 indicates reserved) */
unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
else
protocol_rev = 'C';
- if (protocol_rev != 'A' && info.max_chan > 0)
- printk("%s: warning, only scsi channel 0 is supported.\n", name);
-
irq = info.irq;
- if (*port_base & EISA_RANGE) {
+ if (*port_base >= EISA_RANGE) {
if (!info.haaval || info.ata || info.drqvld) {
- printk("%s: unusable EISA board found (%d%d%d), detaching.\n",
+ printk("%s: unusable EISA/PCI board found (%d%d%d), detaching.\n",
name, info.haaval, info.ata, info.drqvld);
return FALSE;
}
printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
name, irq);
- if (info.second)
- board_status = "Sec.";
- else
- board_status = "Prim.";
-
/* Board detected, allocate its IRQ if not already done */
if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
(irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) {
}
sh[j]->io_port = *port_base;
+ sh[j]->unique_id = *port_base;
sh[j]->n_io_port = REGION_SIZE;
sh[j]->dma_channel = dma_channel;
sh[j]->irq = irq;
enable_dma(dma_channel);
}
+ if (protocol_rev != 'A' && info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
+ sh[j]->max_channel = info.max_chan;
+
+ if (protocol_rev != 'A' && info.max_id > 7 && info.max_id < MAX_TARGET)
+ sh[j]->max_id = info.max_id + 1;
+
+ if (protocol_rev == 'C' && info.max_lun > 7 && info.max_lun < MAX_LUN)
+ sh[j]->max_lun = info.max_lun + 1;
+
strcpy(BN(j), name);
- printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
- "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status,
- sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
+ printk("%s: rev. 2.0%c, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
+ "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev,
+ sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
/* DPT PM2012 does not allow to detect sg_tablesize correctly */
sh[j]->can_queue = MAX_MAILBOXES;
}
+ if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+ printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+ BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+ BN(j), c, info.host_addr[3 - c]);
+
#if defined (DEBUG_DETECT)
if (protocol_rev != 'A')
printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
- " max_chan %u.\n", name, protocol_rev, info.isaena,
- info.forcaddr, info.max_id, info.max_chan);
+ " max_chan %u, max_lun %u.\n", name, protocol_rev, info.isaena,
+ info.forcaddr, info.max_id, info.max_chan, info.max_lun);
- printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n",
- name, info.version, info.sync, DEV2H(info.data_len),
+ printk("%s: Vers. 0x%x, SYNC 0x%x, sec. %u, infol %ld, cpl %ld spl %ld.\n",
+ name, info.version, info.sync, info.second, DEV2H(info.data_len),
DEV2H(info.cp_len), DEV2H(info.sp_len));
#endif
return TRUE;
}
-int eata2x_detect (Scsi_Host_Template * tpnt) {
+int eata2x_detect(Scsi_Host_Template *tpnt) {
unsigned int j = 0, k, flags;
- ushort io_port[] = {
- 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
- 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
- 0x1f0, 0x170, 0x330, 0x230, 0x0
+ unsigned int io_port[] = {
+ 0x1f0, 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88,
+ 0x8c88, 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
+ 0x170, 0x230, 0x330, 0x0
};
- ushort *port_base = io_port;
+ unsigned int *port_base = io_port;
tpnt->proc_dir = &proc_scsi_eata2x;
static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
unsigned int k;
- struct scatterlist * sgpnt;
+ struct scatterlist *sgpnt;
sgpnt = (struct scatterlist *) SCpnt->request_buffer;
cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
}
-int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
unsigned int i, j, k, flags;
struct mscp *cpp;
struct mssp *spp;
cpp->index = i;
SCpnt->host_scribble = (unsigned char *) &cpp->index;
- if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCpnt->target, SCpnt->pid);
+ if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+ BN(j), i, SCpnt->channel, SCpnt->target,
+ SCpnt->lun, SCpnt->pid);
for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
if (SCpnt->cmnd[0] == data_out_cmds[k]) {
cpp->reqsen = TRUE;
cpp->dispri = TRUE;
cpp->one = TRUE;
+ cpp->channel = SCpnt->channel;
cpp->target = SCpnt->target;
cpp->lun = SCpnt->lun;
cpp->SCpnt = SCpnt;
if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
SCpnt->result = DID_ERROR << 16;
SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n",
- BN(j), SCpnt->target, SCpnt->pid);
+ printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+ " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+ SCpnt->pid);
restore_flags(flags);
done(SCpnt);
return 0;
return 0;
}
-int eata2x_abort (Scsi_Cmnd *SCarg) {
+int eata2x_abort(Scsi_Cmnd *SCarg) {
unsigned int i, j, flags;
save_flags(flags);
j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d, pid %ld inactive.\n",
- BN(j), SCarg->target, SCarg->pid);
+ printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+ BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
restore_flags(flags);
return SCSI_ABORT_NOT_RUNNING;
}
i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCarg->target, SCarg->pid);
+ printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+ BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
if (i >= sh[j]->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
}
-int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) {
- unsigned int i, j, flags, time, k, limit = 0;
+int eata2x_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+ unsigned int i, j, flags, time, k, c, limit = 0;
int arg_done = FALSE;
Scsi_Cmnd *SCpnt;
save_flags(flags);
cli();
j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
- printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n",
- BN(j), SCarg->target, SCarg->pid, reset_flags);
+ printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n",
+ BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+ reset_flags);
if (SCarg->host_scribble == NULL)
printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
HD(j)->retries = 0;
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ for (k = 0; k < sh[j]->max_id; k++) {
+ HD(j)->target_redo[k][c] = TRUE;
+ HD(j)->target_to[k][c] = 0;
+ }
for (i = 0; i < sh[j]->can_queue; i++) {
}
}
-static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void eata2x_interrupt_handler(int irq, void *dev_id,
+ struct pt_regs *regs) {
Scsi_Cmnd *SCpnt;
- unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+ unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
struct mssp *spp;
struct mscp *cpp;
status = DID_ERROR << 16;
/* If there was a bus reset, redo operation on each target */
- else if (tstatus != GOOD
- && SCpnt->device->type == TYPE_DISK
- && HD(j)->target_reset[SCpnt->target])
+ else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+ && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
status = DID_BUS_BUSY << 16;
/* Works around a flaw in scsi.c */
status = DID_OK << 16;
if (tstatus == GOOD)
- HD(j)->target_reset[SCpnt->target] = FALSE;
+ HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
if (spp->target_status && SCpnt->device->type == TYPE_DISK)
- printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
- "0x%x, sense key 0x%x.\n", BN(j),
- SCpnt->target, SCpnt->lun, SCpnt->pid,
- spp->target_status, SCpnt->sense_buffer[2]);
+ printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+ "target_status 0x%x, sense key 0x%x.\n", BN(j),
+ SCpnt->channel, SCpnt->target, SCpnt->lun,
+ SCpnt->pid, spp->target_status,
+ SCpnt->sense_buffer[2]);
- HD(j)->target_time_out[SCpnt->target] = 0;
+ HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
case ASST: /* Selection Time Out */
case 0x02: /* Command Time Out */
- if (HD(j)->target_time_out[SCpnt->target] > 1)
+ if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
status = DID_ERROR << 16;
else {
status = DID_TIME_OUT << 16;
- HD(j)->target_time_out[SCpnt->target]++;
+ HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
}
break;
case 0x03: /* SCSI Bus Reset Received */
case 0x04: /* Initial Controller Power-up */
- for (k = 0; k < MAX_TARGET; k++)
- HD(j)->target_reset[k] = TRUE;
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ for (k = 0; k < sh[j]->max_id; k++)
+ HD(j)->target_redo[k][c] = TRUE;
if (SCpnt->device->type != TYPE_TAPE
&& HD(j)->retries < MAX_INTERNAL_RETRIES) {
do_trace)
#endif
printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
- " target %d:%d, pid %ld, count %d.\n",
+ " target %d.%d:%d, pid %ld, count %d.\n",
BN(j), i, spp->adapter_status, spp->target_status,
- SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+ SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+ HD(j)->iocount);
/* Set the command state to inactive */
SCpnt->host_scribble = NULL;
int eata2x_abort(Scsi_Cmnd *);
int eata2x_reset(Scsi_Cmnd *, unsigned int);
-#define EATA_VERSION "2.12.00"
+#define EATA_VERSION "2.20.00"
#define EATA { \
blocks--;
}
+ if (blocks) {
#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: EXTRA: Waiting for buffer\n");
+ printk("53C400r: EXTRA: Waiting for buffer\n");
#endif
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
- ;
+ while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+ ;
#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: Transferring EXTRA 128 bytes\n");
+ printk("53C400r: Transferring EXTRA 128 bytes\n");
#endif
#ifdef CONFIG_SCSI_G_NCR5380_PORT
for (i=0; i<128; i++)
/* implies CONFIG_SCSI_G_NCR5380_MEM */
memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
#endif
- start+=128;
- blocks--;
+ start+=128;
+ blocks--;
+ }
+#if (NDEBUG & NDEBUG_C400_PREAD)
+ else
+ printk("53C400r: No EXTRA required\n");
+#endif
#if (NDEBUG & NDEBUG_C400_PREAD)
printk("53C400r: Final values: blocks=%d start=%d\n", blocks, start);
case CDROMPLAYMSF:
{
- struct cdrom_msf* msf = (struct cdrom_msf*)arg;
+ struct cdrom_msf msf;
+
+ if (copy_from_user(&msf, (void *) arg, sizeof(msf))) {
+ result = -EFAULT;
+ break;
+ }
sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
sr_cmd[1] = scsi_CDs[target].device->lun << 5;
sr_cmd[2] = 0;
- sr_cmd[3] = msf->cdmsf_min0;
- sr_cmd[4] = msf->cdmsf_sec0;
- sr_cmd[5] = msf->cdmsf_frame0;
- sr_cmd[6] = msf->cdmsf_min1;
- sr_cmd[7] = msf->cdmsf_sec1;
- sr_cmd[8] = msf->cdmsf_frame1;
+ sr_cmd[3] = msf.cdmsf_min0;
+ sr_cmd[4] = msf.cdmsf_sec0;
+ sr_cmd[5] = msf.cdmsf_frame0;
+ sr_cmd[6] = msf.cdmsf_min1;
+ sr_cmd[7] = msf.cdmsf_sec1;
+ sr_cmd[8] = msf.cdmsf_frame1;
sr_cmd[9] = 0;
result = sr_do_ioctl(target, sr_cmd, NULL, 255);
case CDROMPLAYBLK:
{
- struct cdrom_blk* blk = (struct cdrom_blk*)arg;
+ struct cdrom_blk blk;
+
+ if (copy_from_user(&blk, (void *) arg, sizeof(blk))) {
+ result = -EFAULT;
+ break;
+ }
sr_cmd[0] = SCMD_PLAYAUDIO10;
sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = blk->from >> 24;
- sr_cmd[3] = blk->from >> 16;
- sr_cmd[4] = blk->from >> 8;
- sr_cmd[5] = blk->from;
+ sr_cmd[2] = blk.from >> 24;
+ sr_cmd[3] = blk.from >> 16;
+ sr_cmd[4] = blk.from >> 8;
+ sr_cmd[5] = blk.from;
sr_cmd[6] = 0;
- sr_cmd[7] = blk->len >> 8;
- sr_cmd[8] = blk->len;
+ sr_cmd[7] = blk.len >> 8;
+ sr_cmd[8] = blk.len;
sr_cmd[9] = 0;
result = sr_do_ioctl(target, sr_cmd, NULL, 255);
case CDROMPLAYTRKIND:
{
- struct cdrom_ti* ti = (struct cdrom_ti*)arg;
+ struct cdrom_ti ti;
+
+ if (copy_from_user(&ti, (void *) arg, sizeof(ti))) {
+ result = -EFAULT;
+ break;
+ }
sr_cmd[0] = SCMD_PLAYAUDIO_TI;
sr_cmd[1] = scsi_CDs[target].device->lun << 5;
sr_cmd[2] = 0;
sr_cmd[3] = 0;
- sr_cmd[4] = ti->cdti_trk0;
- sr_cmd[5] = ti->cdti_ind0;
+ sr_cmd[4] = ti.cdti_trk0;
+ sr_cmd[5] = ti.cdti_ind0;
sr_cmd[6] = 0;
- sr_cmd[7] = ti->cdti_trk1;
- sr_cmd[8] = ti->cdti_ind1;
+ sr_cmd[7] = ti.cdti_trk1;
+ sr_cmd[8] = ti.cdti_ind1;
sr_cmd[9] = 0;
result = sr_do_ioctl(target, sr_cmd, NULL, 255);
case CDROMREADTOCHDR:
{
- struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
+ struct cdrom_tochdr tochdr;
char * buffer;
sr_cmd[0] = SCMD_READ_TOC;
result = sr_do_ioctl(target, sr_cmd, buffer, 12);
- tochdr->cdth_trk0 = buffer[2];
- tochdr->cdth_trk1 = buffer[3];
+ tochdr.cdth_trk0 = buffer[2];
+ tochdr.cdth_trk1 = buffer[3];
scsi_free(buffer, 512);
+
+ if (copy_to_user ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr)))
+ result = -EFAULT;
break;
}
case CDROMREADTOCENTRY:
{
- struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
+ struct cdrom_tocentry tocentry;
unsigned char * buffer;
+ if (copy_from_user (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry))) {
+ result = -EFAULT;
+ break;
+ }
+
sr_cmd[0] = SCMD_READ_TOC;
sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |
- (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
+ (tocentry.cdte_format == CDROM_MSF ? 0x02 : 0);
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
- sr_cmd[6] = tocentry->cdte_track;
+ sr_cmd[6] = tocentry.cdte_track;
sr_cmd[7] = 0; /* MSB of length (12) */
sr_cmd[8] = 12; /* LSB of length */
sr_cmd[9] = 0;
result = sr_do_ioctl (target, sr_cmd, buffer, 12);
- tocentry->cdte_ctrl = buffer[5] & 0xf;
- tocentry->cdte_adr = buffer[5] >> 4;
- tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
- if (tocentry->cdte_format == CDROM_MSF) {
- tocentry->cdte_addr.msf.minute = buffer[9];
- tocentry->cdte_addr.msf.second = buffer[10];
- tocentry->cdte_addr.msf.frame = buffer[11];
+ tocentry.cdte_ctrl = buffer[5] & 0xf;
+ tocentry.cdte_adr = buffer[5] >> 4;
+ tocentry.cdte_datamode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0;
+ if (tocentry.cdte_format == CDROM_MSF) {
+ tocentry.cdte_addr.msf.minute = buffer[9];
+ tocentry.cdte_addr.msf.second = buffer[10];
+ tocentry.cdte_addr.msf.frame = buffer[11];
} else
- tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
+ tocentry.cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
+ buffer[10]) << 8) + buffer[11];
scsi_free(buffer, 512);
+
+ if (copy_to_user ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry)))
+ result = -EFAULT;
break;
}
case CDROMVOLCTRL:
{
char * buffer, * mask;
- struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+ struct cdrom_volctrl volctrl;
+ if (copy_from_user (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl))) {
+ result = -EFAULT;
+ break;
+ }
+
/* First we get the current params so we can just twiddle the volume */
sr_cmd[0] = MODE_SENSE;
/* Now mask and substitute our own volume and reuse the rest */
buffer[0] = 0; /* Clear reserved field */
- buffer[21] = volctrl->channel0 & mask[21];
- buffer[23] = volctrl->channel1 & mask[23];
- buffer[25] = volctrl->channel2 & mask[25];
- buffer[27] = volctrl->channel3 & mask[27];
+ buffer[21] = volctrl.channel0 & mask[21];
+ buffer[23] = volctrl.channel1 & mask[23];
+ buffer[25] = volctrl.channel2 & mask[25];
+ buffer[27] = volctrl.channel3 & mask[27];
sr_cmd[0] = MODE_SELECT;
sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10; /* Params are SCSI-2 */
case CDROMVOLREAD:
{
char * buffer;
- struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+ struct cdrom_volctrl volctrl;
/* Get the current params */
break;
}
- volctrl->channel0 = buffer[21];
- volctrl->channel1 = buffer[23];
- volctrl->channel2 = buffer[25];
- volctrl->channel3 = buffer[27];
+ volctrl.channel0 = buffer[21];
+ volctrl.channel1 = buffer[23];
+ volctrl.channel2 = buffer[25];
+ volctrl.channel3 = buffer[27];
scsi_free(buffer, 512);
+
+ if (copy_to_user ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl)))
+ result = -EFAULT;
break;
}
case CDROMSUBCHNL:
{
- struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
+ struct cdrom_subchnl subchnl;
char * buffer;
sr_cmd[0] = SCMD_READ_SUBCHANNEL;
result = sr_do_ioctl(target, sr_cmd, buffer, 16);
- subchnl->cdsc_audiostatus = buffer[1];
- subchnl->cdsc_format = CDROM_MSF;
- subchnl->cdsc_ctrl = buffer[5] & 0xf;
- subchnl->cdsc_trk = buffer[6];
- subchnl->cdsc_ind = buffer[7];
+ subchnl.cdsc_audiostatus = buffer[1];
+ subchnl.cdsc_format = CDROM_MSF;
+ subchnl.cdsc_ctrl = buffer[5] & 0xf;
+ subchnl.cdsc_trk = buffer[6];
+ subchnl.cdsc_ind = buffer[7];
- subchnl->cdsc_reladdr.msf.minute = buffer[13];
- subchnl->cdsc_reladdr.msf.second = buffer[14];
- subchnl->cdsc_reladdr.msf.frame = buffer[15];
- subchnl->cdsc_absaddr.msf.minute = buffer[9];
- subchnl->cdsc_absaddr.msf.second = buffer[10];
- subchnl->cdsc_absaddr.msf.frame = buffer[11];
+ subchnl.cdsc_reladdr.msf.minute = buffer[13];
+ subchnl.cdsc_reladdr.msf.second = buffer[14];
+ subchnl.cdsc_reladdr.msf.frame = buffer[15];
+ subchnl.cdsc_absaddr.msf.minute = buffer[9];
+ subchnl.cdsc_absaddr.msf.second = buffer[10];
+ subchnl.cdsc_absaddr.msf.frame = buffer[11];
scsi_free(buffer, 512);
+
+ if (copy_to_user ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)))
+ result = -EFAULT;
break;
}
default:
/*
* u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
*
+ * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ * Added multichannel support.
+ *
* 27 Sep 1996 rev. 2.12 for linux 2.1.0
* Portability cleanups (virtual/bus addressing, little/big endian
* support).
#undef DEBUG_STATISTICS
#undef DEBUG_RESET
+#define MAX_CHANNEL 1
+#define MAX_LUN 8
#define MAX_TARGET 8
#define MAX_IRQ 16
#define MAX_BOARDS 4
unsigned char dcn: 1; /* disable disconnect */
unsigned char ca: 1; /* use cache (if available) */
unsigned char sg: 1; /* scatter/gather operation */
- unsigned char target: 3; /* target SCSI id */
- unsigned char ch_no: 2; /* SCSI channel (always 0 for 14f) */
- unsigned char lun: 3; /* logical unit number */
+ unsigned char target: 3; /* SCSI target id */
+ unsigned char channel: 2; /* SCSI channel number */
+ unsigned char lun: 3; /* SCSI logical unit number */
unsigned int data_address PACKED; /* transfer data pointer */
unsigned int data_len PACKED; /* length in bytes */
unsigned int command_link PACKED; /* for linking command chains */
char board_name[16]; /* Name of this board */
char board_id[256]; /* data from INQUIRY on this board */
int in_reset; /* True if board is doing a reset */
- int target_time_out[MAX_TARGET]; /* N. of timeout errors on target */
- int target_reset[MAX_TARGET]; /* If TRUE redo operation on target */
+ int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+ int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
unsigned int retries; /* Number of internal retries */
unsigned long last_retried_pid; /* Pid of last retried command */
unsigned char subversion; /* Bus type, either ISA or ESA */
unsigned char slot;
};
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "Ux4F";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "Ux4F";
static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
static void u14_34f_interrupt_handler(int, void *, struct pt_regs *);
static int do_trace = FALSE;
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
unsigned int loop = MAXLOOP;
while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED)
return FALSE;
}
-static inline int port_detect(ushort *port_base, unsigned int j,
- Scsi_Host_Template * tpnt) {
- unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j,
+ Scsi_Host_Template *tpnt) {
+ unsigned char irq, dma_channel, subversion, c;
unsigned char in_byte;
/* Allowed BIOS base addresses (NULL indicates reserved) */
}
sh[j]->io_port = *port_base;
+ sh[j]->unique_id = *port_base;
sh[j]->n_io_port = REGION_SIZE;
sh[j]->base = bios_segment_table[config_1.bios_segment];
sh[j]->irq = irq;
enable_dma(dma_channel);
}
+ sh[j]->max_channel = MAX_CHANNEL - 1;
+ sh[j]->max_id = MAX_TARGET;
+ sh[j]->max_lun = MAX_LUN;
+
if (HD(j)->subversion == ISA && !board_inquiry(j)) {
HD(j)->board_id[40] = 0;
printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, DMA %u, SG %d, "\
"Mbox %d, CmdLun %d, C%d.\n", BN(j), sh[j]->io_port,
- (int)sh[j]->base, sh[j]->irq,
- sh[j]->dma_channel, sh[j]->sg_tablesize,
- sh[j]->can_queue, sh[j]->cmd_per_lun,
+ (int)sh[j]->base, sh[j]->irq, sh[j]->dma_channel,
+ sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun,
sh[j]->hostt->use_clustering);
+
+ if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+ printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+ BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+ BN(j), c, sh[j]->this_id);
+
return TRUE;
}
-int u14_34f_detect (Scsi_Host_Template * tpnt) {
+int u14_34f_detect(Scsi_Host_Template *tpnt) {
unsigned int j = 0, k, flags;
- ushort io_port[] = {
+ unsigned int io_port[] = {
0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, 0x0
};
- ushort *port_base = io_port;
+ unsigned int *port_base = io_port;
tpnt->proc_dir = &proc_scsi_u14_34f;
static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
unsigned int k, data_len = 0;
- struct scatterlist * sgpnt;
+ struct scatterlist *sgpnt;
sgpnt = (struct scatterlist *) SCpnt->request_buffer;
cpp->index = i;
SCpnt->host_scribble = (unsigned char *) &cpp->index;
- if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCpnt->target, SCpnt->pid);
+ if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+ BN(j), i, SCpnt->channel, SCpnt->target,
+ SCpnt->lun, SCpnt->pid);
cpp->xdir = DTD_IN;
}
cpp->opcode = OP_SCSI;
+ cpp->channel = SCpnt->channel;
cpp->target = SCpnt->target;
cpp->lun = SCpnt->lun;
cpp->SCpnt = SCpnt;
if (wait_on_busy(sh[j]->io_port)) {
SCpnt->result = DID_ERROR << 16;
SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n",
- BN(j), SCpnt->target, SCpnt->pid);
+ printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+ " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+ SCpnt->pid);
restore_flags(flags);
done(SCpnt);
return 0;
j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d, pid %ld inactive.\n",
- BN(j), SCarg->target, SCarg->pid);
+ printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+ BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
restore_flags(flags);
return SCSI_ABORT_NOT_RUNNING;
}
i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCarg->target, SCarg->pid);
+ printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+ BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
if (i >= sh[j]->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
}
-int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) {
- unsigned int i, j, flags, time, k, limit = 0;
+int u14_34f_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+ unsigned int i, j, flags, time, k, c, limit = 0;
int arg_done = FALSE;
Scsi_Cmnd *SCpnt;
save_flags(flags);
cli();
j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
- printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n",
- BN(j), SCarg->target, SCarg->pid, reset_flags);
+ printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n",
+ BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+ reset_flags);
if (SCarg->host_scribble == NULL)
printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
HD(j)->retries = 0;
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ for (k = 0; k < sh[j]->max_id; k++) {
+ HD(j)->target_redo[k][c] = TRUE;
+ HD(j)->target_to[k][c] = 0;
+ }
for (i = 0; i < sh[j]->can_queue; i++) {
}
}
-int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
+int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
unsigned int j = 0;
int size = disk->capacity;
return 0;
}
-static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void u14_34f_interrupt_handler(int irq, void *dev_id,
+ struct pt_regs *regs) {
Scsi_Cmnd *SCpnt;
- unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+ unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
struct mscp *spp;
save_flags(flags);
status = DID_ERROR << 16;
/* If there was a bus reset, redo operation on each target */
- else if (tstatus != GOOD
- && SCpnt->device->type == TYPE_DISK
- && HD(j)->target_reset[SCpnt->target])
+ else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+ && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
status = DID_BUS_BUSY << 16;
/* Works around a flaw in scsi.c */
status = DID_OK << 16;
if (tstatus == GOOD)
- HD(j)->target_reset[SCpnt->target] = FALSE;
+ HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
if (spp->target_status && SCpnt->device->type == TYPE_DISK)
- printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
- "0x%x, sense key 0x%x.\n", BN(j),
- SCpnt->target, SCpnt->lun, SCpnt->pid,
- spp->target_status, SCpnt->sense_buffer[2]);
+ printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+ "target_status 0x%x, sense key 0x%x.\n", BN(j),
+ SCpnt->channel, SCpnt->target, SCpnt->lun,
+ SCpnt->pid, spp->target_status,
+ SCpnt->sense_buffer[2]);
- HD(j)->target_time_out[SCpnt->target] = 0;
+ HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
break;
case ASST: /* Selection Time Out */
- if (HD(j)->target_time_out[SCpnt->target] > 1)
+ if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
status = DID_ERROR << 16;
else {
status = DID_TIME_OUT << 16;
- HD(j)->target_time_out[SCpnt->target]++;
+ HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
}
break;
case 0x96: /* Illegal SCSI command */
case 0xa3: /* SCSI bus reset error */
- for (k = 0; k < MAX_TARGET; k++)
- HD(j)->target_reset[k] = TRUE;
+ for (c = 0; c <= sh[j]->max_channel; c++)
+ for (k = 0; k < sh[j]->max_id; k++)
+ HD(j)->target_redo[k][c] = TRUE;
+
case 0x92: /* Data over/under-run */
do_trace)
#endif
printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
- " target %d:%d, pid %ld, count %d.\n",
+ " target %d.%d:%d, pid %ld, count %d.\n",
BN(j), i, spp->adapter_status, spp->target_status,
- SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+ SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+ HD(j)->iocount);
/* Set the command state to inactive */
SCpnt->host_scribble = NULL;
int u14_34f_reset(Scsi_Cmnd *, unsigned int);
int u14_34f_biosparam(Disk *, kdev_t, int *);
-#define U14_34F_VERSION "2.12.00"
+#define U14_34F_VERSION "2.20.00"
#define ULTRASTOR_14_34F { \
NULL, /* Ptr for modules */ \
*
* Copyright (C) 1996 Brian A. Lantz
* derived from binfmt_script.c
+ *
+ * Simplified and modified to support binary java interpreters
+ * by Tom May <ftom@netcom.com>.
*/
#include <linux/module.h>
#define _PATH_JAVA "/usr/bin/java"
#define _PATH_APPLET "/usr/bin/appletviewer"
-#define _PATH_SH "/bin/bash"
+
+/* These paths can be modified with sysctl(). */
char binfmt_java_interpreter[65] = _PATH_JAVA;
char binfmt_java_appletviewer[65] = _PATH_APPLET;
-static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs)
{
- char *cp, *interp, *i_name;
+ char *i_name;
+ int len;
int retval;
unsigned char *ucp = (unsigned char *) bprm->buf;
if ((ucp[0] != 0xca) || (ucp[1] != 0xfe) || (ucp[2] != 0xba) || (ucp[3] != 0xbe))
return -ENOEXEC;
+ /*
+ * Fail if we're called recursively, e.g., the Java interpreter
+ * is a java binary.
+ */
+
+ if (bprm->java)
+ return -ENOEXEC;
+
+ bprm->java = 1;
+
iput(bprm->inode);
bprm->dont_iput=1;
/*
- * OK, we've set the interpreter name
- * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
- * (2) the name of the java wrapper for argv[1] (_PATH_JAVA)
- * (3) filename of Java class (replace argv[0])
- * without leading path or trailing '.class'
+ * Set args: [0] the name of the java interpreter
+ * [1] name of java class to execute, which is the
+ * filename without the path and without trailing
+ * ".class". Note that the interpreter will use
+ * its own way to found the class file (typically using
+ * environment variable CLASSPATH), and may in fact
+ * execute a different file from the one we want.
*
* This is done in reverse order, because of how the
* user environment and arguments are stored.
*/
remove_arg_zero(bprm);
- if ((cp = strstr (bprm->filename, ".class")) != NULL)
- *cp = 0;
+ len = strlen (bprm->filename);
+ if (len >= 6 && !strcmp (bprm->filename + len - 6, ".class"))
+ bprm->filename[len - 6] = 0;
if ((i_name = strrchr (bprm->filename, '/')) != NULL)
i_name++;
else
bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
bprm->argc++;
- strcpy (bprm->buf, binfmt_java_interpreter);
- cp = bprm->buf;
- bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
- bprm->argc++;
-
- strcpy (bprm->buf, _PATH_SH);
- interp = bprm->buf;
- if ((i_name = strrchr (bprm->buf, '/')) != NULL)
- i_name++;
- else
- i_name = bprm->buf;
+ i_name = binfmt_java_interpreter;
bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
bprm->argc++;
+
if (!bprm->p)
return -E2BIG;
/*
* OK, now restart the process with the interpreter's inode.
- * Note that we use open_namei() as the name is now in kernel
- * space, and we don't need to copy it.
*/
- retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+ bprm->filename = binfmt_java_interpreter;
+ retval = open_namei(binfmt_java_interpreter, 0, 0, &bprm->inode, NULL);
if (retval)
return retval;
bprm->dont_iput=0;
static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
{
- char *cp, *interp, *i_name;
+ char *i_name;
int retval;
if (strncmp (bprm->buf, "<!--applet", 10))
return -ENOEXEC;
bprm->dont_iput=1;
/*
- * OK, we've set the interpreter name
- * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
- * (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET)
- * (3) filename of html file (replace argv[0])
+ * Set args: [0] the name of the appletviewer
+ * [1] filename of html file
*
* This is done in reverse order, because of how the
* user environment and arguments are stored.
bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
bprm->argc++;
- strcpy (bprm->buf, binfmt_java_appletviewer);
- cp = bprm->buf;
- bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
- bprm->argc++;
-
- strcpy (bprm->buf, _PATH_SH);
- interp = bprm->buf;
- if ((i_name = strrchr (bprm->buf, '/')) != NULL)
- i_name++;
- else
- i_name = bprm->buf;
+ i_name = binfmt_java_appletviewer;
bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
bprm->argc++;
+
if (!bprm->p)
return -E2BIG;
/*
* OK, now restart the process with the interpreter's inode.
- * Note that we use open_namei() as the name is now in kernel
- * space, and we don't need to copy it.
*/
- retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+ bprm->filename = binfmt_java_appletviewer;
+ retval = open_namei(binfmt_java_appletviewer, 0, 0, &bprm->inode, NULL);
if (retval)
return retval;
bprm->dont_iput=0;
return search_binary_handler(bprm,regs);
}
-static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int load_java(struct linux_binprm *bprm,struct pt_regs *regs)
{
int retval;
MOD_INC_USE_COUNT;
- retval = do_load_script(bprm,regs);
+ retval = do_load_java(bprm,regs);
MOD_DEC_USE_COUNT;
return retval;
}
-struct linux_binfmt java_format = {
+static struct linux_binfmt java_format = {
#ifndef MODULE
- NULL, 0, load_script, NULL, NULL
+ NULL, 0, load_java, NULL, NULL
#else
- NULL, &mod_use_count_, load_script, NULL, NULL
+ NULL, &mod_use_count_, load_java, NULL, NULL
#endif
};
return retval;
}
-struct linux_binfmt applet_format = {
+static struct linux_binfmt applet_format = {
#ifndef MODULE
NULL, 0, load_applet, NULL, NULL
#else
};
int init_java_binfmt(void) {
- printk(KERN_INFO "JAVA Binary support v1.01 for Linux 1.3.98 (C)1996 Brian A. Lantz\n");
register_binfmt(&java_format);
return register_binfmt(&applet_format);
}
}
void cleanup_module( void) {
- printk(KERN_INFO "Removing JAVA Binary support...\n");
unregister_binfmt(&java_format);
unregister_binfmt(&applet_format);
}
static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
{
- char *cp, *interp, *i_name, *i_arg;
+ char *cp, *i_name, *i_arg;
+ char interp[128];
int retval;
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
return -ENOEXEC;
break;
}
for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
- if (!cp || *cp == '\0')
+ if (cp == '\0')
return -ENOEXEC; /* No interpreter name found */
- interp = i_name = cp;
+ strcpy (interp, cp);
+ i_name = cp;
i_arg = 0;
for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
if (*cp == '/')
return -E2BIG;
/*
* OK, now restart the process with the interpreter's inode.
- * Note that we use open_namei() as the name is now in kernel
- * space, and we don't need to copy it.
*/
+ bprm->filename = interp;
retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
if (retval)
return retval;
return retval;
bprm.filename = filename;
bprm.sh_bang = 0;
+ bprm.java = 0;
bprm.loader = 0;
bprm.exec = 0;
bprm.dont_iput = 0;
*/
static int *root_nfs_header(int proc, int program, int version)
{
- int groups[] = { 0, NOGROUP };
+ gid_t groups[] = { 0 };
if (rpc_packet == NULL) {
if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
return NULL;
}
}
- return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
+ return rpc_header(rpc_packet, proc, program, version, 0, 0, 1, groups);
}
*/
int *rpc_header(int *p, int procedure, int program, int version,
- int uid, int gid, int *groups)
+ int uid, int gid,
+ int ngroup, gid_t *groups)
{
- int *p1, *p2;
- int i;
+ int *p1;
static int xid = 0;
unsigned char *sys = (unsigned char *) system_utsname.nodename;
p = xdr_encode_string(p, (char *) sys);
*p++ = htonl(uid);
*p++ = htonl(gid);
- p2 = p++;
- for (i = 0; i < 16 && i < NGROUPS && groups[i] != NOGROUP; i++)
- *p++ = htonl(groups[i]);
- *p2 = htonl(i);
+ if (ngroup > 16)
+ ngroup = 16;
+ *p++ = htonl(ngroup);
+ while (ngroup) {
+ *p++ = htonl(*groups);
+ groups++;
+ ngroup--;
+ }
*p1 = htonl((p - (p1 + 1)) << 2);
*p++ = htonl(RPC_AUTH_NULL);
*p++ = htonl(0);
{
return rpc_header(p, procedure, NFS_PROGRAM, NFS_VERSION,
(ruid ? current->uid : current->fsuid),
- current->egid, current->groups);
+ current->egid, current->ngroups, current->groups);
}
" .align 4\n" \
" .long 0b,3b\n" \
".text" \
- : "=r"(res), "=r"(count) \
+ : "=d"(res), "=c"(count) \
: "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \
: "si", "di", "ax", "memory")
--- /dev/null
+
+#ifndef _ATARI_SLM_H
+#define _ATARI_SLM_H
+
+/* Atari SLM laser printer specific ioctls */
+
+#define SLMIOGSTAT 0xa100
+#define SLMIOGPSIZE 0xa101
+#define SLMIOGMFEED 0xa102
+
+#define SLMIORESET 0xa140
+
+#define SLMIOSPSIZE 0xa181
+#define SLMIOSMFEED 0xa182
+
+/* Status returning structure (SLMIOGSTAT) */
+struct SLM_status {
+ int stat; /* numeric status code */
+ char str[40]; /* status string */
+};
+
+/* Paper size structure (SLMIO[GS]PSIZE) */
+struct SLM_paper_size {
+ int width;
+ int height;
+};
+
+#endif /* _ATARI_SLM_H */
#define __BIG_ENDIAN_BITFIELD
#endif
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/types.h>
+
+/*
+ * In-kernel byte order macros to handle stuff like
+ * byte-order-dependent filesystems etc.
+ */
+
+#define le16_to_cpu(__val) __swab16(__val)
+#define le32_to_cpu(__val) __swab32(__val)
+#define cpu_to_le32(__val) __swab32(__val)
+#define cpu_to_le16(__val) __swab16(__val)
+
+extern __inline__ __u16 __swab16 (__u16 val)
+{
+ return (val << 8) | (val >> 8);
+}
+
+extern __inline__ __u32 __swab32 (__u32 val)
+{
+ __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
+ return val;
+}
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+
+#endif
+
#undef ntohl
#undef ntohs
#undef htonl
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
+#define __constant_htonl(x) (x)
+#define __constant_htons(x) (x)
+#define __constant_ntohl(x) (x)
+#define __constant_ntohs(x) (x)
+
#ifdef __OPTIMIZE__
#define ntohl(x) __ntohl(x)
#define ntohs(x) __ntohs(x)
*/
#include <asm/ptrace.h>
+#include <asm/user.h>
typedef unsigned long elf_greg_t;
-#define ELF_NGREG 20 /* d1-d7/a0-a6/d0/usp/orig_d0/sr/pc/fmtvec */
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_m68kfp_struct elf_fpregset_t;
pr_reg[8] = regs->a1; \
pr_reg[14] = regs->d0; \
pr_reg[15] = rdusp(); \
- pr_reg[16] = 0; /* orig_d0 */ \
+ pr_reg[16] = regs->orig_d0; \
pr_reg[17] = regs->sr; \
pr_reg[18] = regs->pc; \
+ pr_reg[19] = (regs->format << 12) | regs->vector; \
{ \
struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
pr_reg[5] = sw->d6; \
#ifndef _M68K_IO_H
#define _M68K_IO_H
-static inline unsigned char get_user_byte_io(const char * addr)
-{
- register unsigned char _v;
+#ifdef __KERNEL__
- __asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
- return _v;
-}
-#define inb_p(addr) get_user_byte_io((char *)(addr))
-#define inb(addr) get_user_byte_io((char *)(addr))
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
-static inline void put_user_byte_io(char val,char *addr)
-{
- __asm__ __volatile__ ("moveb %0,%1"
- : /* no outputs */
- :"idm" (val),"m" (*addr)
- : "memory");
-}
-#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
-#define outb(x,addr) put_user_byte_io((x),(char *)(addr))
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c) memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+
+#define inb_p(addr) readb(addr)
+#define inb(addr) readb(addr)
+
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outb_p(x,addr) outb(x,addr)
/*
* Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
- * make the kernel segment mapped at 0, we need to do translation
- * on the i386 as well)
*/
-extern unsigned long mm_vtop(unsigned long addr);
-extern unsigned long mm_ptov(unsigned long addr);
+extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
+extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
extern inline unsigned long virt_to_phys(volatile void * address)
{
- return (unsigned long) mm_vtop((unsigned long)address);
+ return mm_vtop((unsigned long)address);
}
extern inline void * phys_to_virt(unsigned long address)
}
/*
- * IO bus memory addresses are also 1:1 with the physical address
+ * IO bus memory addresses are 1:1 with the physical address
*/
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
+#endif /* __KERNEL__ */
#endif /* _M68K_IO_H */
--- /dev/null
+#ifndef __m68k_IPC_H__
+#define __m68k_IPC_H__
+
+/*
+ * These are used to wrap system calls on m68k.
+ *
+ * See arch/m68k/kernel/sys_m68k.c for ugly details..
+ */
+struct ipc_kludge {
+ struct msgbuf *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
+#endif
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
+#define MAP_NORESERVE 0x4000 /* don't check for reservations */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
#define STRICT_MM_TYPECHECKS
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
#endif
-/* This is the cache mode to be used for pages containing page descriptors for
- * processors >= '040. It is in pte_mknocache(), and the variable is defined
- * and initialized in head.S */
-extern int m68k_pgtable_cachemode;
-
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* This handles the memory map.. */
#define PAGE_OFFSET 0
-#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED (1<<15)
+#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
#endif /* __KERNEL__ */
* area for the same reason. ;)
*/
#define VMALLOC_OFFSET (8*1024*1024)
-#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#endif /* __ASSEMBLY__ */
#ifndef __ASSEMBLY__
+/* This is the cache mode to be used for pages containing page descriptors for
+ * processors >= '040. It is in pte_mknocache(), and the variable is defined
+ * and initialized in head.S */
+extern int m68k_pgtable_cachemode;
+
+#if defined(CONFIG_M68040_OR_M68060_ONLY)
+#define mm_cachebits _PAGE_CACHE040
+#elif defined(CONFIG_M68020_OR_M68030_ONLY)
+#define mm_cachebits 0
+#else
extern unsigned long mm_cachebits;
+#endif
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
#define PAGE_PTR(address) \
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-extern unsigned long high_memory;
-
/* For virtual address to physical address conversion */
extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = VTOP(page) | pgprot_val(pgprot); return pte; }
+#define mk_pte(page, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(page) + pgprot_val(pgprot); __pte; })
+#define mk_pte_phys(physpage, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(physpage) + pgprot_val(pgprot); __pte; })
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
ptep = (pte_t *) VTOP(ptep);
for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
- pmdp->pmd[i] = _PAGE_TABLE | (unsigned long)ptep;
+ pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep;
}
/* early termination version of the above */
ptep = (pte_t *) VTOP(ptep);
for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
- pmdp->pmd[i] = _PAGE_PRESENT | (unsigned long)ptep;
+ pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep;
}
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | VTOP(pmdp); }
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | VTOP(pmdp); }
extern inline unsigned long pte_page(pte_t pte)
{ return PTOV(pte_val(pte) & PAGE_MASK); }
extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
#define pmd_none(pmd) pmd_none2(&(pmd))
-extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE || pmd_page(*pmd) > high_memory; }
+extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
#define pmd_bad(pmd) pmd_bad2(&(pmd))
extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; }
#define pmd_present(pmd) pmd_present2(&(pmd))
}
extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
+extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; }
extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
/* to set the page-dir */
extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
{
- tsk->tss.pagedir_v = (unsigned long *)pgdir;
- tsk->tss.pagedir_p = VTOP(pgdir);
- tsk->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
- tsk->tss.crp[1] = tsk->tss.pagedir_p;
+ tsk->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+ tsk->tss.crp[1] = VTOP(pgdir);
if (tsk == current) {
if (CPU_IS_040_OR_060)
__asm__ __volatile__ ("movel %0@,%/d0\n\t"
{
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
if (pmd_none(*pmd)) {
- pte_t * page = (pte_t *)get_free_page(GFP_KERNEL);
+ pte_t * page = (pte_t *)__get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
+ memset((void *) page, 0, PAGE_SIZE);
nocache_page((unsigned long)page);
pmd_set(pmd,page);
return page + address;
typedef unsigned short __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
typedef unsigned int __kernel_size_t;
/*
* Bus types
*/
-#define EISA_bus__is_a_macro 1
#define EISA_bus 0
-#define MCA_bus__is_a_macro 1
#define MCA_bus 0
-/*
- * The m68k has no problems with write protection
- */
-#define wp_works_ok__is_a_macro 1
-#define wp_works_ok 1
-
/* MAX floating point unit state size (FSAVE/FRESTORE) */
#define FPSTATESIZE (216/sizeof(unsigned char))
unsigned long usp; /* user stack pointer */
unsigned short sr; /* saved status register */
unsigned short fs; /* saved fs (sfc, dfc) */
- unsigned long *pagedir_v; /* root page table virtual addr */
- unsigned long pagedir_p; /* root page table physaddr */
unsigned long crp[2]; /* cpu root pointer */
unsigned long esp0; /* points to SR of stack frame */
unsigned long fp[8*3];
#define INIT_TSS { \
sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \
PS_S, KERNEL_DS, \
- NULL, 0, {0, 0}, 0 \
+ {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
}
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
#ifndef __ASSEMBLY__
-/*
- * Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- */
-#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
-#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
-
-/*
- * This is a silly but good way to make sure that
- * the __put_user function is indeed always optimized,
- * and that we use the correct sizes..
- */
-extern int bad_user_access_length(void);
-
-#define __ptr(x) ((unsigned long *)(x))
-
-static inline void __put_user(unsigned long x, void * y, int size)
-{
- switch (size) {
- case 1:
- __asm__ ("movesb %0,%1"
- : /* no outputs */
- :"r" (x),"m" (*__ptr(y)) : "memory");
- break;
- case 2:
- __asm__ ("movesw %0,%1"
- : /* no outputs */
- :"r" (x),"m" (*__ptr(y)) : "memory");
- break;
- case 4:
- __asm__ ("movesl %0,%1"
- : /* no outputs */
- :"r" (x),"m" (*__ptr(y)) : "memory");
- break;
- default:
- bad_user_access_length();
- }
-}
-
-static inline unsigned long __get_user(const void * y, int size)
-{
- unsigned long result;
-
- switch (size) {
- case 1:
- __asm__ ("movesb %1,%0"
- :"=r" (result)
- :"m" (*__ptr(y)));
- return (unsigned char) result;
- case 2:
- __asm__ ("movesw %1,%0"
- :"=r" (result)
- :"m" (*__ptr(y)));
- return (unsigned short) result;
- case 4:
- __asm__ ("movesl %1,%0"
- :"=r" (result)
- :"m" (*__ptr(y)));
- return result;
- default:
- return bad_user_access_length();
- }
-}
-#undef __ptr
-
-/*
- * These are deprecated..
- *
- * Use "put_user()" and "get_user()" with the proper pointer types instead.
- */
-
-#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
-#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
-#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
-
-#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
-#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
-#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
-
-#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
-
-static inline unsigned char get_user_byte(const char * addr)
-{
- return __get_user(addr,1);
-}
-
-static inline unsigned short get_user_word(const short *addr)
-{
- return __get_user(addr,2);
-}
-
-static inline unsigned long get_user_long(const int *addr)
-{
- return __get_user(addr,4);
-}
-
-static inline void put_user_byte(char val,char *addr)
-{
- __put_user(val, addr, 1);
-}
-
-static inline void put_user_word(short val,short * addr)
-{
- __put_user(val, addr, 2);
-}
-
-static inline void put_user_long(unsigned long val,int * addr)
-{
- __put_user(val, addr, 4);
-}
-
-#endif
-
-static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
- unsigned long tmp;
- if (n == 0) return;
- tmp = n;
- n >>= 2;
- if (n != 0)
- __asm__ __volatile__ ("1:\t"
- "movel %1@+,%/d0\n\t"
- "movesl %/d0,%2@+\n\t"
- "dbra %0,1b\n\t"
- "clrw %0\n\t"
- "subql #1,%0\n\t"
- "bccs 1b\n\t"
- : "=d" (n), "=a" (from), "=a" (to)
- : "0" (n-1), "1" (from), "2" (to)
- : "d0", "memory");
- if (tmp & 2)
- __asm__ __volatile__ ("movew %0@+,%/d0\n\t"
- "movesw %/d0,%1@+\n\t"
- : "=a" (from), "=a" (to)
- : "0" (from), "1" (to)
- : "d0", "memory");
- if (tmp & 1)
- __asm__ __volatile__ ("moveb %0@,%/d0\n\t"
- "movesb %/d0,%1@\n\t"
- : /* no outputs */
- : "a" (from), "a" (to)
- : "d0", "memory");
-}
-
-static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
- switch (n) {
- case 0:
- return;
- case 1:
- __put_user(*(const char *) from, (char *) to, 1);
- return;
- case 2:
- __put_user(*(const short *) from, (short *) to, 2);
- return;
- case 3:
- __put_user(*(const short *) from, (short *) to, 2);
- __put_user(*(2+(const char *) from), 2+(char *) to, 1);
- return;
- case 4:
- __put_user(*(const int *) from, (int *) to, 4);
- return;
- case 8:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- return;
- case 12:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- __put_user(*(2+(const int *) from), 2+(int *) to, 4);
- return;
- case 16:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- __put_user(*(2+(const int *) from), 2+(int *) to, 4);
- __put_user(*(3+(const int *) from), 3+(int *) to, 4);
- return;
- }
-#define COMMON(x) \
-__asm__ __volatile__ ("1:\n\t" \
- "movel %1@+,%/d0\n\t" \
- "movesl %/d0,%2@+\n\t" \
- "dbra %0,1b\n\t" \
- "clrw %0\n\t" \
- "subql #1,%0\n\t" \
- "bccs 1b\n\t" \
- x \
- : "=d" (n), "=a" (from), "=a" (to) \
- : "1" (from), "2" (to), "0" (n/4-1) \
- : "d0", "memory");
-
- switch (n % 4) {
- case 0:
- COMMON("");
- return;
- case 1:
- COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
- return;
- case 2:
- COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
- return;
- case 3:
- COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
- "moveb %1@+,%/d0; movesb %/d0,%2@+");
- return;
- }
-#undef COMMON
-}
-
-static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
- unsigned long tmp;
- if (n == 0) return;
- tmp = n;
- n >>= 2;
- if (n != 0)
- __asm__ __volatile__ ("1:\t"
- "movesl %1@+,%/d0\n\t"
- "movel %/d0,%2@+\n\t"
- "dbra %0,1b\n\t"
- "clrw %0\n\t"
- "subql #1,%0\n\t"
- "bccs 1b\n\t"
- : "=d" (n), "=a" (from), "=a" (to)
- : "0" (n-1), "1" (from), "2" (to)
- : "d0", "memory");
- if (tmp & 2)
- __asm__ __volatile__ ("movesw %0@+,%/d0\n\t"
- "movew %/d0,%1@+\n\t"
- : "=a" (from), "=a" (to)
- : "0" (from), "1" (to)
- : "d0", "memory");
- if (tmp & 1)
- __asm__ __volatile__ ("movesb %0@,%/d0\n\t"
- "moveb %/d0,%1@\n\t"
- : /* no outputs */
- : "a" (from), "a" (to)
- : "d0", "memory");
-}
-
-static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
- switch (n) {
- case 0:
- return;
- case 1:
- *(char *)to = __get_user((const char *) from, 1);
- return;
- case 2:
- *(short *)to = __get_user((const short *) from, 2);
- return;
- case 3:
- *(short *) to = __get_user((const short *) from, 2);
- *((char *) to + 2) = __get_user(2+(const char *) from, 1);
- return;
- case 4:
- *(int *) to = __get_user((const int *) from, 4);
- return;
- case 8:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- return;
- case 12:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- *(2+(int *) to) = __get_user(2+(const int *) from, 4);
- return;
- case 16:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- *(2+(int *) to) = __get_user(2+(const int *) from, 4);
- *(3+(int *) to) = __get_user(3+(const int *) from, 4);
- return;
- }
-#define COMMON(x) \
-__asm__ __volatile__ ("1:\n\t" \
- "movesl %1@+,%/d0\n\t" \
- "movel %/d0,%2@+\n\t" \
- "dbra %0,1b\n\t" \
- "clrw %0\n\t" \
- "subql #1,%0\n\t" \
- "bccs 1b\n\t" \
- x \
- : "=d" (n), "=a" (from), "=a" (to) \
- : "1" (from), "2" (to), "0" (n/4-1) \
- : "d0", "memory");
-
- switch (n % 4) {
- case 0:
- COMMON("");
- return;
- case 1:
- COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
- return;
- case 2:
- COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
- return;
- case 3:
- COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
- "movesb %1@+,%/d0; moveb %/d0,%2@+");
- return;
- }
-#undef COMMON
-}
-
-#define memcpy_fromfs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_fromfs((to),(from),(n)) : \
- __generic_memcpy_fromfs((to),(from),(n)))
-
-#define memcpy_tofs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_tofs((to),(from),(n)) : \
- __generic_memcpy_tofs((to),(from),(n)))
-
/*
* Get/set the SFC/DFC registers for MOVES instructions
*/
#define MUTEX ((struct semaphore) { 1, 0, NULL })
#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL })
-asmlinkage void down_failed(void /* special register calling convention */);
-asmlinkage void up_wakeup(void /* special register calling convention */);
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
extern void __down(struct semaphore * sem);
extern void __up(struct semaphore * sem);
{
register struct semaphore *sem1 __asm__ ("%a1") = sem;
__asm__ __volatile__(
- "# atomic down operation\n"
- "1:\n\t"
- "lea %%pc@(1b),%%a0\n\t"
+ "| atomic down operation\n\t"
+ "lea %%pc@(1f),%%a0\n\t"
"subql #1,%0\n\t"
- "jmi " SYMBOL_NAME_STR(down_failed)
+ "jmi " SYMBOL_NAME_STR(__down_failed) "\n"
+ "1:"
: /* no outputs */
: "m" (sem->count), "a" (sem1)
- : "%a0", "%d0", "%d1", "memory");
+ : "%a0", "memory");
}
/*
{
register struct semaphore *sem1 __asm__ ("%a1") = sem;
__asm__ __volatile__(
- "# atomic up operation\n\t"
+ "| atomic up operation\n\t"
"lea %%pc@(1f),%%a0\n\t"
"addql #1,%0\n\t"
- "jls " SYMBOL_NAME_STR(up_wakeup) "\n"
+ "jle " SYMBOL_NAME_STR(__up_wakeup) "\n"
"1:"
: /* no outputs */
: "m" (sem->count), "a" (sem1)
- : "%a0", "%d0", "%d1", "memory");
+ : "%a0", "memory");
}
#endif
-#ifndef _ASMm68k_SIGCONTEXT_H
-#define _ASMm68k_SIGCONTEXT_H
+#ifndef _ASM_M68k_SIGCONTEXT_H
+#define _ASM_M68k_SIGCONTEXT_H
-struct sigcontext_struct {
+struct sigcontext {
unsigned long sc_mask; /* old sigmask */
unsigned long sc_usp; /* old user stack pointer */
unsigned long sc_d0;
#ifndef _M68K_STAT_H
#define _M68K_STAT_H
-struct old_stat {
+struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned long st_ctime;
};
-struct new_stat {
+struct stat {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
--- /dev/null
+#ifndef __M68K_UACCESS_H
+#define __M68K_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/* We let the MMU do all checking */
+#define access_ok(type,addr,size) 1
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+ return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+ unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines. They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr) \
+({ \
+ int __pu_err; \
+ typeof(*(ptr)) __pu_val = (x); \
+ switch (sizeof (*(ptr))) { \
+ case 1: \
+ __put_user_asm(__pu_err, __pu_val, ptr, b); \
+ break; \
+ case 2: \
+ __put_user_asm(__pu_err, __pu_val, ptr, w); \
+ break; \
+ case 4: \
+ __put_user_asm(__pu_err, __pu_val, ptr, l); \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+#define __put_user_asm(err,x,ptr,bwl) \
+__asm__ __volatile__ \
+ ("21:moves" #bwl " %2,%1\n" \
+ "1:\n" \
+ ".section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "2: movel %3,%0\n" \
+ " jra 1b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 21b,2b\n" \
+ " .long 1b,2b\n" \
+ ".text" \
+ : "=d"(err) \
+ : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
+
+#define get_user(x, ptr) \
+({ \
+ int __gu_err; \
+ typeof(*(ptr)) __gu_val; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
+ break; \
+ case 2: \
+ __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
+ break; \
+ case 4: \
+ __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
+ break; \
+ default: \
+ __gu_val = 0; \
+ __gu_err = __get_user_bad(); \
+ break; \
+ } \
+ (x) = __gu_val; \
+ __gu_err; \
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define __get_user_asm(err,x,ptr,bwl,reg) \
+__asm__ __volatile__ \
+ ("1: moves" #bwl " %2,%1\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "3: movel %3,%0\n" \
+ " sub" #bwl " %1,%1\n" \
+ " jra 2b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=d"(err), reg(x) \
+ : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+ unsigned long tmp;
+ __asm__ __volatile__
+ (" tstl %2\n"
+ " jeq 2f\n"
+ "1: movesl (%1)+,%3\n"
+ " movel %3,(%0)+\n"
+ " subql #1,%2\n"
+ " jne 1b\n"
+ "2: movel %4,%2\n"
+ " bclr #1,%2\n"
+ " jeq 4f\n"
+ "3: movesw (%1)+,%3\n"
+ " movew %3,(%0)+\n"
+ "4: bclr #0,%2\n"
+ " jeq 6f\n"
+ "5: movesb (%1)+,%3\n"
+ " moveb %3,(%0)+\n"
+ "6:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "7: lsll #2,%2\n"
+ " addl %4,%2\n"
+ " jra 6b\n"
+ "8: addql #2,%2\n"
+ " jra 6b\n"
+ "9: addql #1,%2\n"
+ " jra 6b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,7b\n"
+ " .long 3b,8b\n"
+ " .long 5b,9b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+ : "r"(n & 3), "0"(to), "1"(from), "2"(n/4)
+ : "d0", "memory");
+ return n;
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+ unsigned long tmp;
+ __asm__ __volatile__
+ (" tstl %2\n"
+ " jeq 3f\n"
+ "1: movel (%1)+,%3\n"
+ "22:movesl %3,(%0)+\n"
+ "2: subql #1,%2\n"
+ " jne 1b\n"
+ "3: movel %4,%2\n"
+ " bclr #1,%2\n"
+ " jeq 4f\n"
+ " movew (%1)+,%3\n"
+ "24:movesw %3,(%0)+\n"
+ "4: bclr #0,%2\n"
+ " jeq 5f\n"
+ " moveb (%1)+,%3\n"
+ "25:movesb %3,(%0)+\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: lsll #2,%2\n"
+ " addl %4,%2\n"
+ " jra 5b\n"
+ "7: addql #2,%2\n"
+ " jra 5b\n"
+ "8: addql #1,%2\n"
+ " jra 5b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 22b,6b\n"
+ " .long 2b,6b\n"
+ " .long 24b,7b\n"
+ " .long 4b,7b\n"
+ " .long 25b,8b\n"
+ " .long 5b,8b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+ : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4));
+ return n;
+}
+
+#define __copy_from_user_big(to, from, n, fixup, copy) \
+ __asm__ __volatile__ \
+ ("10: movesl (%1)+,%%d0\n" \
+ " movel %%d0,(%0)+\n" \
+ " subql #1,%2\n" \
+ " jne 10b\n" \
+ ".section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "11: lsll #2,%2\n" \
+ fixup "\n" \
+ " jra 12f\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 10b,11b\n" \
+ ".text\n" \
+ copy "\n" \
+ ".text\n" \
+ "12:" \
+ : "=a"(to), "=a"(from), "=d"(n) \
+ : "0"(to), "1"(from), "2"(n/4) \
+ : "d0", "memory")
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void *from, unsigned long n)
+{
+ switch (n) {
+ case 0:
+ break;
+ case 1:
+ __asm__ __volatile__
+ ("1: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #1,%2\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("1: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #2,%2\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 3:
+ __asm__ __volatile__
+ ("1: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ "2: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ "3:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: addql #2,%2\n"
+ "5: addql #1,%2\n"
+ " jra 3b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 2b,5b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 4:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #4,%2\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 8:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: addql #4,%2\n"
+ "5: addql #4,%2\n"
+ " jra 3b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 2b,5b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 12:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "4:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "5: addql #4,%2\n"
+ "6: addql #4,%2\n"
+ "7: addql #4,%2\n"
+ " jra 4b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,5b\n"
+ " .long 2b,6b\n"
+ " .long 3b,7b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 16:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "4: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "5:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: addql #4,%2\n"
+ "7: addql #4,%2\n"
+ "8: addql #4,%2\n"
+ "9: addql #4,%2\n"
+ " jra 5b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,6b\n"
+ " .long 2b,7b\n"
+ " .long 3b,8b\n"
+ " .long 4b,9b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ default:
+ switch (n & 3) {
+ case 0:
+ __copy_from_user_big(to, from, n, "", "");
+ break;
+ case 1:
+ __copy_from_user_big(to, from, n,
+ /* fixup */
+ "1: addql #1,%2",
+ /* copy */
+ "2: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ ".section __ex_table,\"a\"\n"
+ " .long 2b,1b");
+ break;
+ case 2:
+ __copy_from_user_big(to, from, n,
+ /* fixup */
+ "1: addql #2,%2",
+ /* copy */
+ "2: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ ".section __ex_table,\"a\"\n"
+ " .long 2b,1b");
+ break;
+ case 3:
+ __copy_from_user_big(to, from, n,
+ /* fixup */
+ "1: addql #2,%2"
+ "2: addql #1,%2",
+ /* copy */
+ "3: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ "4: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ ".section __ex_table,\"a\"\n"
+ " .long 3b,1b\n"
+ " .long 4b,2b");
+ break;
+ }
+ break;
+ }
+ return n;
+}
+
+#define __copy_to_user_big(to, from, n, fixup, copy) \
+ __asm__ __volatile__ \
+ ("10: movel (%1)+,%%d0\n" \
+ "31: movesl %%d0,(%0)+\n" \
+ "11: subql #1,%2\n" \
+ " jne 10b\n" \
+ ".section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "12: lsll #2,%2\n" \
+ fixup "\n" \
+ " jra 13f\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 31b,12b\n" \
+ " .long 11b,12b\n" \
+ ".text\n" \
+ copy "\n" \
+ ".text\n" \
+ "13:" \
+ : "=a"(to), "=a"(from), "=d"(n) \
+ : "0"(to), "1"(from), "2"(n/4) \
+ : "d0")
+
+static inline unsigned long
+__constant_copy_to_user(void *to, const void *from, unsigned long n)
+{
+ switch (n) {
+ case 0:
+ break;
+ case 1:
+ __asm__ __volatile__
+ (" moveb (%1)+,%%d0\n"
+ "21:movesb %%d0,(%0)+\n"
+ "1:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "2: addql #1,%2\n"
+ " jra 1b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n "
+ " .long 21b,2b\n"
+ " .long 1b,2b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 2:
+ __asm__ __volatile__
+ (" movew (%1)+,%%d0\n"
+ "21:movesw %%d0,(%0)+\n"
+ "1:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "2: addql #2,%2\n"
+ " jra 1b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,2b\n"
+ " .long 1b,2b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 3:
+ __asm__ __volatile__
+ (" movew (%1)+,%%d0\n"
+ "21:movesw %%d0,(%0)+\n"
+ "1: moveb (%1)+,%%d0\n"
+ "22:movesb %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #2,%2\n"
+ "4: addql #1,%2\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,3b\n"
+ " .long 1b,3b\n"
+ " .long 22b,4b\n"
+ " .long 2b,4b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 4:
+ __asm__ __volatile__
+ (" movel (%1)+,%%d0\n"
+ "21:movesl %%d0,(%0)+\n"
+ "1:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "2: addql #4,%2\n"
+ " jra 1b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,2b\n"
+ " .long 1b,2b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 8:
+ __asm__ __volatile__
+ (" movel (%1)+,%%d0\n"
+ "21:movesl %%d0,(%0)+\n"
+ "1: movel (%1)+,%%d0\n"
+ "22:movesl %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #4,%2\n"
+ "4: addql #4,%2\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,3b\n"
+ " .long 1b,3b\n"
+ " .long 22b,4b\n"
+ " .long 2b,4b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 12:
+ __asm__ __volatile__
+ (" movel (%1)+,%%d0\n"
+ "21:movesl %%d0,(%0)+\n"
+ "1: movel (%1)+,%%d0\n"
+ "22:movesl %%d0,(%0)+\n"
+ "2: movel (%1)+,%%d0\n"
+ "23:movesl %%d0,(%0)+\n"
+ "3:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: addql #4,%2\n"
+ "5: addql #4,%2\n"
+ "6: addql #4,%2\n"
+ " jra 3b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,4b\n"
+ " .long 1b,4b\n"
+ " .long 22b,5b\n"
+ " .long 2b,5b\n"
+ " .long 23b,6b\n"
+ " .long 3b,6b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 16:
+ __asm__ __volatile__
+ (" movel (%1)+,%%d0\n"
+ "21:movesl %%d0,(%0)+\n"
+ "1: movel (%1)+,%%d0\n"
+ "22:movesl %%d0,(%0)+\n"
+ "2: movel (%1)+,%%d0\n"
+ "23:movesl %%d0,(%0)+\n"
+ "3: movel (%1)+,%%d0\n"
+ "24:movesl %%d0,(%0)+\n"
+ "4:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "5: addql #4,%2\n"
+ "6: addql #4,%2\n"
+ "7: addql #4,%2\n"
+ "8: addql #4,%2\n"
+ " jra 4b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 21b,5b\n"
+ " .long 1b,5b\n"
+ " .long 22b,6b\n"
+ " .long 2b,6b\n"
+ " .long 23b,7b\n"
+ " .long 3b,7b\n"
+ " .long 24b,8b\n"
+ " .long 4b,8b\n"
+ ".text"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ default:
+ switch (n & 3) {
+ case 0:
+ __copy_to_user_big(to, from, n, "", "");
+ break;
+ case 1:
+ __copy_to_user_big(to, from, n,
+ /* fixup */
+ "1: addql #1,%2",
+ /* copy */
+ " moveb (%1)+,%%d0\n"
+ "22:movesb %%d0,(%0)+\n"
+ "2:"
+ ".section __ex_table,\"a\"\n"
+ " .long 22b,1b\n"
+ " .long 2b,1b");
+ break;
+ case 2:
+ __copy_to_user_big(to, from, n,
+ /* fixup */
+ "1: addql #2,%2",
+ /* copy */
+ " movew (%1)+,%%d0\n"
+ "22:movesw %%d0,(%0)+\n"
+ "2:"
+ ".section __ex_table,\"a\"\n"
+ " .long 22b,1b\n"
+ " .long 2b,1b");
+ break;
+ case 3:
+ __copy_to_user_big(to, from, n,
+ /* fixup */
+ "1: addql #2,%2"
+ "2: addql #1,%2",
+ /* copy */
+ " movew (%1)+,%%d0\n"
+ "23:movesw %%d0,(%0)+\n"
+ "3: moveb (%1)+,%%d0\n"
+ "24:movesb %%d0,(%0)+\n"
+ "4:"
+ ".section __ex_table,\"a\"\n"
+ " .long 23b,1b\n"
+ " .long 3b,1b\n"
+ " .long 24b,2b\n"
+ " .long 4b,2b");
+ break;
+ }
+ break;
+ }
+ return n;
+}
+
+#define copy_from_user(to, from, n) \
+(__builtin_constant_p(n) ? \
+ __constant_copy_from_user(to, from, n) : \
+ __generic_copy_from_user(to, from, n))
+
+#define copy_to_user(to, from, n) \
+(__builtin_constant_p(n) ? \
+ __constant_copy_to_user(to, from, n) : \
+ __generic_copy_to_user(to, from, n))
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+ long res;
+ if (count == 0) return count;
+ __asm__ __volatile__
+ ("1: movesb (%2)+,%%d0\n"
+ "12:moveb %%d0,(%1)+\n"
+ " jeq 2f\n"
+ " subql #1,%3\n"
+ " jne 1b\n"
+ "2: subl %3,%0\n"
+ "3:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: movel %4,%0\n"
+ " jra 3b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 12b,4b\n"
+ ".text"
+ : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
+ : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
+ : "d0", "memory");
+ return res;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+static inline long strlen_user(const char * src)
+{
+ long res = (long) src;
+ __asm__ __volatile__
+ ("1: movesb (%1)+,%%d0\n"
+ "12:tstb %%d0\n"
+ " jne 1b\n"
+ " subl %1,%0\n"
+ " negl %0\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: moveq %2,%0\n"
+ " jra 2b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ " .long 12b,3b\n"
+ ".text"
+ : "=d"(res), "=a"(src)
+ : "i"(0), "0"(res), "1"(src)
+ : "d0", "memory");
+ return res;
+}
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+ __asm__ __volatile__
+ (" tstl %1\n"
+ " jeq 3f\n"
+ "1: movesl %3,(%0)+\n"
+ "2: subql #1,%1\n"
+ " jne 1b\n"
+ "3: movel %2,%1\n"
+ " bclr #1,%1\n"
+ " jeq 4f\n"
+ "24:movesw %3,(%0)+\n"
+ "4: bclr #0,%1\n"
+ " jeq 5f\n"
+ "25:movesb %3,(%0)+\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: lsll #2,%1\n"
+ " addl %2,%1\n"
+ " jra 5b\n"
+ "7: addql #2,%1\n"
+ " jra 5b\n"
+ "8: addql #1,%1\n"
+ " jra 5b\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,6b\n"
+ " .long 2b,6b\n"
+ " .long 24b,7b\n"
+ " .long 4b,7b\n"
+ " .long 25b,8b\n"
+ " .long 5b,8b\n"
+ ".text"
+ : "=a"(to), "=d"(n)
+ : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
+ return n;
+}
+
+#endif /* _M68K_UACCESS_H */
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
-#ifdef __ELF__
+/* user-visible error numbers are in the range -1 - -122: see
+ <asm-m68k/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+ if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+ errno = -(res); \
+ res = -1; \
+ } \
+ return (type) (res); \
+} while (0)
#define _syscall0(type,name) \
type name(void) \
register long __res __asm__ ("%d0") = __NR_##name; \
__asm__ __volatile__ ("trap #0" \
: "=g" (__res) \
- : "0" (__NR_##name) \
+ : "0" (__res) \
: "%d0"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+__syscall_return(type,__res); \
}
#define _syscall1(type,name,atype,a) \
type name(atype a) \
{ \
register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)) \
- : "%d0", "%d1"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+__asm__ __volatile__ ("trap #0" \
+ : "=d" (__res) \
+ : "0" (__res), "d" (__a) \
+ : "%d0"); \
+__syscall_return(type,__res); \
}
#define _syscall2(type,name,atype,a,btype,b) \
type name(atype a,btype b) \
{ \
register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
- "movel %3,%/d2\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)) \
- : "%d0", "%d1", "%d2"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+__asm__ __volatile__ ("trap #0" \
+ : "=d" (__res) \
+ : "0" (__res), "d" (__a), "d" (__b) \
+ : "%d0"); \
+__syscall_return(type,__res); \
}
#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
type name(atype a,btype b,ctype c) \
{ \
register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
- "movel %3,%/d2\n\t" \
- "movel %4,%/d3\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)) \
- : "%d0", "%d1", "%d2", "%d3"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+__asm__ __volatile__ ("trap #0" \
+ : "=d" (__res) \
+ : "0" (__res), "d" (__a), "d" (__b), \
+ "d" (__c) \
+ : "%d0"); \
+__syscall_return(type,__res); \
}
#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
type name (atype a, btype b, ctype c, dtype d) \
{ \
register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
- "movel %3,%/d2\n\t" \
- "movel %4,%/d3\n\t" \
- "movel %5,%/d4\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)), \
- "g" ((long)(d)) \
- : "%d0", "%d1", "%d2", "%d3", "%d4"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+__asm__ __volatile__ ("trap #0" \
+ : "=d" (__res) \
+ : "0" (__res), "d" (__a), "d" (__b), \
+ "d" (__c), "d" (__d) \
+ : "%d0"); \
+__syscall_return(type,__res); \
}
#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
type name (atype a,btype b,ctype c,dtype d,etype e) \
{ \
register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
- "movel %3,%/d2\n\t" \
- "movel %4,%/d3\n\t" \
- "movel %5,%/d4\n\t" \
- "movel %6,%/d5\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)), \
- "g" ((long)(d)), \
- "g" ((long)(e)) \
- : "%d0", "%d1", "%d2", "%d3", "%d4", "%d5"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#else /* not ELF; a.out */
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+register long __e __asm__ ("%d5") = (long)(e); \
__asm__ __volatile__ ("trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name) \
- : "d0"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall1(type,name,atype,a) \
-type name(atype a) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)) \
- : "d0", "d1"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
- "movel %3,d2\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)) \
- : "d0", "d1", "d2"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name(atype a,btype b,ctype c) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
- "movel %3,d2\n\t" \
- "movel %4,d3\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)) \
- : "d0", "d1", "d2", "d3"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
+ : "=d" (__res) \
+ : "0" (__res), "d" (__a), "d" (__b), \
+ "d" (__c), "d" (__d), "d" (__e) \
+ : "%d0"); \
+__syscall_return(type,__res); \
}
-#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
- "movel %3,d2\n\t" \
- "movel %4,d3\n\t" \
- "movel %5,d4\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)), \
- "g" ((long)(d)) \
- : "d0", "d1", "d2", "d3", "d4"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
- "movel %3,d2\n\t" \
- "movel %4,d3\n\t" \
- "movel %5,d4\n\t" \
- "movel %6,d5\n\t" \
- "trap #0" \
- : "=g" (__res) \
- : "0" (__NR_##name), "g" ((long)(a)), \
- "g" ((long)(b)), \
- "g" ((long)(c)), \
- "g" ((long)(d)), \
- "g" ((long)(e)) \
- : "d0", "d1", "d2", "d3", "d4", "d5"); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#endif /* ELF or otherwise */
-
#ifdef __KERNEL_SYSCALLS__
/*
{
register long retval __asm__ ("d0") = __NR_clone;
register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
- unsigned short fs;
+ unsigned long fs;
fs = get_fs();
set_fs (KERNEL_DS);
__asm__ __volatile__
- ("movel %%sp,%%d2\n\t"
- "trap #0\n\t" /* Linux/m68k system call */
- "cmpl %%sp,%%d2\n\t" /* child or parent */
- "jeq 1f\n\t" /* parent - jump */
+ ("trap #0\n\t" /* Linux/m68k system call */
+ "tstl %0\n\t" /* child or parent */
+ "jne 1f\n\t" /* parent - jump */
"movel %3,%%sp@-\n\t" /* push argument */
"jsr %4@\n\t" /* call fn */
+ "movel %0,%%d1\n\t" /* pass exit value */
"movel %2,%0\n\t" /* exit */
"trap #0\n"
"1:"
: "=d" (retval)
: "0" (__NR_clone), "i" (__NR_exit),
"r" (arg), "a" (fn), "d" (clone_arg)
- : "d0", "d2");
+ : "d0");
set_fs (fs);
return retval;
unsigned long fpcntl[3]; /* fp control regs */
};
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+ is still the layout used by user (the new pt_regs doesn't have
+ all registers). */
+struct user_regs_struct {
+ long d1,d2,d3,d4,d5,d6,d7;
+ long a0,a1,a2,a3,a4,a5,a6;
+ long d0;
+ long usp;
+ long orig_d0;
+ short stkadj;
+ short sr;
+ long pc;
+ short fmtvec;
+ short __fill;
+};
+
+
/* When the kernel dumps core, it starts by dumping the user struct -
this will be used by gdb to figure out where the data and stack segments
are within the file, and what virtual addresses to use. */
struct user{
/* We start with the registers, to mimic the way that "memory" is returned
from the ptrace(3,...) function. */
- struct pt_regs regs; /* Where the registers are actually stored */
- struct switch_stack regs2; /* Backward compatibility, sort of */
+ struct user_regs_struct regs; /* Where the registers are actually stored */
/* ptrace does not yet supply these. Someday.... */
int u_fpvalid; /* True if math co-processor being used. */
/* for this mess. Not yet used. */
#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */
#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */
#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */
-#define PROD_CYBERSTORM (0x19) /* CyberStorm */
+#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */
#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */
#define MANUF_DPS (0x2169) /* DPS */
unsigned long page[MAX_ARG_PAGES];
unsigned long p;
int sh_bang;
+ int java; /* Java binary, prevent recursive invocation */
struct inode * inode;
int e_uid, e_gid;
int argc, envc;
+++ /dev/null
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
- struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
- struct linear_hash *hash_table; /* Dynamically allocated */
- struct real_dev *smallest;
- int nr_zones;
-};
-
-#endif
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
- struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
- struct linear_hash *hash_table; /* Dynamically allocated */
- struct real_dev *smallest;
- int nr_zones;
-};
-
-#endif
unsigned long grow;
address &= PAGE_MASK;
+ grow = vma->vm_start - address;
if (vma->vm_end - address
- > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur)
+ > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur ||
+ (vma->vm_mm->total_vm << PAGE_SHIFT) + grow
+ > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
return -ENOMEM;
- grow = vma->vm_start - address;
vma->vm_start = address;
vma->vm_offset -= grow;
vma->vm_mm->total_vm += grow >> PAGE_SHIFT;
unsigned long count, __u32 *buf);
extern int nfs_proc_read_reply(struct rpc_ioreq *, struct nfs_fattr *);
extern int *rpc_header(int *p, int procedure, int program, int version,
- int uid, int gid, int *groups);
+ int uid, int gid, int ngroup, gid_t *groups);
extern int *rpc_verify(int *p);
/* linux/fs/nfs/sock.c */
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_ViRGE 0x5631
#define PCI_DEVICE_ID_S3_TRIO 0x8811
+#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
+#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
#define PCI_DEVICE_ID_S3_868 0x8880
#define PCI_DEVICE_ID_S3_928 0x88b0
int session;
/* boolean value for session group leader */
int leader;
- int groups[NGROUPS];
+ int ngroups;
+ gid_t groups[NGROUPS];
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
/* stack */ 0,(unsigned long) &init_kernel_stack, \
/* ec,brk... */ 0,0,0,0,0, \
/* pid etc.. */ 0,0,0,0,0, \
-/* suppl grps*/ {NOGROUP,}, \
+/* suppl grps*/ 0, {0,}, \
/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
/* uid etc */ 0,0,0,0,0,0,0,0, \
/* timeout */ 0,SCHED_OTHER,0,0,0,0,0,0,0, \
#define SOL_NETROM 259
#define SOL_ROSE 260
#define SOL_DECNET 261
+#define SOL_X25 262
#define SOL_TCP 6
#define SOL_UDP 17
#define NET_ROSE_ROUTING_CONTROL 6
/* /proc/sys/net/x25 */
+#define NET_X25_RESTART_REQUEST_TIMEOUT 1
+#define NET_X25_CALL_REQUEST_TIMEOUT 2
+#define NET_X25_RESET_REQUEST_TIMEOUT 3
+#define NET_X25_CLEAR_REQUEST_TIMEOUT 4
+#define NET_X25_ACK_HOLDBACK_TIMEOUT 5
/* CTL_PROC names: */
/* specifications */
kdev_t dev; /* device number */
int mask; /* mask of capability: disables them */
- const int speed; /* maximum speed for reading data */
- const int capacity; /* number of discs in jukebox */
+ int speed; /* maximum speed for reading data */
+ int capacity; /* number of discs in jukebox */
/* device-related storage */
int options : 30; /* options flags */
unsigned mc_flags : 2; /* media change buffer flags */
#include <linux/netdevice.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <net/protocol.h> /* struct inet_protocol */
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+#include <net/x25.h>
+#endif
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
#include <net/ax25.h>
#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
struct tcp_opt af_tcp;
#endif
#endif
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+ x25_cb *x25;
+#endif
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
ax25_cb *ax25;
#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
extern int udpv6_connect(struct sock *sk,
struct sockaddr *uaddr,
- int addr_len);
+ size_t addr_len);
extern int datagram_recv_ctl(struct sock *sk,
struct msghdr *msg,
--- /dev/null
+/* Separate to keep compilation of protocols.c simpler */
+extern void x25_proto_init(struct net_proto *pro);
do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
/* add new mapping */
- current->mm->total_vm += (shmd->vm_end - shmd->vm_start) >> PAGE_SHIFT;
+ tmp = shmd->vm_end - shmd->vm_start;
+ if((current->mm->total_vm << PAGE_SHIFT) + tmp
+ > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
+ return -ENOMEM;
+ current->mm->total_vm += tmp >> PAGE_SHIFT;
insert_vm_struct(current->mm, shmd);
merge_segments(current->mm, shmd->vm_start, shmd->vm_end);
return -EPERM;
if (module_name == NULL || size == 0)
return -EINVAL;
- if ((error = get_mod_name(module_name, name)) != 0)
+ if ((error = get_mod_name(module_name, name)) < 0)
return error;
if (find_module(name) != NULL) {
return -EEXIST;
symtab = NULL;
}
#endif
- if ((error = get_mod_name(module_name, name)) != 0)
+ if ((error = get_mod_name(module_name, name)) < 0)
return error;
pr_debug("initializing module `%s', %d (0x%x) bytes\n",
name, codesize, codesize);
return -EPERM;
/* else */
if (module_name != NULL) {
- if ((error = get_mod_name(module_name, name)) != 0)
+ if ((error = get_mod_name(module_name, name)) < 0)
return error;
if ((mp = find_module(name)) == NULL)
return -ENOENT;
asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
{
int i;
- int * groups;
if (gidsetsize < 0)
return -EINVAL;
- groups = current->groups;
- for (i = 0 ; i < NGROUPS ; i++) {
- if (groups[i] == NOGROUP)
- break;
- }
+ i = current->ngroups;
if (gidsetsize) {
if (i > gidsetsize)
return -EINVAL;
- if (copy_to_user(grouplist, groups, sizeof(*groups)*i))
- return -EFAULT;
+ if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
+ return -EFAULT;
}
return i;
}
if (!suser())
return -EPERM;
- if (gidsetsize > NGROUPS)
+ if ((unsigned) gidsetsize > NGROUPS)
return -EINVAL;
err = copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t));
if (err) {
- gidsetsize = err/sizeof(gid_t); /* +1? */
- err = -EFAULT;
- }
- if (gidsetsize < NGROUPS)
- current->groups[gidsetsize] = NOGROUP;
+ gidsetsize = 0;
+ err = -EFAULT;
+ }
+ current->ngroups = gidsetsize;
return err;
}
int in_group_p(gid_t grp)
{
- int i;
-
- if (grp == current->fsgid)
- return 1;
-
- for (i = 0; i < NGROUPS; i++) {
- if (current->groups[i] == NOGROUP)
- break;
- if (current->groups[i] == grp)
- return 1;
+ if (grp != current->fsgid) {
+ int i = current->ngroups;
+ if (i) {
+ gid_t *groups = current->groups;
+ do {
+ if (*groups == grp)
+ goto out;
+ groups++;
+ i--;
+ } while (i);
+ }
+ return 0;
}
- return 0;
+out:
+ return 1;
}
asmlinkage int sys_newuname(struct new_utsname * name)
/* Like in_group_p, but testing against egid, not fsgid */
static int in_egroup_p(gid_t grp)
{
- int i;
-
- if (grp == current->euid)
- return 1;
-
- for (i = 0; i < NGROUPS; i++) {
- if (current->groups[i] == NOGROUP)
- break;
- if (current->groups[i] == grp)
- return 1;
+ if (grp != current->egid) {
+ int i = current->ngroups;
+ if (i) {
+ gid_t *groups = current->groups;
+ do {
+ if (*groups == grp)
+ goto out;
+ groups++;
+ i--;
+ } while (i);
+ }
+ return 0;
}
- return 0;
+out:
+ return 1;
}
+
/* ctl_perm does NOT grant the superuser all rights automatically, because
some sysctl variables are readonly even to root. */
static int test_perm(int mode, int op)
/*
* Ok, looks good - let it rip.
*/
- mm->brk = brk;
- do_mmap(NULL, oldbrk, newbrk-oldbrk,
+ if(do_mmap(NULL, oldbrk, newbrk-oldbrk,
PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_FIXED|MAP_PRIVATE, 0);
- return brk;
+ MAP_FIXED|MAP_PRIVATE, 0) != oldbrk)
+ return mm->brk;
+ return mm->brk = brk;
}
/*
do_munmap(addr, len); /* Clear old maps */
+ /* Check against address space limit. */
+ if ((mm->total_vm << PAGE_SHIFT) + len
+ > current->rlim[RLIMIT_AS].rlim_cur) {
+ kfree(vma);
+ return -ENOMEM;
+ }
+
/* Private writable mapping? Check memory availability.. */
if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) {
if (!(flags & MAP_NORESERVE) &&
insert_vm_struct(current->mm, new_vma);
merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end);
do_munmap(addr, old_len);
+ current->mm->total_vm += new_len >> PAGE_SHIFT;
return new_addr;
}
kfree(new_vma);
if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
return -EAGAIN;
}
+ if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
+ > current->rlim[RLIMIT_AS].rlim_cur)
+ return -ENOMEM;
/* old_len exactly to the end of the area.. */
if (old_len == vma->vm_end - addr &&
dep_tristate 'Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+# tristate 'CCITT X.25 Packet Layer' CONFIG_X25
bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
fi
endmenu
s->state = AX25_STATE_0;
s->device = NULL;
if (s->sk != NULL) {
- s->sk->state = TCP_CLOSE;
- s->sk->err = ENETUNREACH;
+ s->sk->state = TCP_CLOSE;
+ s->sk->err = ENETUNREACH;
+ s->sk->shutdown |= SEND_SHUTDOWN;
if (!s->sk->dead)
s->sk->state_change(s->sk);
s->sk->dead = 1;
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ENETRESET;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ENETRESET;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
ax25->sk->dead = 1;
switch (sk->protinfo.ax25->state) {
case AX25_STATE_0:
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
ax25_destroy_socket(sk->protinfo.ax25);
ax25_send_control(sk->protinfo.ax25, DISC, POLLON, C_COMMAND);
sk->protinfo.ax25->state = AX25_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
ax25_destroy_socket(sk->protinfo.ax25);
ax25_send_control(sk->protinfo.ax25, DM, POLLON, C_RESPONSE);
sk->protinfo.ax25->state = AX25_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
ax25_destroy_socket(sk->protinfo.ax25);
sk->protinfo.ax25->t1timer = sk->protinfo.ax25->t1 = ax25_calculate_t1(sk->protinfo.ax25);
sk->protinfo.ax25->state = AX25_STATE_2;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
sk->destroy = 1;
}
} else {
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
- sk->dead = 1;
+ sk->dead = 1;
ax25_destroy_socket(sk->protinfo.ax25);
}
if (sk->zapped)
return -EADDRNOTAVAIL;
- if (sk->shutdown & SEND_SHUTDOWN)
- {
+ if (sk->shutdown & SEND_SHUTDOWN) {
send_sig(SIGPIPE, current, 0);
return -EPIPE;
}
skb->h.raw = skb->data;
}
- copied=size;
- if(copied>length)
- {
- copied = length;
- msg->msg_flags|=MSG_TRUNC;
+ copied = length;
+
+ if (copied > size) {
+ copied = size;
+ msg->msg_flags |= MSG_TRUNC;
}
+
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (sax) {
ax25_clear_queues(ax25);
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNREFUSED;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ECONNREFUSED;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
} else {
ax25->modulus = MODULUS;
if (ax25->dama_slave) {
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
}
break;
if (pf) {
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
}
break;
if (pf) {
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown|=SEND_SHUTDOWN;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
}
break;
switch (frametype) {
case SABM:
if (dama) ax25_dama_on(ax25);
-
ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE);
case SABME:
if (dama) ax25_dama_on(ax25);
-
ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE);
ax25->t3timer = 0;
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- ax25->sk->shutdown|=SEND_SHUTDOWN;
+ ax25->sk->dead = 1;
}
break;
ax25->t3timer = 0;
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
- if (ax25->sk) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNRESET;
+ if (ax25->sk != NULL) {
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ECONNRESET;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
break;
switch (frametype) {
case SABM:
if (dama) ax25_dama_on(ax25);
-
ax25->dama_slave = dama;
ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
case SABME:
if (dama) ax25_dama_on(ax25);
-
ax25->dama_slave = dama;
ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
ax25->t3timer = 0;
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
break;
ax25->t3timer = 0;
ax25->state = AX25_STATE_0;
ax25_dama_off(ax25);
-
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNRESET;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ECONNRESET;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
break;
return queued;
if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
- ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
- printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
+ ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
return queued;
- }
del_timer(&ax25->timer);
if (ax25->device == NULL) {
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ENETUNREACH;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ENETUNREACH;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
return;
}
ax25_dev->values[AX25_VALUES_CONMODE] = AX25_DEF_CONMODE;
ax25_dev->values[AX25_VALUES_WINDOW] = AX25_DEF_WINDOW;
ax25_dev->values[AX25_VALUES_EWINDOW] = AX25_DEF_EWINDOW;
- ax25_dev->values[AX25_VALUES_T1] = AX25_DEF_T1 * PR_SLOWHZ;
- ax25_dev->values[AX25_VALUES_T2] = AX25_DEF_T2 * PR_SLOWHZ;
- ax25_dev->values[AX25_VALUES_T3] = AX25_DEF_T3 * PR_SLOWHZ;
- ax25_dev->values[AX25_VALUES_IDLE] = AX25_DEF_IDLE * PR_SLOWHZ * 60;
+ ax25_dev->values[AX25_VALUES_T1] = AX25_DEF_T1;
+ ax25_dev->values[AX25_VALUES_T2] = AX25_DEF_T2;
+ ax25_dev->values[AX25_VALUES_T3] = AX25_DEF_T3;
+ ax25_dev->values[AX25_VALUES_IDLE] = AX25_DEF_IDLE;
ax25_dev->values[AX25_VALUES_N2] = AX25_DEF_N2;
ax25_dev->values[AX25_VALUES_DIGI] = AX25_DEF_DIGI;
ax25_dev->values[AX25_VALUES_PACLEN] = AX25_DEF_PACLEN;
if (ax25->sk != NULL) {
if (ax25->sk->debug)
printk(KERN_DEBUG "AX.25 T3 Timeout\n");
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
ax25_reset_timer(ax25);
ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- ax25->sk->destroy = 1;
+ ax25->sk->dead = 1;
+ ax25->sk->destroy = 1;
}
}
ax25_clear_queues(ax25);
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
} else {
ax25->modulus = MODULUS;
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
} else {
ax25->n2count++;
if (ax25->sk != NULL) {
if (ax25->sk->debug)
printk(KERN_DEBUG "AX.25 link Failure\n");
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
if (!ax25->sk->dead)
ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
+ ax25->sk->dead = 1;
}
} else {
ax25->n2count++;
*/
if (tot_len > dev->mtu)
+ {
goto fragment;
+ }
/*
* Add an IP checksum
goto out;
fragment:
+ if ((iph->frag_off & htons(IP_DF)))
+ {
+ printk(KERN_DEBUG "sending pkt_too_big to self\n");
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+ htonl(dev->mtu), dev);
+ goto out;
+ }
ip_fragment(sk,skb,dev,0);
goto out;
}
#endif
(*conn->class->destructor)(conn);
tcp_dec_slow_timer(TCP_SLT_SYNACK);
+ sk->ack_backlog--;
kfree(conn);
if (!tp->syn_wait_queue)
}
else
{
- rtmsg.rtmsg_prefixlen = 128;
+ rtmsg.rtmsg_prefixlen = 10;
rtmsg.rtmsg_dst.s6_addr32[0] = __constant_htonl(0xfe800000);
rtmsg.rtmsg_dst.s6_addr32[3] = dev->pa_dstaddr;
rtmsg.rtmsg_metric = 1;
- rtmsg.rtmsg_flags = RTF_HOST|RTF_UP;
+ rtmsg.rtmsg_flags = RTF_NEXTHOP|RTF_UP;
}
strcpy(rtmsg.rtmsg_device, dev->name);
* 2 of the License, or (at your option) any later version.
*/
+/*
+ * Changes:
+ *
+ * Masaki Hirabaru : Fix for /proc info > pagesize
+ * <masaki@merit.edu>
+ */
#include <linux/config.h>
#include <linux/errno.h>
static void rt6_walk_tree(f_pnode func, void * arg, int filter);
static void rt6_rt_timeout(struct fib6_node *fn, void *arg);
-static int rt6_msgrcv(struct sk_buff *skb);
+static int rt6_msgrcv(int unit, struct sk_buff *skb);
struct rt6_statistics rt6_stats = {
1, 0, 1, 1, 0
return 0;
}
- return 1;
+ return 1;
}
/*
if (addr_match(&fn->leaf->rt_dst, addr, fn->fn_bit))
{
- if (pbit == fn->fn_bit &&
+ if (pbit == fn->fn_bit && pbit &&
addr_bit_equal(addr, &fn->leaf->rt_dst,
rt->rt_prefixlen))
{
return 0;
}
- if (pbit > fn->fn_bit)
+ if (pbit > fn->fn_bit || pbit == 0)
{
/* walk down on tree */
if (children < 2)
{
struct fib6_node *child;
+ struct fib6_node *pn;
child = dir ? fn->right : fn->left;
child->parent = fn->parent;
}
- /*
+ /*
* try to collapse on top
- */
- if ((fn->parent->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
+ */
+ pn = fn->parent;
+ fn->parent = NULL;
+
+ if ((pn->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
{
- if (fn->leaf)
+ if (pn->leaf)
{
- rt_release(fn->leaf);
- fn->leaf = NULL;
+ rt_release(pn->leaf);
+ pn->leaf = NULL;
}
- fib6_del_3(fn->parent);
+ fib6_del_3(pn);
}
+
if (fn->fn_flags & RTN_BACKTRACK)
{
rt6_stats.fib_route_nodes--;
fn->fn_bit = bit;
fn->fn_flags &= ~RTN_BACKTRACK;
+
fn->leaf = fn->left->leaf;
+ atomic_inc(&fn->leaf->rt_ref);
rt6_stats.fib_route_nodes--;
}
return NULL;
}
-static struct fib6_node * fib6_del_rt_2(struct in6_addr *addr, __u32 prefixlen,
- struct rt6_info *rt)
+static struct fib6_node * fib6_del_rt_2(struct rt6_info *rt)
{
struct fib6_node *fn;
-
+ struct in6_addr *addr = &rt->rt_dst;
+ int prefixlen = rt->rt_prefixlen;
+
for (fn = &routing_table; fn;)
{
int dir;
if (fn)
{
- struct rt6_info *back = NULL;
+ struct rt6_info **back;
struct rt6_info *lf;
+ back = &fn->leaf;
+
for(lf = fn->leaf; lf; lf=lf->next)
{
if (rt == lf)
{
- /* delete this entry */
- if (back == NULL)
- fn->leaf = lf->next;
- else
- back->next = lf->next;
-
- lf->fib_node = NULL;
+ /*
+ * delete this entry
+ */
+
+ *back = lf->next;
rt_release(lf);
return fn;
}
- back = lf;
+ back = &lf->next;
}
}
{
struct fib6_node *fn;
- fn = fib6_del_rt_2(&rt->rt_dst, rt->rt_prefixlen, rt);
+ fn = fib6_del_rt_2(rt);
if (fn == NULL)
return -ENOENT;
memcpy(&rt->rt_dst, &rtmsg->rtmsg_dst, sizeof(struct in6_addr));
rt->rt_prefixlen = rtmsg->rtmsg_prefixlen;
+
+ if (rt->rt_prefixlen == 0)
+ {
+ printk(KERN_DEBUG "ip6_fib: zero length route not allowed\n");
+ return -EINVAL;
+ }
if (flags & (RTF_GATEWAY | RTF_NEXTHOP))
{
{
struct rt6_info *gw_rt;
- gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, NULL,
+ gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, dev,
RTI_GATEWAY);
if (gw_rt == NULL)
int ipv6_route_del(struct in6_rtmsg *rtmsg)
{
struct rt6_info * rt;
-
+ int res = -ENOENT;
+
+ atomic_inc(&rt6_lock);
+
rt = fib6_lookup_1(&rtmsg->rtmsg_dst, 0);
- if (!rt || (rt && (rt->rt_prefixlen != rtmsg->rtmsg_prefixlen)))
- return -ENOENT;
- return fib6_del_rt(rt);
+
+ if (rt && (rt->rt_prefixlen == rtmsg->rtmsg_prefixlen))
+ {
+ int test;
+
+ start_bh_atomic();
+
+ test = (rt6_lock == 1);
+
+ if (test)
+ {
+ res = fib6_del_rt(rt);
+ }
+ end_bh_atomic();
+
+ if (!test)
+ {
+ /*
+ * This function is called from user
+ * context only (at the moment).
+ * As we don't sleep we should never see
+ * a lock count > 1.
+ *
+ * If this assumptions becomes invalid we'll
+ * just have to had a del request to the
+ * queue in this case.
+ */
+ res = -EBUSY;
+ }
+ }
+
+ atomic_dec(&rt6_lock);
+ return res;
}
/*
{
struct rt6_info *rt;
+ atomic_inc(&rt6_lock);
+
if ((rt = fib6_lookup_1(addr, flags)))
{
if (src_dev)
for (sprt=rt; sprt; sprt=sprt->next)
{
if (sprt->rt_dev == src_dev)
- return sprt;
+ {
+ rt = sprt;
+ goto out;
+ }
}
if (flags & RTI_DEVRT)
{
- return NULL;
+ rt = NULL;
}
}
- return rt;
+ goto out;
}
if (!(flags & RTI_GATEWAY))
{
if ((rt = dflt_rt_lookup()))
{
- return rt;
+ goto out;
}
- return last_resort_rt;
+ rt = last_resort_rt;
}
-
- return NULL;
+ out:
+ atomic_dec(&rt6_lock);
+ return rt;
}
/*
}
#ifdef CONFIG_PROC_FS
-#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7)
+#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7 + 1)
struct rt6_proc_arg {
char *buffer;
int offset;
+ int length;
int skip;
int len;
};
arg->skip++;
continue;
}
-
+
+ if (arg->len >= arg->length)
+ return;
+
for (i=0; i<16; i++)
{
sprintf(arg->buffer + arg->len, "%02x",
struct fib6_node sfn;
arg.buffer = buffer;
arg.offset = offset;
+ arg.length = length;
arg.skip = 0;
arg.len = 0;
* routing socket moral equivalent
*/
-static int rt6_msgrcv(struct sk_buff *skb)
+static int rt6_msgrcv(int unit, struct sk_buff *skb)
{
int count = 0;
struct in6_rtmsg *rtmsg;
static void sit_err(int type, int code,
unsigned char *buff, __u32 info,
__u32 daddr, __u32 saddr,
- struct inet_protocol *protocol);
+ struct inet_protocol *protocol,
+ int len);
static struct inet_protocol sit_protocol = {
sit_rcv,
*/
static void sit_err(int type, int code, unsigned char *buff, __u32 info,
- __u32 daddr, __u32 saddr, struct inet_protocol *protocol)
+ __u32 daddr, __u32 saddr, struct inet_protocol *protocol,
+ int len)
{
if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
*
*/
-int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, size_t addr_len)
{
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
struct in6_addr *daddr;
s->protinfo.nr->device = NULL;
s->state = TCP_CLOSE;
s->err = ENETUNREACH;
+ s->shutdown |= SEND_SHUTDOWN;
s->state_change(s);
s->dead = 1;
}
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ENETRESET;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
case NR_STATE_0:
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
nr_destroy_socket(sk);
case NR_STATE_1:
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
nr_destroy_socket(sk);
nr_write_internal(sk, NR_DISCACK);
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown = SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
nr_destroy_socket(sk);
sk->protinfo.nr->t4timer = 0;
sk->protinfo.nr->state = NR_STATE_2;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
sk->destroy = 1;
if (sk->zapped)
return -EADDRNOTAVAIL;
+ if (sk->shutdown & SEND_SHUTDOWN) {
+ send_sig(SIGPIPE, current, 0);
+ return -EPIPE;
+ }
+
if (sk->protinfo.nr->device == NULL)
return -ENETUNREACH;
}
copied = skb->len;
- if(copied>size)
- {
- copied=size;
- msg->msg_flags|=MSG_TRUNC;
+
+ if (copied > size) {
+ copied = size;
+ msg->msg_flags |= MSG_TRUNC;
}
+
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (sax != NULL) {
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ECONNREFUSED;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ECONNRESET;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
if (!nr_route_frame(skb, NULL)) {
kfree_skb(skb, FREE_WRITE);
- sk->state = TCP_CLOSE;
- sk->err = ENETUNREACH;
+ sk->state = TCP_CLOSE;
+ sk->err = ENETUNREACH;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
- sk->dead = 1;
+ sk->dead = 1;
}
}
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ETIMEDOUT;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ETIMEDOUT;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.nr->state = NR_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ETIMEDOUT;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
extern void destroy_8023_client(struct datalink_proto *);
#endif
+extern char *skb_push_errstr;
+extern char *skb_put_errstr;
static struct symbol_table net_syms = {
#include <linux/symtab_begin.h>
+ /* Skbuff symbols. */
+ X(skb_push_errstr),
+ X(skb_put_errstr),
+
/* Socket layer registration */
X(sock_register),
X(sock_unregister),
#include <net/p8022call.h>
#include <net/p8022trcall.h>
#endif
+#ifdef CONFIG_X25
+#include <net/x25call.h>
+#endif
#ifdef CONFIG_AX25
#include <net/ax25call.h>
#ifdef CONFIG_NETROM
s->protinfo.rose->device = NULL;
s->state = TCP_CLOSE;
s->err = ENETUNREACH;
+ s->shutdown |= SEND_SHUTDOWN;
s->state_change(s);
s->dead = 1;
}
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ENETRESET;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
case ROSE_STATE_0:
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
rose_destroy_socket(sk);
case ROSE_STATE_1:
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
rose_destroy_socket(sk);
case ROSE_STATE_2:
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
rose_destroy_socket(sk);
sk->protinfo.rose->timer = sk->protinfo.rose->t3;
sk->protinfo.rose->state = ROSE_STATE_2;
sk->state = TCP_CLOSE;
+ sk->shutdown |= SEND_SHUTDOWN;
sk->state_change(sk);
sk->dead = 1;
sk->destroy = 1;
if (sk->zapped)
return -EADDRNOTAVAIL;
+ if (sk->shutdown & SEND_SHUTDOWN) {
+ send_sig(SIGPIPE, current, 0);
+ return -EPIPE;
+ }
+
if (sk->protinfo.rose->device == NULL)
return -ENETUNREACH;
copied = skb->len;
- if(copied>size)
- {
- copied=size;
- msg->msg_flags|=MSG_TRUNC;
+ if (copied > size) {
+ copied = size;
+ msg->msg_flags |= MSG_TRUNC;
}
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ECONNREFUSED;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;
sk->protinfo.rose->state = ROSE_STATE_0;
sk->state = TCP_CLOSE;
sk->err = ETIMEDOUT;
+ sk->shutdown |= SEND_SHUTDOWN;
if (!sk->dead)
sk->state_change(sk);
sk->dead = 1;