S: Poltava 314023
S: Ukraine
+N: John E. Gotts
+E: jgotts@engin.umich.edu
+D: kernel hacker
+S: 8124 Constitution Apt. 7
+S: Sterling Heights, MI 48313
+S: USA
+
N: Grant Guenther
E: grant@torque.net
D: Iomega PPA / ZIP driver
S: 8103 Rein
S: Austria
+N: Stefan Reinauer
+E: stepan@home.culture.mipt.ru
+W: http://home.culture.mipt.ru/~stepan
+D: Modulized affs and ufs. Minor fixes.
+S: Rebmannsweg 34h
+S: 79539 Loerrach
+S: Germany
+
N: William E. Roadcap
E: roadcapw@cfw.com
W: http://www.cfw.com/~roadcapw
format. Saying M or N here is dangerous, because some crucial
programs on your system might be in A.OUT format.
+Kernel support for JAVA binaries
+CONFIG_BINFMT_JAVA
+ JAVA binaries are becoming a universal executable format. This
+ option allows Java binaries and Java Applets to be handled invisibly
+ to the OS. As more and more Java programs become available, the use
+ for this will gradually increase. If you want to use this, read the
+ Java on Linux HOWTO, available via ftp (user: anonymous) at
+ sunsite.unc.edu:/pub/Linux/docs/HOWTO. In order to execute Java binaries,
+ you will also need to install the Java Developers Kit. If you disable
+ this option it will reduce your kernel by about one page. This is not
+ much and by itself does not warrant removing support. However its
+ removal is a good idea if you do not have the JDK installed. If you
+ don't know what to answer at this point then answer Y. You may answer
+ M for module support and later load the module when you install the
+ JDK or find a interesting Java program that you can't live without.
Processor type
CONFIG_M386
This is the processor type of your CPU. It is used for optimizing
### Dunno
###
-Always IN2000 SCSI support (test release)
+Always IN2000 SCSI support
CONFIG_SCSI_IN2000
- Believe it or not, there is a SCSI host adaptor of that name. It is
- explained in section 3.6 of the SCSI-HOWTO, available via ftp (user:
- anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't
- work out of the box, you may have to change some settings in
- drivers/scsi/in2000.h. You may also want to drop in a rewritten,
- and probably more reliable, driver from John Shifflett, which you
- can get from ftp://ftp.netcom.com/pub/js/jshiffle/in2000/ . 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.
+ This is support for an ISA bus SCSI host adaptor. You'll find
+ more information in drivers/scsi/in2000.readme. If it doesn't
+ work out of the box, you may have to change the jumpers for IRQ
+ or address selection. 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.
PAS16 SCSI support
CONFIG_SCSI_PAS16
%
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$}
-\date{Last revised: May 5, 1996}
+\date{Last revised: May 9, 1996}
\maketitle
%
\noindent
\major{48}{}{char }{SDL RISCom serial card}
\major{49}{}{char }{SDL RISCom serial card -- alternate devices}
\major{50}{}{char }{Reserved for GLINT}
-\major{51}{--59}{}{Unallocated}
+\major{51}{}{char }{Baycom radio modem}
+\major{52}{--59}{}{Unallocated}
\major{60}{--63}{}{Local/experimental use}
\major{64}{--119}{}{Unallocated}
\major{120}{--127}{}{Local/experimental use}
\end{devicelist}
\begin{devicelist}
-\major{50}{--59}{}{Unallocated}
+\major{50}{}{char}{Reserved for GLINT}
+\end{devicelist}
+
+\begin{devicelist}
+\major{51}{}{char }{Baycom radio modem}
+ \minor{0}{/dev/bc0}{First Baycom radio modem}
+ \minor{1}{/dev/bc1}{Second Baycom radio modem}
+ \minordots
+\end{devicelist}
+
+\begin{devicelist}
+\major{52}{--59}{}{Unallocated}
\end{devicelist}
\begin{devicelist}
Maintained by H. Peter Anvin <hpa@zytor.com>
- Last revised: May 5, 1996
+ Last revised: May 9, 1996
This list is the successor to Rick Miller's Linux Device List, which
he stopped maintaining when he got busy with other things in 1993. It
1 = /dev/cul1 Callout device corresponding to ttyL1
...
- 50-59 UNALLOCATED
+ 50 char Reserved for GLINT
+
+ 51 char Baycom radio modem
+ 0 = /dev/bc0 First Baycom radio modem
+ 1 = /dev/bc1 Second Baycom radio modem
+ ...
+
+ 52-59 UNALLOCATED
60-63 LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not
DOS\4 The original filesystem with directory cache. The directory
cache speeds up directory accesses on floppies considerably,
- but slowes down file creation/deletion. Doesn't make much
+ but slows down file creation/deletion. Doesn't make much
sense on hard disks. Not supported.
DOS\5 The Fast File System with directory cache. Not supported.
uid[=uid] This sets the uid of the root directory (i. e. the mount point
to uid or to the uid of the current user, if the =uid is
- ommitted.
+ omitted.
gid[=gid] Same as above, but for gid.
use_mp The uid and gid are taken from the now covered mount point
instead of the current user or value defined.
-mode=mode Sets the mode flags to the given (octal) value, regardles
+mode=mode Sets the mode flags to the given (octal) value, regardless
of the original permissions. Directories will get an x
permission, if the corresponding r bit is set.
This is useful since most of the plain AmigaOS files
reserved=num Sets the number of reserved blocks at the start of the
partition to num. Default is 2.
-root=block Sets the block number of the root block. This schould never
- be neccessary.
+root=block Sets the block number of the root block. This should never
+ be necessary.
bs=blksize Sets the blocksize to blksize. Valid block sizes are 512,
1024, 2048 and 4096. Like the root option, this should
- never be neccessary, as the affs can figure it out itself.
+ never be necessary, as the affs can figure it out itself.
quiet The file system will not return an error for disallowed
mode changes.
--- /dev/null
+ JAVA Binary Kernel Support for Linux v1.01
+ ------------------------------------------
+
+Linux beats them ALL! While all other OS's are TALKING about direct
+support of Java Binaries in the OS, Linux is doing it!
+
+You execute Java classes as you would any other executable, after a few
+small details:
+
+ 1) You MUST FIRST install the Java Developers Kit for Linux.
+ The Java on Linux HOWTO gives the details on getting and
+ installing this. This HOWTO can be found at:
+
+ 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 edit the
+ kernel's fs/binfmt_java.c file and make the needed change to the
+ _PATH_JAVA definition at the top of that file.
+
+ 2) You must chmod the '*.class' files you wish to execute with
+ the execute bit. This is not normally (till now) done with
+ '.class' files.
+
+ 3) You must optionally export a CLASSPATH environment variable,
+ if you plan to use Java applications installed outside of
+ /usr/local/java/classes/*.
+
+ 4) Either compile your kernel with Java support builtin, or
+ as a loadable module. If a module, load it with insmod or
+ kerneld.
+
+
+To test your new setup, enter in the following simple Java app, and name
+it "HelloWorld.java":
+
+ class HelloWorld {
+ public static void main(String args[]) {
+ System.out.println("Hello World!");
+ }
+ }
+
+
+Now compile the application with:
+
+ /usr/local/java/bin/javac HelloWorld.java
+
+Set the executable permissions of the binary file, with:
+
+ chmod 755 HelloWorld.class
+
+And then execute it:
+
+ ./HellowWorld.class
+
+
+Yes, it's JUST THAT EASY! ;-)
+
+-----------------------------------------------------------------
+
+Nope, I didn't forget about Java Applets! ;-)
+
+While this may not be the best way to do this, it works!
+
+Take any html file used with the Java appletviewer (like the
+demo/Blink/example1.html file), and:
+
+ 1) Insert a new first line of:
+
+ <!--applet-->
+
+ Make sure the '<' is the first character in the file. This
+ will be treated as a valid HTML comment outside of this
+ 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 edit the
+ kernel's fs/binfmt_java.c file and make the needed change to the
+ _PATH_APPLET definition at the top of that file.
+
+ 3) You must chmod the '*.html' files you wish to execute with
+ the execute bit. This is not normally (till now) done with
+ '.html' files.
+
+ 4) And then execute it.
+
+
+
+Brian A. Lantz
+brian@lantz.com
Some misc modules:
lp: line printer
binfmt_elf: elf loader
+ binfmt_java: java loader
isp16: cdrom interface
When you have made the kernel, you create the modules by doing:
L: linux-kernel@vger.rutgers.edu
S: Maintained
-
MOUSE AND MISC DEVICES [GENERAL]
P: Alessandro Rubini
M: rubini@ipvvis.unipv.it
L: linux-net@vger.rutgers.edu
S: Maintained
+ADVANSYS SCSI DRIVER
+P: Bob Frey
+M: Bob Frey <bobf@advansys.com>
+W: http://www.advansys.com/linux
+S: Maintained
+
REST:
P: Linus Torvalds
S: Buried alive in email
VERSION = 1
PATCHLEVEL = 3
-SUBLEVEL = 99
+SUBLEVEL = 100
ARCH = i386
CONFIG_ALPHA_ALCOR=y
# CONFIG_SERIAL_ECHO is not set
# CONFIG_TGA_CONSOLE is not set
-CONFIG_PCI_OPTIMIZE=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y
bool 'System V IPC' CONFIG_SYSVIPC
tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
choice 'Processor type' \
CONFIG_NET=y
# CONFIG_MAX_16M is not set
CONFIG_PCI=y
-CONFIG_PCI_OPTIMIZE=y
CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_JAVA is not set
CONFIG_KERNEL_ELF=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
{
static const char *model[] = {
"0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB",
- "10","11","12","13","Am5x85-WT","Am5x86-WB"
+ "10","11","12","13","Am5x86-WT","Am5x86-WB"
};
if (nr < sizeof(model)/sizeof(char *))
return model[nr];
#ifndef __ASSEMBLY__
#include <asm/sigcontext.h> /* for struct _fpstate */
-#include <linux/math_emu.h>
+#include <asm/math_emu.h>
+
#include <linux/linkage.h>
/*
#define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
-#define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
-
-#define DPRINT1(x,x1) printk(DEVICE_NAME "%d: " x,current_drive,(x1))
-
-#define DPRINT2(x,x1,x2) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
-
-#define DPRINT3(x,x1,x2,x3) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
+#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args)
#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
static void floppy_start(void);
static void process_fd_request(void);
static void recalibrate_floppy(void);
-static void floppy_shutdown(unsigned long);
+static void floppy_shutdown(void);
+static void unexpected_floppy_interrupt(void);
static int floppy_grab_irq_and_dma(void);
static void floppy_release_irq_and_dma(void);
{
/* this routine checks whether the floppy driver is "alive" */
if (fdc_busy && command_status < 2 && !fd_timeout.prev){
- DPRINT1("timeout handler died: %s\n",message);
+ DPRINT("timeout handler died: %s\n",message);
}
}
#endif
(FDCS->dor & 3) != UNIT(drive) ||
fdc != FDC(drive)){
DPRINT("probing disk change on unselected drive\n");
- DPRINT3("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
+ DPRINT("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
FDCS->dor);
}
#endif
#ifdef DCL_DEBUG
if (UDP->flags & FD_DEBUG){
- DPRINT1("checking disk change line for drive %d\n",drive);
- DPRINT1("jiffies=%ld\n", jiffies);
- DPRINT1("disk change line=%x\n",fd_inb(FD_DIR)&0x80);
- DPRINT1("flags=%x\n",UDRS->flags);
+ DPRINT("checking disk change line for drive %d\n",drive);
+ DPRINT("jiffies=%ld\n", jiffies);
+ DPRINT("disk change line=%x\n",fd_inb(FD_DIR)&0x80);
+ DPRINT("flags=%x\n",UDRS->flags);
}
#endif
if (UDP->flags & FD_BROKEN_DCL)
if (UDRS->maxblock){
/* mark it changed */
USETF(FD_DISK_CHANGED);
+ }
- /* invalidate its geometry */
- if (UDRS->keep_data >= 0) {
- if ((UDP->flags & FTD_MSG) &&
- current_type[drive] != NULL)
- DPRINT("Disk type is undefined after "
- "disk change\n");
- current_type[drive] = NULL;
- floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE;
- }
+ /* invalidate its geometry */
+ if (UDRS->keep_data >= 0) {
+ if ((UDP->flags & FTD_MSG) &&
+ current_type[drive] != NULL)
+ DPRINT("Disk type is undefined after "
+ "disk change\n");
+ current_type[drive] = NULL;
+ floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE;
}
+
/*USETF(FD_DISK_NEWCHANGE);*/
return 1;
} else {
DPRINT("FDC access conflict!\n");
if (DEVICE_INTR)
- DPRINT1("device interrupt still active at FDC release: %p!\n",
+ DPRINT("device interrupt still active at FDC release: %p!\n",
DEVICE_INTR);
command_status = FD_COMMAND_NONE;
del_timer(&fd_timeout);
set_fdc(saved_drive);
}
+static void empty(void)
+{
+}
+
+static struct tq_struct floppy_tq =
+{ 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
+
static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
+static void cancel_activity(void)
+{
+ CLEAR_INTR;
+ floppy_tq.routine = (void *)(void *) empty;
+ del_timer(&fd_timer);
+}
+
/* this function makes sure that the disk stays in the drive during the
* transfer */
static void fd_watchdog(void)
if (disk_change(current_drive)){
DPRINT("disk removed during i/o\n");
- floppy_shutdown(1);
+ cancel_activity();
+ cont->done(0);
+ reset_fdc();
} else {
del_timer(&fd_timer);
fd_timer.function = (timeout_fn) fd_watchdog;
return status;
}
if (!initialising) {
- DPRINT2("Getstatus times out (%x) on fdc %d\n",
+ DPRINT("Getstatus times out (%x) on fdc %d\n",
status, fdc);
show_floppy();
}
}
FDCS->reset = 1;
if (!initialising) {
- DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
- byte, status);
+ DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
+ byte, fdc, status);
show_floppy();
}
return -1;
break;
}
if(!initialising) {
- DPRINT2("'get result' error. Last status=%x Read bytes=%d\n",
- status, i);
+ DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
+ fdc, status, i);
show_floppy();
}
FDCS->reset = 1;
#ifdef DCL_DEBUG
if (DP->flags & FD_DEBUG){
DPRINT("clearing NEWCHANGE flag because of effective seek\n");
- DPRINT1("jiffies=%ld\n", jiffies);
+ DPRINT("jiffies=%ld\n", jiffies);
}
#endif
CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
#ifdef DCL_DEBUG
if (DP->flags & FD_DEBUG){
DPRINT("checking whether disk is write protected\n");
- DPRINT1("wp=%x\n",ST3 & 0x40);
+ DPRINT("wp=%x\n",ST3 & 0x40);
}
#endif
if (!(ST3 & 0x40))
FDCS->reset = 1;
}
-static struct tq_struct floppy_tq =
-{ 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
-
/* interrupt handler */
void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
}
}
-static void empty(void)
-{
-}
-
void show_floppy(void)
{
int i;
printk("\n");
}
-static void floppy_shutdown(unsigned long mode)
+static void floppy_shutdown(void)
{
- if (!initialising && !mode)
+ if (!initialising)
show_floppy();
- CLEAR_INTR;
- floppy_tq.routine = (void *)(void *) empty;
- del_timer(&fd_timer);
+ cancel_activity();
sti();
floppy_enable_hlt();
fd_disable_dma();
/* avoid dma going to a random drive after shutdown */
- if (!initialising && !mode)
- DPRINT("floppy timeout\n");
+ if (!initialising)
+ DPRINT("floppy timeout called\n");
FDCS->reset = 1;
if (cont){
cont->done(0);
(done_f)empty
};
+
+static struct cont_t intr_cont={
+ empty,
+ process_fd_request,
+ empty,
+ (done_f) empty
+};
+
static int wait_til_done(void (*handler)(void), int interruptible)
{
int ret;
sleep_on(&command_done);
}
if (command_status < 2){
- floppy_shutdown(1);
+ cancel_activity();
+ cont = &intr_cont;
+ reset_fdc();
sti();
- process_fd_request();
return -EINTR;
}
sti();
}
/*
- * formatting and support.
- * =======================
+ * formatting support.
+ * ===================
*/
static void format_interrupt(void)
{
raw_cmd->track = track;
raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
- /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
+ FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
raw_cmd->rate = _floppy->rate & 0x43;
raw_cmd->cmd_count = NR_F;
COMMAND = FM_MODE(_floppy,FD_FORMAT);
if (nr_sectors > current_count_sectors + ssize -
(current_count_sectors + sector_t) % ssize +
sector_t % ssize){
- DPRINT2("long rw: %x instead of %lx\n",
+ DPRINT("long rw: %x instead of %lx\n",
nr_sectors, current_count_sectors);
printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
printk("rh=%d h=%d\n", R_HEAD, HEAD);
if (probing) {
if (DP->flags & FTD_MSG)
- DPRINT2("Auto-detected floppy type %s in fd%d\n",
+ DPRINT("Auto-detected floppy type %s in fd%d\n",
_floppy->name,current_drive);
current_type[current_drive] = _floppy;
floppy_sizes[TOMINOR(current_drive)] = _floppy->size >> 1;
if (dma_buffer + size >
floppy_track_buffer + (max_buffer_sectors << 10) ||
dma_buffer < floppy_track_buffer){
- DPRINT1("buffer overrun in copy buffer %d\n",
+ DPRINT("buffer overrun in copy buffer %d\n",
(int) ((floppy_track_buffer - dma_buffer) >>9));
printk("sector_t=%d buffer_min=%d\n",
sector_t, buffer_min);
break;
}
if (((unsigned long)buffer) % 512)
- DPRINT1("%p buffer not aligned\n", buffer);
+ DPRINT("%p buffer not aligned\n", buffer);
#endif
if (CT(COMMAND) == FD_READ) {
fd_cacheflush(dma_buffer, size);
if (remaining){
if (remaining > 0)
max_sector -= remaining >> 9;
- DPRINT1("weirdness: remaining %d\n", remaining>>9);
+ DPRINT("weirdness: remaining %d\n", remaining>>9);
}
#endif
}
raw_cmd->length = current_count_sectors << 9;
if (raw_cmd->length == 0){
DPRINT("zero dma transfer attempted from make_raw_request\n");
- DPRINT3("indirect=%d direct=%d sector_t=%d",
+ DPRINT("indirect=%d direct=%d sector_t=%d",
indirect, direct, sector_t);
return 0;
}
aligned_sector_t < buffer_min)) ||
raw_cmd->length % (128 << SIZECODE) ||
raw_cmd->length <= 0 || current_count_sectors <= 0){
- DPRINT2("fractionary current count b=%lx s=%lx\n",
+ DPRINT("fractionary current count b=%lx s=%lx\n",
raw_cmd->length, current_count_sectors);
if (raw_cmd->kernel_data != CURRENT->buffer)
printk("addr=%d, length=%ld\n",
if (cmd != FDDEFPRM)
/* notice a disk change immediately, else
* we loose our settings immediately*/
- CALL(poll_drive(1,0));
+ CALL(poll_drive(1, FD_RAW_NEED_DISK));
user_params[drive] = *g;
if (buffer_drive == drive)
SUPBOUND(buffer_max, user_params[drive].sect);
return set_geometry(cmd, & inparam.g,
drive, type, device);
case FDGETPRM:
+ LOCK_FDC(drive,1);
+ CALL(poll_drive(1,0));
+ process_fd_request();
if (type)
outparam = (char *) &floppy_type[type];
else
default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
}
}
- DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
+ DPRINT("Assuming %s floppy hardware\n", param ? "standard" : "broken");
}
static void set_cmos(int *ints, int dummy)
FDC2 = 0x370;
if (ints[2] <= 0 ||
(ints[2] >= NUMBER(default_drive_params) && ints[2] != 16)){
- DPRINT1("bad cmos code %d\n", ints[2]);
+ DPRINT("bad cmos code %d\n", ints[2]);
return;
}
DP->cmos = ints[2];
- DPRINT1("setting cmos code to %d\n", ints[2]);
+ DPRINT("setting cmos code to %d\n", ints[2]);
}
static struct param_table {
if(config_params[i].fn)
config_params[i].fn(ints,param);
if(config_params[i].var) {
- DPRINT2("%s=%d\n", str, param);
+ DPRINT("%s=%d\n", str, param);
*config_params[i].var = param;
}
return;
}
}
if (str) {
- DPRINT1("unknown floppy option [%s]\n", str);
+ DPRINT("unknown floppy option [%s]\n", str);
DPRINT("allowed options are:");
for (i=0; i< ARRAY_SIZE(config_params); i++)
set_dor(0, ~0, 8); /* avoid immediate interrupt */
if (fd_request_irq()) {
- DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
+ DPRINT("Unable to grab IRQ%d for the floppy driver\n",
FLOPPY_IRQ);
return -1;
}
if (fd_request_dma()) {
- DPRINT1("Unable to grab DMA%d for the floppy driver\n",
+ DPRINT("Unable to grab DMA%d for the floppy driver\n",
FLOPPY_DMA);
fd_free_irq();
return -1;
* 3.10 Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
* 3.11 Apr 29, 1996 -- Patch from Heiko Eissfeldt <heiko@colossus.escape.de>
* to remove redundant verify_area calls.
+ * 3.12 May 7, 1996 -- Rudimentary changer support. Based on patches
+ * from Gerhard Zuber <zuber@berlin.snafu.de>.
+ * Let open succeed even if there's no loaded disc.
*
* NOTE: Direct audio reads will only work on some types of drive.
* So far, i've received reports of success for Sony and Toshiba drives.
*
+ * NOTE: The changer functions were tested with the NEC CDR-251 drive.
+ * They may not work with the Sanyo 3-cd changer, which i understand
+ * uses a different protocol.
+ *
* ATAPI cd-rom driver. To be used with ide.c.
*
* Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
#define MODE_SELECT_10 0x55
#define READ_CD 0xbe
+#define LOAD_UNLOAD 0xa6
+
/* ATAPI sense keys (mostly copied from scsi.h). */
}
+/* If SLOT<0, unload the current slot. Otherwise, try to load SLOT. */
+static int
+cdrom_load_unload (ide_drive_t *drive, unsigned long slot,
+ struct atapi_request_sense *reqbuf)
+{
+ struct packet_command pc;
+
+ memset (&pc, 0, sizeof (pc));
+ pc.sense_data = reqbuf;
+
+ pc.c[0] = LOAD_UNLOAD;
+ pc.c[4] = 2 + (slot >= 0);
+ pc.c[8] = slot;
+ return cdrom_queue_packet_command (drive, &pc);
+}
+
+
int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
struct file *file, unsigned int cmd, unsigned long arg)
{
return stat;
}
+ case CDROMLOADFROMSLOT: {
+ struct atapi_request_sense my_reqbuf;
+ int stat;
+
+ if (drive->usage > 1)
+ return -EBUSY;
+
+ stat = cdrom_load_unload (drive, -1, NULL);
+ if (stat) return stat;
+
+ cdrom_saw_media_change (drive);
+ if (arg == -1) {
+ (void) cdrom_lockdoor (drive, 0, NULL);
+ return 0;
+ }
+ stat = cdrom_load_unload (drive, arg, NULL);
+ if (stat) return stat;
+
+ stat = cdrom_check_status (drive, &my_reqbuf);
+ if (stat && my_reqbuf.sense_key == NOT_READY) {
+ return -ENOENT;
+ }
+
+ /* And try to read the TOC information now. */
+ return cdrom_read_toc (drive, &my_reqbuf);
+ }
+
#if 0 /* Doesn't work reliably yet. */
case CDROMRESET: {
struct request req;
stat = cdrom_check_status (drive, &my_reqbuf);
}
- /* Return an error if there are still problems. */
- if (stat && my_reqbuf.sense_key != UNIT_ATTENTION) {
- --drive->usage;
- return -ENXIO;
+ /* If things worked ok, lock the door and read the
+ TOC information. */
+ if (stat == 0 || my_reqbuf.sense_key == UNIT_ATTENTION) {
+ (void) cdrom_lockdoor (drive, 1, &my_reqbuf);
+ (void) cdrom_read_toc (drive, &my_reqbuf);
}
-
- /* Now lock the door. */
- (void) cdrom_lockdoor (drive, 1, &my_reqbuf);
-
- /* And try to read the TOC information now. */
- (void) cdrom_read_toc (drive, &my_reqbuf);
}
return 0;
* duplicated functionality between read and ioctl paths?
* Establish interfaces for an IDE port driver, and break out the cdrom
* code into a loadable module.
- * Support changers.
+ * Support changers better.
* Write some real documentation.
*/
/*
- * linux/drivers/block/ide.c Version 5.39 May 3, 1996
+ * linux/drivers/block/ide.c Version 5.41 May 9, 1996
*
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/
* mask drive irq after use, if sharing with another hwif
* add code to help debug weird cmd640 problems
* Version 5.39 fix horrible error in earlier irq sharing "fix"
+ * Version 5.40 fix serialization -- was broken in 5.39
+ * help sharing by masking device irq after probing
+ * Version 5.41 more fixes to irq sharing/serialize detection
+ * disable io_32bit by default on drive reset
*
* Some additional driver compile-time options are in ide.h
*
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk) {
if (!do_not_try_atapi) {
- if (!drive->keep_settings)
+ if (!drive->keep_settings) {
drive->unmask = 0;
+ drive->io_32bit = 0;
+ }
OUT_BYTE (drive->select.all, IDE_SELECT_REG);
udelay (20);
OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
if (!rdrive->keep_settings) {
rdrive->mult_req = 0;
rdrive->unmask = 0;
+ rdrive->io_32bit = 0;
if (rdrive->using_dma) {
rdrive->using_dma = 0;
printk("%s: disabled DMA\n", rdrive->name);
#if CONFIG_BLK_DEV_PROMISE
if (IS_PROMISE_DRIVE) {
- if(promise_cmd(drive,PROMISE_IDENTIFY))
+ if (promise_cmd(drive,PROMISE_IDENTIFY)) {
+ if (irqs)
+ (void) probe_irq_off(irqs);
return 1;
+ }
} else
#endif /* CONFIG_BLK_DEV_PROMISE */
OUT_BYTE(cmd,IDE_COMMAND_REG); /* ask drive for ID */
timeout += jiffies;
do {
if (jiffies > timeout) {
- if (!HWIF(drive)->irq)
+ if (irqs)
(void) probe_irq_off(irqs);
return 1; /* drive timed-out */
}
} else
rc = 2; /* drive refused ID */
if (!HWIF(drive)->irq) {
- irqs = probe_irq_off(irqs); /* get irq number */
- if (irqs > 0)
- HWIF(drive)->irq = irqs;
- else { /* Mmmm.. multiple IRQs */
+ irqs = probe_irq_off(irqs); /* get our irq number */
+ if (irqs > 0) {
+ HWIF(drive)->irq = irqs; /* save it for later */
+ irqs = probe_irq_on(); /* grab irqs, to ignore next edge */
+ OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
+ (void) probe_irq_off(irqs); /* restore irqs again */
+ } else { /* Mmmm.. multiple IRQs.. don't know which was ours */
printk("%s: IRQ probe failed (%d)\n", drive->name, irqs);
#ifdef CONFIG_BLK_DEV_CMD640
if (HWIF(drive)->chipset == ide_cmd640) {
return 1;
}
+#if MAX_HWIFS > 1
+/*
+ * save_match() is used to simplify logic in init_irq() below.
+ *
+ * A loophole here is that we may not know about a particular
+ * hwif's irq until after that hwif is actually probed/initialized..
+ * This could be a problem for the case where an hwif is on a
+ * dual interface that requires serialization (eg. cmd640) and another
+ * hwif using one of the same irqs is initialized beforehand.
+ *
+ * This routine detects and reports such situations, but does not fix them.
+ */
+static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
+{
+ ide_hwif_t *m = *match;
+
+ if (m && m->hwgroup && m->hwgroup != new->hwgroup) {
+ if (!new->hwgroup)
+ return;
+ printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name);
+ }
+ if (m->irq != hwif->irq) /* don't undo a prior perfect match */
+ *match = new;
+}
+#endif /* MAX_HWIFS > 1 */
/*
* This routine sets up the irq for an ide interface, and creates a new
* hwgroup for the irq/hwif if none was previously assigned.
*
+ * Much of the code is for correctly detecting/handling irq sharing
+ * and irq serialization situations. This is somewhat complex because
+ * it handles static as well as dynamic (PCMCIA) IDE interfaces.
+ *
* The SA_INTERRUPT in sa_flags means ide_intr() is always entered with
* interrupts completely disabled. This can be bad for interrupt latency,
* but anything else has led to problems on some machines. We re-enable
static int init_irq (ide_hwif_t *hwif)
{
unsigned long flags;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
- ide_hwif_t *mate_hwif;
- unsigned int index, mate_irq = hwif->irq;
+ unsigned int index;
+ ide_hwgroup_t *hwgroup;
+ ide_hwif_t *match = NULL;
save_flags(flags);
cli();
+ hwif->hwgroup = NULL;
+#if MAX_HWIFS > 1
/*
- * Handle serialization, regardless of init sequence
- */
- mate_hwif = &ide_hwifs[hwif->index ^ 1];
- if (hwif->serialized && mate_hwif->present)
- mate_irq = mate_hwif->irq;
-
- /*
- * Group up with any other hwifs that share our irq(s)
+ * Group up with any other hwifs that share our irq(s).
*/
for (index = 0; index < MAX_HWIFS; index++) {
- if (index != hwif->index) {
- ide_hwif_t *h = &ide_hwifs[index];
- if (h->irq == hwif->irq || h->irq == mate_irq) {
+ ide_hwif_t *h = &ide_hwifs[index];
+ if (h->hwgroup) { /* scan only initialized hwif's */
+ if (hwif->irq == h->irq) {
hwif->sharing_irq = h->sharing_irq = 1;
- if (hwgroup && !h->hwgroup)
- h->hwgroup = hwgroup;
- else if (!hwgroup)
- hwgroup = h->hwgroup;
+ save_match(hwif, h, &match);
+ }
+ if (hwif->serialized) {
+ ide_hwif_t *mate = &ide_hwifs[hwif->index^1];
+ if (index == mate->index || h->irq == mate->irq)
+ save_match(hwif, h, &match);
+ }
+ if (h->serialized) {
+ ide_hwif_t *mate = &ide_hwifs[h->index^1];
+ if (hwif->irq == mate->irq)
+ save_match(hwif, h, &match);
}
}
}
-
+#endif /* MAX_HWIFS > 1 */
/*
* If we are still without a hwgroup, then form a new one
*/
- if (hwgroup == NULL) {
- hwgroup = kmalloc (sizeof(ide_hwgroup_t), GFP_KERNEL);
+ if (match) {
+ hwgroup = match->hwgroup;
+ } else {
+ hwgroup = kmalloc(sizeof(ide_hwgroup_t), GFP_KERNEL);
hwgroup->hwif = hwgroup->next_hwif = hwif->next = hwif;
hwgroup->rq = NULL;
hwgroup->handler = NULL;
if (hwif->drives[0].present)
- hwgroup->drive = &hwif->drives[0];
+ hwgroup->drive = &hwif->drives[0];
else
- hwgroup->drive = &hwif->drives[1];
+ hwgroup->drive = &hwif->drives[1];
hwgroup->poll_timeout = 0;
init_timer(&hwgroup->timer);
hwgroup->timer.function = &timer_expiry;
/*
* Allocate the irq, if not already obtained for another hwif
*/
- if (!hwif->got_irq) {
+ if (!match || match->irq != hwif->irq) {
if (request_irq(hwif->irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name, hwgroup)) {
+ if (!match)
+ kfree(hwgroup);
restore_flags(flags);
return 1;
}
- for (index = 0; index < MAX_HWIFS; index++) {
- ide_hwif_t *g = &ide_hwifs[index];
- if (g->irq == hwif->irq)
- g->got_irq = 1;
- }
}
/*
printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
hwif->io_base, hwif->io_base+7, hwif->ctl_port, hwif->irq);
- if (hwgroup->hwif != hwif)
- printk(" (serialized with %s)", hwgroup->hwif->name);
+ if (match)
+ printk(" (%sed with %s)", hwif->sharing_irq ? "shar" : "serializ", match->name);
printk("\n");
return 0;
}
unsigned present : 1; /* this interface exists */
unsigned serialized : 1; /* serialized operation with mate hwif */
unsigned no_unmask : 1; /* disallow setting unmask bits */
- unsigned got_irq : 1; /* 1 = already alloc'd our irq */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
#ifdef CONFIG_BLK_DEV_PROMISE
unsigned is_promise2: 1; /* 2nd i/f on promise DC4030 */
#ifdef CONFIG_BLK_DEV_LOOP
loop_init();
#endif
+#ifdef CONFIG_CDI_INIT
+ cdi_init(); /* this MUST precede ide_init */
+#endif CONFIG_CDI_INIT
#ifdef CONFIG_BLK_DEV_IDE
ide_init(); /* this MUST precede hd_init */
#endif
#else
outb_p(0xc, 0x3f2);
#endif
-#ifdef CONFIG_CDI_INIT
- cdi_init();
-#endif CONFIG_CDI_INIT
#ifdef CONFIG_CDU31A
cdu31a_init();
#endif CONFIG_CDU31A
/*
- * linux/drivers/block/umc8672.c Version 0.03 Feb 09, 1996
+ * linux/drivers/block/umc8672.c Version 0.04 May 09, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & author (see below)
*/
* the results from the DOS speed test program supplied from UMC. 11 is the
* highest speed (about PIO mode 3)
*/
-#undef REALLY_SLOW_IO /* most systems can safely undef this */
+#define REALLY_SLOW_IO /* some systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
+Tue May 7 22:51:11 1996 <tytso@rsts-11.mit.edu>
+
+ * random.c (add_timer_randomness): Limit the amount randomness
+ that we estimate to 12 bits. (An arbitrary amount).
+
+ (extract_entropy): To make it harder to analyze the hash
+ function, fold the hash function in half using XOR, and
+ use the folded result as the value to emit to the user.
+ Also, add timer randomness each pass through the
+ exact_entropy call, to increase the amount of unknown
+ values during the extraction process.
+
+ (random_ioctl): Use IOR/IOW definitions to define the
+ ioctl values used by the /dev/random driver. Allow the
+ old ioctl values to be used for backwards compatibility
+ (for a limited amount of time).
+
+
Wed Apr 24 14:02:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* random.c (add_timer_randomness): Use 2nd derivative as well to
#include <asm/irq.h>
static struct mouse_status mouse;
+static int mouse_irq = MOUSE_IRQ;
+
+void msmouse_setup(char *str, int *ints)
+{
+ if (ints[0] > 0)
+ mouse_irq=ints[1];
+}
static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
return;
MS_MSE_INT_OFF();
mouse.ready = 0;
- free_irq(MOUSE_IRQ, NULL);
+ free_irq(mouse_irq, NULL);
MOD_DEC_USE_COUNT;
}
return -EINVAL;
if (mouse.active++)
return 0;
- if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse", NULL)) {
+ if (request_irq(mouse_irq, ms_mouse_interrupt, 0, "MS Busmouse", NULL)) {
mouse.active--;
return -EBUSY;
}
/*
* random.c -- A strong random number generator
*
- * Version 0.97, last modified 24-Apr-96
+ * Version 0.98, last modified 7-May-96
*
* Copyright Theodore Ts'o, 1994, 1995, 1996. All rights reserved.
*
* On the i386, this is assumed to be at most 16 bits, and the high bits
* are used for a high-resolution timer.
*
- * TODO: Read the time stamp register on the Pentium.
*/
static void add_timer_randomness(struct random_bucket *r,
struct timer_rand_state *state, unsigned num)
time = (__u32) low;
num ^= (__u32) high;
} else {
-#if 0
- /*
- * On a 386, read the high resolution timer. We assume that
- * this gives us 2 bits of randomness.
- *
- * This is turned off for now because of the speed hit
- * it entails.
- */
- outb_p(0x00, 0x43); /* latch the count ASAP */
- num |= inb_p(0x40) << 16;
- num |= inb(0x40) << 24;
- if (!state->dont_count_entropy)
- r->entropy_count += 2;
-#endif
-
time = jiffies;
}
#else
for (nbits = 0; delta; nbits++)
delta >>= 1;
+ /*
+ * In no case do we assume we've added more than 12
+ * bits of randomness.
+ */
+ if (nbits > 12)
+ nbits = 12;
+
r->entropy_count += nbits;
/* Prevent overflow */
{
int ret, i;
__u32 tmp[HASH_BUFFER_SIZE];
+ char *cp,*dp;
add_timer_randomness(r, &extract_timer_state, nbytes);
* add_entropy_word().
*/
HASH_TRANSFORM(tmp, r->pool);
+
+ /*
+ * In case the hash function has some recognizeable
+ * output pattern, we fold it half.
+ */
+ cp = (char *) tmp;
+ dp = cp + (HASH_BUFFER_SIZE*sizeof(__u32)) - 1;
+ for (i=0; i < HASH_BUFFER_SIZE*sizeof(__u32)/2; i++) {
+ *cp ^= *dp;
+ cp++; dp--;
+ }
/* Copy data to destination buffer */
- i = MIN(nbytes, HASH_BUFFER_SIZE*sizeof(__u32));
+ i = MIN(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2);
if (to_user)
memcpy_tofs(buf, (__u8 const *)tmp, i);
else
memcpy(buf, (__u8 const *)tmp, i);
nbytes -= i;
buf += i;
+ add_timer_randomness(r, &extract_timer_state, nbytes);
}
/* Wipe data from memory */
int *p, size, ent_count;
int retval;
+ /*
+ * Translate old 1.3.XX values.
+ * Remove this code in 2.1.0.
+ * <mec@duracef.shout.net>
+ */
+ switch (cmd) {
+ case 0x01080000: cmd = RNDGETENTCNT; break;
+ case 0x01080001: cmd = RNDADDTOENTCNT; break;
+ case 0x01080002: cmd = RNDGETPOOL; break;
+ case 0x01080003: cmd = RNDADDENTROPY; break;
+ case 0x01080004: cmd = RNDZAPENTCNT; break;
+ case 0x01080006: cmd = RNDCLEARPOOL; break;
+ }
+
switch (cmd) {
case RNDGETENTCNT:
retval = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
#endif
- /* overwrite warning occured, stop NIC & check the BOUNDARY pointer */
+ /* overwrite warning occurred, stop NIC & check the BOUNDARY pointer */
/* FIXME - real overwrite handling needed !! */
printk("hydra_interrupt(): overwrite warning, resetting NIC\n");
#define ISR_PTX 0x02 /* Packet transmitted without errors */
#define ISR_RXE 0x04 /* Receive error */
#define ISR_TXE 0x08 /* Transmit error */
-#define ISR_OVW 0x10 /* Ring buffer overrrun */
+#define ISR_OVW 0x10 /* Ring buffer overrun */
#define ISR_CNT 0x20 /* Counter overflow */
#define ISR_RDC 0x40 /* Remote DMA compile */
#define ISR_RST 0x80 /* Reset status */
bool ' allow DISCONNECT' CONFIG_SCSI_NCR53C7xx_DISCONNECT
fi
fi
-dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 $CONFIG_SCSI
+dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
dep_tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC $CONFIG_SCSI
dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
-/* $Id: advansys.c,v 1.12 1996/02/23 20:48:27 bobf Exp bobf $ */
+/* $Id: advansys.c,v 1.14 1996/05/10 00:26:31 bobf Exp bobf $ */
/*
* advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
*
* bobf@advansys.com (Bob Frey)
*/
-/* The driver has been tested with Linux v1.2.1 and v1.3.57 kernels. */
-#define ASC_VERSION "1.3" /* AdvanSys Driver Version */
+/* The driver has been tested with Linux v1.2.13 and v1.3.57 kernels. */
+#define ASC_VERSION "1.4" /* AdvanSys Driver Version */
/*
4. Eliminate 'make dep' warning.
5. Try to fix problem with handling resets by increasing their
timeout value.
+
+ 5/8/96 1.4:
+ 1. Change definitions to eliminate conflicts with other subsystems.
+ 2. Add versioning code for the shared interrupt changes.
+ 3. Eliminate problem in asc_rmqueue() with iterating after removing
+ a request.
+ 4. Remove reset request loop problem from the "Known Problems or
+ Issues" section. This problem was isolated and fixed in the
+ mid-level SCSI driver.
H. Known Problems or Issues
value is only changed on the first scsi command for each device
and never thereafter. The same change is made for reset commands.
- 3. The driver occasionally enters a loop handling reset requests. It
- isn't clear yet whether this is a bug in the upper or mid-level
- scsi modules or in this driver.
-
I. Credits
Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
#define ASC_LIB_SERIAL_NUMBER 53
typedef unsigned char uchar;
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-
-typedef int BOOL;
#ifndef NULL
#define NULL (0)
#define REG register
-#define rchar REG char
-#define rshort REG short
-#define rint REG int
-#define rlong REG long
+#define rchar REG __s8
+#define rshort REG __s16
+#define rint REG __s32
+#define rlong REG __s32
-#define ruchar REG uchar
-#define rushort REG ushort
-#define ruint REG uint
-#define rulong REG ulong
+#define ruchar REG __u8
+#define rushort REG __u16
+#define ruint REG __u32
+#define rulong REG __u32
#define NULLPTR ( void *)0
#define FNULLPTR ( void dosfar *)0UL
#define EOF (-1)
#define EOS '\0'
#define ERR (-1)
-#define UB_ERR (uchar)(0xFF)
-#define UW_ERR (uint)(0xFFFF)
-#define UL_ERR (ulong)(0xFFFFFFFFUL)
+#define UB_ERR (__u8)(0xFF)
+#define UW_ERR (__u16)(0xFFFF)
+#define UL_ERR (__u32)(0xFFFFFFFFUL)
-#define iseven_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) == 0 )
-#define isodd_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) != 0 )
-#define toeven_word( val ) ( ( ( uint )val ) & ( uint )0xFFFE )
+#define iseven_word( val ) ( ( ( ( __u16 )val) & ( __u16 )0x0001 ) == 0 )
+#define isodd_word( val ) ( ( ( ( __u16 )val) & ( __u16 )0x0001 ) != 0 )
+#define toeven_word( val ) ( ( ( __u16 )val ) & ( __u16 )0xFFFE )
-#define biton( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) != 0 )
-#define bitoff( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) == 0 )
-#define lbiton( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) != 0 )
-#define lbitoff( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) == 0 )
+#define biton( val, bits ) ((( __u16 )( val >> bits ) & (__u16)0x0001 ) != 0 )
+#define bitoff( val, bits ) ((( __u16 )( val >> bits ) & (__u16)0x0001 ) == 0 )
+#define lbiton( val, bits ) ((( __u32 )( val >> bits ) & (__u32)0x00000001UL ) != 0 )
+#define lbitoff( val, bits ) ((( __u32 )( val >> bits ) & (__u32)0x00000001UL ) == 0 )
#define absh( val ) ( ( val ) < 0 ? -( val ) : ( val ) )
#define KBYTE (0x400)
#endif
-#define HI_BYTE(x) ( *( ( BYTE *)(&x)+1 ) )
-#define LO_BYTE(x) ( *( ( BYTE *)&x ) )
+#define HI_BYTE(x) ( *( ( __u8 *)(&x)+1 ) )
+#define LO_BYTE(x) ( *( ( __u8 *)&x ) )
-#define HI_WORD(x) ( *( ( WORD *)(&x)+1 ) )
-#define LO_WORD(x) ( *( ( WORD *)&x ) )
+#define HI_WORD(x) ( *( ( __u16 *)(&x)+1 ) )
+#define LO_WORD(x) ( *( ( __u16 *)&x ) )
#ifndef MAKEWORD
-#define MAKEWORD(lo, hi) ((WORD) (((WORD) lo) | ((WORD) hi << 8)))
+#define MAKEWORD(lo, hi) ((__u16) (((__u16) lo) | ((__u16) hi << 8)))
#endif
#ifndef MAKELONG
-#define MAKELONG(lo, hi) ((DWORD) (((DWORD) lo) | ((DWORD) hi << 16)))
+#define MAKELONG(lo, hi) ((__u32) (((__u32) lo) | ((__u32) hi << 16)))
#endif
-#define SwapWords(dWord) ((DWORD) ((dWord >> 16) | (dWord << 16)))
-#define SwapBytes(word) ((WORD) ((word >> 8) | (word << 8)))
+#define SwapWords(dWord) ((__u32) ((dWord >> 16) | (dWord << 16)))
+#define SwapBytes(word) ((__u16) ((word >> 8) | (word << 8)))
#define BigToLittle(dWord) \
- ((DWORD) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
+ ((__u32) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
#define LittleToBig(dWord) BigToLittle(dWord)
#define Lptr
#ifdef LINUX_1_3
STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
#endif /* LINUX_1_3 */
+#ifdef LINUX_1_2
+STATIC void advansys_interrupt(int, struct pt_regs *);
+#else /* LINUX_1_3 */
STATIC void advansys_interrupt(int, void *, struct pt_regs *);
+#endif /* LINUX_1_3 */
STATIC void advansys_command_done(Scsi_Cmnd *);
STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *);
STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
/* Register IRQ Number. */
ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
+#ifdef LINUX_1_2
+ if ((ret = request_irq(shp->irq, advansys_interrupt,
+ SA_INTERRUPT, "advansys")) != 0) {
+#else /* LINUX_1_3 */
if ((ret = request_irq(shp->irq, advansys_interrupt,
SA_INTERRUPT, "advansys", NULL)) != 0) {
+#endif /* LINUX_1_3 */
ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
release_region(shp->io_port, shp->n_io_port);
if (shp->dma_channel != NO_ISA_DMA) {
if (shp->dma_channel != NO_ISA_DMA) {
free_dma(shp->dma_channel);
}
+#ifdef LINUX_1_2
+ free_irq(shp->irq);
+#else /* LINUX_1_3 */
free_irq(shp->irq, NULL);
+#endif /* LINUX_1_3 */
scsi_unregister(shp);
asc_board_count--;
continue;
advansys_release(struct Scsi_Host *shp)
{
ASC_DBG(1, "advansys_release: begin\n");
+#ifdef LINUX_1_2
+ free_irq(shp->irq);
+#else /* LINUX_1_3 */
free_irq(shp->irq, NULL);
+#endif /* LINUX_1_3 */
if (shp->dma_channel != NO_ISA_DMA) {
ASC_DBG(1, "advansys_release: free_dma()\n");
free_dma(shp->dma_channel);
* First-level interrupt handler.
*/
STATIC void
+#ifdef LINUX_1_2
+advansys_interrupt(int irq, struct pt_regs *regs)
+#else /* LINUX_1_3 */
advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#endif /* LINUX_1_3 */
{
int i;
int flags;
scp->host_scribble = NULL;
ASC_STATS(rmqueue);
ret = ASC_TRUE;
+ break; /* Note: Don't iterate, *scpp may be NULL. */
}
}
if (ASC_BOARD(shp)->pending[tid] == NULL) {
info_array[1]=32;
info_array[2]=disk->capacity / (64 * 32);
} else {
- info_array[0] = 256;
+ info_array[0] = 255;
info_array[1] = 63;
- info_array[2] = disk->capacity / (256 * 63);
+ info_array[2] = disk->capacity / (255 * 63);
if(info_array[2] > 1023)
info_array[2]=1023;
}
/*
* If we are using a ISA board, we can't use extended SG,
- * because we would need exessive amounts of memory for
+ * because we would need excessive amounts of memory for
* bounce buffers.
*/
if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){
*
*
* TODO:
- * proc interface. tagged queuing. multiple cards.
+ * tagged queuing. multiple cards.
*
*
* NOTE:
#include "hosts.h"
#include "in2000.h"
-#if LINUX_VERSION_CODE >= 0x010300
#include <linux/blk.h>
-#else
-#include "../block/blk.h"
-#endif
+#include <linux/stat.h>
#ifdef MODULE
#include <linux/module.h>
#endif
-#define PROC_INTERFACE /* add code for /proc/scsi/in2000/xxx interface */
-
-#define FAST_READ_IO /* No problems with these on my machine */
-#define FAST_WRITE_IO
+#define IN2000_VERSION "1.28"
+#define IN2000_DATE "07/May/1996"
+#define PROC_INTERFACE /* add code for /proc/scsi/in2000/xxx interface */
#define SYNC_DEBUG /* extra info on sync negotiation printed */
#define DEBUGGING_ON /* enable command-line debugging bitmask */
#define DEBUG_DEFAULTS 0 /* default bitmask - change from command-line */
-#define IN2000_VERSION "1.28"
-#define IN2000_DATE "27/Apr/1996"
+#define FAST_READ_IO /* No problems with these on my machine */
+#define FAST_WRITE_IO
#ifdef DEBUGGING_ON
#define DB(f,a) if (hostdata->args & (f)) a;
-#define CHECK_NULL(p,s) if (!(p)) {printk("\n"); while (1) printk("NP:%s\r",(s));}
+#define CHECK_NULL(p,s) /* if (!(p)) {printk("\n"); while (1) printk("NP:%s\r",(s));} */
#else
#define DB(f,a)
#define CHECK_NULL(p,s)
* re-think the multiple card capability....
*/
-#if LINUX_VERSION_CODE >= 0x010346 /* 1.3.70 */
void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs)
-#else
-void in2000_intr (int irqnum, struct pt_regs *ptregs)
-#endif
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
-#if LINUX_VERSION_CODE >= 0x010359 /* 1.3.89 */
int in2000_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
-#else
-int in2000_reset(Scsi_Cmnd *cmd)
-#endif
{
unsigned long flags;
struct Scsi_Host *instance;
-#if LINUX_VERSION_CODE >= 0x010300
-#include <linux/stat.h>
struct proc_dir_entry proc_scsi_in2000 = {
PROC_SCSI_IN2000, 6, "in2000",
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
-#endif
const unsigned int *bios_tab[] = {
if (check_setup_strings("ioport",&flags,&val,buf)) {
base = val;
switches = ~inb(base + IO_SWITCHES) & 0xff;
- printk("Forcing detection at IOport 0x%x.\n",base);
+ printk("Forcing IN2000 detection at IOport 0x%x ",base);
bios = 2;
}
else if (*(bios_tab[bios]+0x04) == 0x41564f4e ||
*(bios_tab[bios]+0x0c) == 0x61776c41) {
- printk("Found IN2000 BIOS at 0x%x.\n",(unsigned int)bios_tab[bios]);
+ printk("Found IN2000 BIOS at 0x%x ",(unsigned int)bios_tab[bios]);
/* Read the switch image that's mapped into EPROM space */
x = ~inb(base + IO_SWITCHES) & 0xff;
if (x != switches) {
- printk("Bad IO signature: %02x vs %02x\n",x,switches);
+ printk("Bad IO signature: %02x vs %02x.\n",x,switches);
continue;
}
}
* initialize it.
*/
-#if LINUX_VERSION_CODE >= 0x010300
tpnt->proc_dir = &proc_scsi_in2000; /* done more than once? harmless. */
-#endif
-
detect_count++;
instance = scsi_register(tpnt, sizeof(struct IN2000_hostdata));
if (!instance_list)
write1_io(0,IO_FIFO_READ); /* start fifo out in read mode */
write1_io(0,IO_INTR_MASK); /* allow all ints */
x = int_tab[(switches & (SW_INT0 | SW_INT1)) >> SW_INT_SHIFT];
-
-#if LINUX_VERSION_CODE >= 0x010346 /* 1.3.70 */
if (request_irq(x, in2000_intr, SA_INTERRUPT, "in2000", NULL)) {
-#else
- if (request_irq(x, in2000_intr, SA_INTERRUPT, "in2000")) {
-#endif
printk("in2000_detect: Unable to allocate IRQ.\n");
detect_count--;
continue;
disc_taken_total = 0;
#endif
-
if (check_setup_strings("nosync",&flags,&val,buf))
hostdata->sync_off = val;
if (check_setup_strings("debug",&flags,&val,buf))
hostdata->args = (val & DB_MASK);
- while (check_setup_strings("proc",&flags,&val,buf))
+ if (check_setup_strings("proc",&flags,&val,buf))
hostdata->proc = val;
x = reset_hardware(instance,(hostdata->args & A_NO_SCSI_RESET)?RESET_CARD:RESET_CARD_AND_BUS);
else
hostdata->chip = C_WD33C93;
- printk("in2000-%d: dip_switch=%02x: irq=%d ioport=%02x floppy=%s sync/DOS5=%s\n",
- instance->host_no,(switches & 0x7f),
+ printk("dip_switch=%02x irq=%d ioport=%02x floppy=%s sync/DOS5=%s ",
+ (switches & 0x7f),
instance->irq,hostdata->io_base,
(switches & SW_FLOPPY)?"Yes":"No",
(switches & SW_SYNC_DOS5)?"Yes":"No");
- printk("in2000-%d: hardware_ver=%02x chip=%s microcode=%02x\n",
- instance->host_no,hrev,
+ printk("hardware_ver=%02x chip=%s microcode=%02x\n",
+ hrev,
(hostdata->chip==C_WD33C93)?"WD33c93":
(hostdata->chip==C_WD33C93A)?"WD33c93A":
(hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
hostdata->microcode);
#ifdef DEBUGGING_ON
- printk("in2000-%d: setup_strings = ",instance->host_no);
+ printk("setup_strings = ");
for (x=0; x<8; x++)
printk("%s,",setup_strings[x]);
printk("\n");
#endif
if (hostdata->sync_off == 0xff)
- printk("in2000-%d: Sync-transfer DISABLED on all devices: ENABLE from command-line\n",instance->host_no);
- printk("in2000-%d: driver version %s - %s\n",instance->host_no,
- IN2000_VERSION,IN2000_DATE);
+ printk("Sync-transfer DISABLED on all devices: ENABLE from command-line\n");
+ printk("IN2000 driver version %s - %s\n",IN2000_VERSION,IN2000_DATE);
}
return detect_count;
* supposed to do...
*/
-#if LINUX_VERSION_CODE >= 0x010300
int in2000_biosparam(Disk *disk, kdev_t dev, int *iinfo)
-#else
-int in2000_biosparam(Disk *disk, int dev, int *iinfo)
-#endif
{
int size;
}
+#ifdef PROC_INTERFACE
+
+/* Certain older compilers (such as a.out 2.5.8) choke and give a
+ * "Too many reloads" error when there are a lot of calls to 'strcat()'
+ * in one function. Modern kernels define 'strcat()' as an inline
+ * function - I _guess_ this is related to the problem. Regardless,
+ * we can make everyone happy by doing some macro fudging to force
+ * gcc to do calls instead of inline expansion.
+ */
+
+char * in2000_strcat(char * dest, const char * src)
+{
+ return strcat(dest,src);
+}
+
+#define strcat(d,s) (in2000_strcat((d),(s)))
+
+#endif
+
+
int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
{
* in2000.h - Linux device driver definitions for the
* Always IN2000 ISA SCSI card.
*
- * IMPORTANT: This file is for version 1.28 - 27/Apr/1996
+ * IMPORTANT: This file is for version 1.28 - 07/May/1996
*
* Copyright (c) 1996 John Shifflett, GeoLog Consulting
* john@geolog.com
#include <asm/io.h>
-/* We include version.h to get 'LINUX_VERSION_CODE' - a define used here
- * and there in the source to get around various compatibility problems:
- * - pre-1.3.xx kernels didn't have 'kdev_t' or proc, and their
- * <blk.h> was in a different place.
- * - 1.3.70 introduced an additional argument for interrupt functions
- * - 1.3.89 added an argument to in2000_reset(), which we don't really
- * use at the moment. But for completeness...
- */
-#include <linux/version.h>
-
#define uchar unsigned char
void in2000_setup(char *, int *);
int in2000_proc_info(char *, char **, off_t, int, int, int);
struct proc_dir_entry proc_scsi_in2000;
-
-#if LINUX_VERSION_CODE >= 0x010300
int in2000_biosparam(struct scsi_disk *, kdev_t, int *);
-#else
-int in2000_biosparam(Disk *, int, int *);
-#endif
-#if LINUX_VERSION_CODE >= 0x010359 /* 1.3.89 */
int in2000_reset(Scsi_Cmnd *, unsigned int);
-#else
-int in2000_reset(Scsi_Cmnd *);
-#endif
#define IN2000_CAN_Q 16
#define IN2000_CPL 2
#define IN2000_HOST_ID 7
-#if LINUX_VERSION_CODE >= 0x010300
#define IN2000 { NULL, /* link pointer for modules */ \
NULL, /* usage_count for modules */ \
&proc_scsi_in2000, /* pointer to /proc/scsi directory entry */ \
DISABLE_CLUSTERING \
}
-#else
-#define IN2000 { NULL, /* link pointer for modules */ \
- NULL, /* usage_count for modules */ \
-/* NULL,*/ /* pointer to /proc/scsi directory entry */ \
-/* NULL,*/ /* pointer to proc info function */ \
- "Always IN2000", /* device name */ \
- in2000_detect, /* returns number of in2000's found */ \
- NULL, /* optional unload function for modules */ \
- NULL, /* optional misc info function */ \
- NULL, /* send scsi command, wait for completion */ \
- in2000_queuecommand, /* queue scsi command, don't wait */ \
- in2000_abort, /* abort current command */ \
- in2000_reset, /* reset scsi bus */ \
- NULL, /* slave_attach - unused */ \
- in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \
- IN2000_CAN_Q, /* max commands we can queue up */ \
- IN2000_HOST_ID, /* host-adapter scsi id */ \
- IN2000_SG, /* scatter-gather table size */ \
- IN2000_CPL, /* commands per lun */ \
- 0, /* board counter */ \
- 0, /* unchecked dma */ \
- DISABLE_CLUSTERING \
- }
-#endif
-
#endif /* IN2000_H */
-UPDATE NEWS: version 1.28 - 27 Apr 96
+UPDATE NEWS: version 1.28 - 07 May 96
Tightened up the "interrupts enabled/disabled" discipline
in 'in2000_queuecommand()' and maybe 1 or 2 other places.
advantage. In a single device system, or if only 1 device
is being accessed, transfers usually go faster if disconnects
are not allowed.
- Hackers -> the positions of some of the 'setup_default' flags
- have changed, so check your command-line args if
- you've been using them with a previous version.
-Hi everyone:
-
- A revamped IN2000 SCSI driver is available for download and
- testing at my ftp site:
-
- ftp.netcom.com/pub/js/jshiffle
-
- in the 'in2000' directory. It has what I think are a few
- improvements over the stock driver, including disconnect/
- reselect, synchronous transfer, easier debugging, command-
- line arguments for setting run-time parameters and debug
- output, and better FIFO handling. Swap partitions work now,
- as do tape drives and anything else that used to butt heads
- with the old driver's 2k block size limit. See the top
- of the 'in2000.c' file for more details.
-
- This is a rewrite of the in2000.[ch] files for Linux. They
- are drop-in replacements for the originals in linux/drivers/scsi
- - just copy them over the old ones. The driver has been tested
- in 1.2.13 with and without ELF, and in the 1.3 series somewhere
- up into the 60's. I don't expect any problems with newer kernels.
- It is "modular-ised" for those who prefer that route.
-
-------- Hackers take note: ------------------
-Anyone who wants to use LILO to pass a command line to this driver
-will have to make 2 small changes to the file 'init/main.c'. Find
-the area between lines 60-80 where all the 'xxxxx_setup()' extern
-declarations are and insert a new one like the following:
-
-extern void in2000_setup(char *str, int *ints);
-
-Then do a search for "bootsetups" - add a new entry to this array
-(somewhere in the middle) that looks like this:
-
-#ifdef CONFIG_SCSI_IN2000
- { "in2000=", in2000_setup },
-#endif
-
-[You can skip the above if you're only loading the driver as a module
- or if the driver defaults are OK.]
The default arguments (you get these when you don't give an 'in2000'
command-line argument, or you give a blank argument) will cause
------------------------------------------------
- I have run a LOT of tests on this driver, and it seems very solid,
- including with up to 3 simultaneous large copy or tar commands
- running between 6 devices at once. Synchronous transfers are
- working fine for the devices I have to test, although others have
- reported some failures (CDROM drives, mostly). Tape drives work
- well (finally!) and so do CD-ROM drives.
-
I should mention that Drew Eckhardt's 'Generic NCR5380' sources
were my main inspiration, with lots of reference to the IN2000
driver currently distributed in the kernel source. I also owe
much to a driver written by Hamish Macdonald for Linux-m68k(!).
And to Eric Wright for being an ALPHA guinea pig. And to Bill
Earnest for 2 tons of great input and information. And to David
- Willmore for extensive 'bonnie' testing.
-
- Be forewarned that while I've had good luck with it, this
- is the first time it's been loose out in the wide world.
- It wouldn't surprise me if people uncover problems that
- I haven't caught....
+ Willmore for extensive 'bonnie' testing. And to Joe Mack for
+ continual testing and feedback.
- Please try the driver out. Test it, beat on it. And PLEASE get back
- to me - I really need to hear about bugs, stupid or bad code,
- and any ideas for enhancements.
- Thanks very much...
John Shifflett jshiffle@netcom.com
endif
endif
+ifeq ($(CONFIG_BINFMT_JAVA),y)
+BINFMTS += binfmt_java.o
+else
+ ifeq ($(CONFIG_BINFMT_JAVA),m)
+ M_OBJS += binfmt_java.o
+ endif
+endif
+
# binfmt_script is always there
BINFMTS += binfmt_script.o
while (1) {
if (nextkey == 0)
break;
- pr_debug("AFFS: find_link_pred(): next key=%d\n", nextkey));
+ pr_debug("AFFS: find_link_pred(): next key=%d\n", nextkey);
if (!(bh = affs_bread(startino->i_dev,nextkey,AFFS_I2BSIZE(startino))))
break;
if (affs_checksum_block(AFFS_I2BSIZE(startino),bh->b_data,&ptype,&stype)
if (affs_parent_ino(old_inode) != old_dir->i_ino)
goto end_rename;
}
- /* Unlink destination if existant */
+ /* Unlink destination if existent */
if (new_inode) {
if ((retval = affs_fix_hash_pred(new_dir,affs_hash_name(new_name,new_len,
AFFS_I2FSTYPE(new_dir),AFFS_I2HSIZE(new_dir)) + 6,
--- /dev/null
+/*
+ * linux/fs/binfmt_java.c
+ *
+ * Copyright (C) 1996 Brian A. Lantz
+ * derived from binfmt_script.c
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/malloc.h>
+#include <linux/binfmts.h>
+#include <paths.h>
+
+#define _PATH_JAVA "/usr/local/java/bin/java"
+#define _PATH_APPLET "/usr/local/java/bin/appletviewer"
+#define _PATH_BASH "/bin/bash"
+
+static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ char *cp, *interp, *i_name;
+ int retval;
+ unsigned char *ucp = (unsigned char *) bprm->buf;
+ if ((ucp[0] != 0xca) || (ucp[1] != 0xfe) || (ucp[2] != 0xba) || (ucp[3] != 0xbe))
+ return -ENOEXEC;
+
+ 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_BASH)
+ * (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'
+ *
+ * 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;
+ if ((i_name = strrchr (bprm->filename, '/')) != NULL)
+ i_name++;
+ else
+ i_name = bprm->filename;
+ bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
+ bprm->argc++;
+
+ strcpy (bprm->buf, _PATH_JAVA);
+ cp = bprm->buf;
+ bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
+ bprm->argc++;
+
+ strcpy (bprm->buf, _PATH_BASH);
+ interp = bprm->buf;
+ if ((i_name = strrchr (bprm->buf, '/')) != NULL)
+ i_name++;
+ else
+ i_name = bprm->buf;
+ 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);
+ if (retval)
+ return retval;
+ bprm->dont_iput=0;
+ retval=prepare_binprm(bprm);
+ if(retval<0)
+ return retval;
+
+ return search_binary_handler(bprm,regs);
+}
+
+static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ char *cp, *interp, *i_name;
+ int retval;
+ if (strncmp (bprm->buf, "<!--applet", 10))
+ return -ENOEXEC;
+
+ 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_BSHELL)
+ * (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET)
+ * (3) filename of html file (replace argv[0])
+ *
+ * This is done in reverse order, because of how the
+ * user environment and arguments are stored.
+ */
+ remove_arg_zero(bprm);
+ i_name = bprm->filename;
+ bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
+ bprm->argc++;
+
+ strcpy (bprm->buf, _PATH_APPLET);
+ cp = bprm->buf;
+ bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
+ bprm->argc++;
+
+ strcpy (bprm->buf, _PATH_BSHELL);
+ interp = bprm->buf;
+ if ((i_name = strrchr (bprm->buf, '/')) != NULL)
+ i_name++;
+ else
+ i_name = bprm->buf;
+ 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);
+ if (retval)
+ return retval;
+ bprm->dont_iput=0;
+ retval=prepare_binprm(bprm);
+ if(retval<0)
+ return retval;
+
+ return search_binary_handler(bprm,regs);
+}
+
+static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ int retval;
+ MOD_INC_USE_COUNT;
+ retval = do_load_script(bprm,regs);
+ MOD_DEC_USE_COUNT;
+ return retval;
+}
+
+struct linux_binfmt java_format = {
+#ifndef MODULE
+ NULL, 0, load_script, NULL, NULL
+#else
+ NULL, &mod_use_count_, load_script, NULL, NULL
+#endif
+};
+
+static int load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ int retval;
+ MOD_INC_USE_COUNT;
+ retval = do_load_applet(bprm,regs);
+ MOD_DEC_USE_COUNT;
+ return retval;
+}
+
+struct linux_binfmt applet_format = {
+#ifndef MODULE
+ NULL, 0, load_applet, NULL, NULL
+#else
+ NULL, &mod_use_count_, load_applet, NULL, NULL
+#endif
+};
+
+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);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+ return init_java_binfmt();
+}
+
+void cleanup_module( void) {
+ printk(KERN_INFO "Removing JAVA Binary support...\n");
+ unregister_binfmt(&java_format);
+ unregister_binfmt(&applet_format);
+}
+#endif
#ifdef CONFIG_BINFMT_AOUT
init_aout_binfmt();
#endif
+
+#ifdef CONFIG_BINFMT_JAVA
+ init_java_binfmt();
+#endif
/* This cannot be configured out of the kernel */
init_script_binfmt();
}
int block)
{
struct buffer_head *ret = NULL;
- if (sb->s_blocksize == 512){
-/* ret = bread (sb->s_dev,block,512); */
- ret = breada (sb->s_dev,block,512,0,18*1024);
- }else{
-/* struct buffer_head *real = bread (sb->s_dev,block>>1,1024); */
- struct buffer_head *real = breada (sb->s_dev,block>>1,1024,0,18*1024);
+
+ /* Note that the blocksize is 512 or 1024, but the first read
+ is always of size 1024. Doing readahead may be counterproductive
+ or just plain wrong. */
+ if (sb->s_blocksize == 512) {
+ ret = bread (sb->s_dev,block,512);
+ } else {
+ struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
+
if (real != NULL){
- ret = (struct buffer_head *)kmalloc (sizeof(struct buffer_head)
- ,GFP_KERNEL);
- if (ret != NULL){
+ ret = (struct buffer_head *)
+ kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
+ if (ret != NULL) {
/* #Specification: msdos / strategy / special device / dummy blocks
Many special device (Scsi optical disk for one) use
larger hardware sector size. This allows for higher
{
struct buffer_head *bh,*bh2,*c_bh,*c_bh2;
unsigned char *p_first,*p_last;
- int first,last,next,copy;
+ int first,last,next,copy,b;
- if ((unsigned) (nr-2) >= MSDOS_SB(sb)->clusters) return 0;
- if (MSDOS_SB(sb)->fat_bits == 16) first = last = nr*2;
- else {
+ if ((unsigned) (nr-2) >= MSDOS_SB(sb)->clusters)
+ return 0;
+ if (MSDOS_SB(sb)->fat_bits == 16) {
+ first = last = nr*2;
+ } else {
first = nr*3/2;
last = first+1;
}
- if (!(bh = breada(sb->s_dev,MSDOS_SB(sb)->fat_start+(first >>
- SECTOR_BITS),SECTOR_SIZE,0,FAT_READAHEAD))) {
- printk("breada in fat_access failed\n");
+ b = MSDOS_SB(sb)->fat_start + (first >> SECTOR_BITS);
+ if (!(bh = fat_bread(sb, b))) {
+ printk("bread in fat_access failed\n");
return 0;
}
- if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS))
+ if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS)) {
bh2 = bh;
- else {
- if (!(bh2 = breada(sb->s_dev,MSDOS_SB(sb)->fat_start+(last
- >> SECTOR_BITS),SECTOR_SIZE,0,FAT_READAHEAD))) {
- brelse(bh);
- printk("breada in fat_access failed\n");
+ } else {
+ if (!(bh2 = fat_bread(sb, b+1))) {
+ fat_brelse(sb, bh);
+ printk("2nd bread in fat_access failed\n");
return 0;
}
}
*p_first = new_value & 0xff;
*p_last = (*p_last & 0xf0) | (new_value >> 8);
}
- mark_buffer_dirty(bh2, 1);
+ fat_mark_buffer_dirty(sb, bh2, 1);
}
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) {
- if (!(c_bh = breada(sb->s_dev,MSDOS_SB(sb)->
- fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)->
- fat_length*copy,SECTOR_SIZE,0,FAT_READAHEAD))) break;
+ b = MSDOS_SB(sb)->fat_start + (first >> SECTOR_BITS) +
+ MSDOS_SB(sb)->fat_length * copy;
+ if (!(c_bh = fat_bread(sb, b)))
+ break;
memcpy(c_bh->b_data,bh->b_data,SECTOR_SIZE);
- mark_buffer_dirty(c_bh, 1);
+ fat_mark_buffer_dirty(sb, c_bh, 1);
if (bh != bh2) {
- if (!(c_bh2 = breada(sb->s_dev,
- MSDOS_SB(sb)->fat_start+(first >>
- SECTOR_BITS)+MSDOS_SB(sb)->fat_length*copy
- +1,SECTOR_SIZE,0,FAT_READAHEAD))) {
- brelse(c_bh);
+ if (!(c_bh2 = fat_bread(sb, b+1))) {
+ fat_brelse(sb, c_bh);
break;
}
memcpy(c_bh2->b_data,bh2->b_data,SECTOR_SIZE);
- brelse(c_bh2);
+ fat_brelse(sb, c_bh2);
}
- brelse(c_bh);
+ fat_brelse(sb, c_bh);
}
}
- brelse(bh);
- if (bh != bh2) brelse(bh2);
+ fat_brelse(sb, bh);
+ if (bh != bh2)
+ fat_brelse(sb, bh2);
return next;
}
}
ino = fat_get_entry(inode,&filp->f_pos,&bh,&de);
}
- if (bh) brelse(bh);
+ if (bh)
+ fat_brelse(sb, bh);
if (unicode) {
free_page((unsigned long) unicode);
}
static void fat_prefetch (
struct inode *inode,
struct fat_pre *pre,
- int nb) /* How many must be prefetch at once */
+ int nb) /* How many must we prefetch at once */
{
struct super_block *sb = inode->i_sb;
struct buffer_head *bhreq[MSDOS_PREFETCH]; /* Buffers not */
- /* already read */
- int nbreq=0; /* Number of buffers in bhreq */
+ /* already read */
+ int nbreq = 0; /* Number of buffers in bhreq */
int i;
for (i=0; i<nb; i++){
int sector = fat_smap(inode,pre->file_sector);
struct buffer_head *bh;
PRINTK (("fsector2 %d -> %d\n",pre->file_sector-1,sector));
pre->file_sector++;
- bh = getblk(inode->i_dev,sector,SECTOR_SIZE);
+ bh = fat_getblk(sb, sector);
if (bh == NULL) break;
pre->bhlist[pre->nblist++] = bh;
- if (!fat_is_uptodate(sb,bh)) bhreq[nbreq++] = bh;
+ if (!fat_is_uptodate(sb,bh))
+ bhreq[nbreq++] = bh;
}else{
break;
}
wait_on_buffer(bh);
if (!fat_is_uptodate(sb,bh)){
/* read error ? */
- brelse (bh);
+ fat_brelse (sb, bh);
break;
}
offset = filp->f_pos & (SECTOR_SIZE-1);
}
}
}
- brelse(bh);
+ fat_brelse(sb, bh);
}
PRINTK (("--- %d -> %d\n",count,(int)(buf-start)));
- for (i=0; i<pre.nblist; i++) brelse (pre.bhlist[i]);
- if (start == buf) return -EIO;
- if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
+ for (i=0; i<pre.nblist; i++)
+ fat_brelse (sb, pre.bhlist[i]);
+ if (start == buf)
+ return -EIO;
+ if (!IS_RDONLY(inode))
+ inode->i_atime = CURRENT_TIME;
filp->f_reada = 1; /* Will be reset if a lseek is done */
return buf-start;
}
printk("fat_file_write: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
- /* system files are immutable */
- if (IS_IMMUTABLE(inode)) return -EPERM;
+ /* system files may be immutable */
+ if (IS_IMMUTABLE(inode))
+ return -EPERM;
/*
* ok, append may not work when many processes are writing at the same time
* but so what. That way leads to madness anyway.
*/
- if (filp->f_flags & O_APPEND) filp->f_pos = inode->i_size;
- if (count <= 0) return 0;
+ if (filp->f_flags & O_APPEND)
+ filp->f_pos = inode->i_size;
+ if (count <= 0)
+ return 0;
error = carry = 0;
for (start = buf; count || carry; count -= size) {
while (!(sector = fat_smap(inode,filp->f_pos >> SECTOR_BITS)))
/* No need to read the block first since we will */
/* completely overwrite it */
/* or at least write past the end of file */
- if (!(bh = getblk(inode->i_dev,sector,SECTOR_SIZE))){
+ if (!(bh = fat_getblk(sb,sector))){
error = -EIO;
break;
}
- }else if (!(bh = bread(inode->i_dev,sector,SECTOR_SIZE))) {
+ } else if (!(bh = fat_bread(sb,sector))) {
error = -EIO;
break;
}
if (binary_mode) {
memcpy_fromfs(bh->b_data+offset,buf,written = size);
buf += size;
- }
- else {
+ } else {
written = left = SECTOR_SIZE-offset;
to = (char *) bh->b_data+(filp->f_pos & (SECTOR_SIZE-1));
if (carry) {
inode->i_size = filp->f_pos;
inode->i_dirt = 1;
}
- fat_set_uptodate(sb,bh,1);
- mark_buffer_dirty(bh, 0);
- brelse(bh);
+ fat_set_uptodate(sb, bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 0);
+ fat_brelse(sb, bh);
}
if (start == buf)
return error;
int cluster;
/* Why no return value? Surely the disk could fail... */
- if (IS_IMMUTABLE(inode)) return /* -EPERM */;
+ if (IS_IMMUTABLE(inode))
+ return /* -EPERM */;
cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
(void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
/* The first read is always 1024 bytes */
sb->s_blocksize = 1024;
set_blocksize(sb->s_dev, 1024);
- bh = bread(sb->s_dev, 0, 1024);
+ bh = fat_bread(sb, 0);
unlock_super(sb);
if (bh == NULL || !fat_is_uptodate(sb,bh)) {
- brelse (bh);
+ fat_brelse (sb, bh);
sb->s_dev = 0;
printk("FAT bread failed\n");
MOD_DEC_USE_COUNT;
MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
|| !b->secs_track || !b->heads;
}
- brelse(bh);
+ fat_brelse(sb, bh);
/*
This must be done after the brelse because the bh is a dummy
allocated by fat_bread (see buffer.c)
*/
- sb->s_blocksize = blksize; /* Using this small block size solve the */
+ sb->s_blocksize = blksize; /* Using this small block size solves */
/* the misfit with buffer cache and cluster */
- /* because cluster (DOS) are often aligned */
- /* on odd sector */
+ /* because clusters (DOS) are often aligned */
+ /* on odd sectors. */
sb->s_blocksize_bits = blksize == 512 ? 9 : 10;
if (error || debug) {
/* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
struct msdos_dir_entry *raw_entry;
int nr;
-/* printk("read inode %d\n",inode->i_ino); */
MSDOS_I(inode)->i_busy = 0;
MSDOS_I(inode)->i_depend = MSDOS_I(inode)->i_old = NULL;
MSDOS_I(inode)->i_linked = MSDOS_I(inode)->i_oldlink = NULL;
MSDOS_I(inode)->i_binary = 1;
- inode->i_uid = MSDOS_SB(inode->i_sb)->options.fs_uid;
- inode->i_gid = MSDOS_SB(inode->i_sb)->options.fs_gid;
+ inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
+ inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
inode->i_version = ++event;
if (inode->i_ino == MSDOS_ROOT_INO) {
- inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(inode->i_sb)->options.fs_umask) |
+ inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(sb)->options.fs_umask) |
S_IFDIR;
inode->i_op = fs_dir_inode_ops;
inode->i_nlink = fat_subdirs(inode)+2;
/* subdirs (neither . nor ..) plus . and "self" */
- inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries*
+ inode->i_size = MSDOS_SB(sb)->dir_entries*
sizeof(struct msdos_dir_entry);
- inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size*
+ inode->i_blksize = MSDOS_SB(sb)->cluster_size*
SECTOR_SIZE;
inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
- inode->i_blksize*MSDOS_SB(inode->i_sb)->cluster_size;
+ inode->i_blksize*MSDOS_SB(sb)->cluster_size;
MSDOS_I(inode)->i_start = 0;
MSDOS_I(inode)->i_attrs = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
return;
}
- if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS,
- SECTOR_SIZE))) {
+ if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
printk("dev = %s, ino = %ld\n",
kdevname(inode->i_dev), inode->i_ino);
panic("fat_read_inode: unable to read i-node block");
[inode->i_ino & (MSDOS_DPB-1)];
if ((raw_entry->attr & ATTR_DIR) && !IS_FREE(raw_entry->name)) {
inode->i_mode = MSDOS_MKMODE(raw_entry->attr,S_IRWXUGO &
- ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IFDIR;
+ ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
inode->i_op = fs_dir_inode_ops;
MSDOS_I(inode)->i_start = CF_LE_W(raw_entry->start);
while (nr != -1) {
inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->
i_sb)->cluster_size;
- if (!(nr = fat_access(inode->i_sb,nr,-1))) {
+ if (!(nr = fat_access(sb,nr,-1))) {
printk("Directory %ld: bad FAT\n",
inode->i_ino);
break;
} else { /* not a directory */
inode->i_mode = MSDOS_MKMODE(raw_entry->attr,
((IS_NOEXEC(inode) ||
- (MSDOS_SB(inode->i_sb)->options.showexec &&
+ (MSDOS_SB(sb)->options.showexec &&
!is_exec(raw_entry->ext)))
? S_IRUGO|S_IWUGO : S_IRWXUGO)
- & ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IFREG;
+ & ~MSDOS_SB(sb)->options.fs_umask) | S_IFREG;
inode->i_op = (sb->s_blocksize == 1024)
? &fat_file_inode_operations_1024
: &fat_file_inode_operations;
inode->i_size = CF_LE_L(raw_entry->size);
}
if(raw_entry->attr & ATTR_SYS)
- if (MSDOS_SB(inode->i_sb)->options.sys_immutable)
+ if (MSDOS_SB(sb)->options.sys_immutable)
inode->i_flags |= S_IMMUTABLE;
- MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(inode->i_sb)->options.conversion,
+ MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(sb)->options.conversion,
raw_entry->ext);
MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED;
/* this is as close to the truth as we can get ... */
- inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size*SECTOR_SIZE;
+ inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
- inode->i_blksize*MSDOS_SB(inode->i_sb)->cluster_size;
+ inode->i_blksize*MSDOS_SB(sb)->cluster_size;
inode->i_mtime = inode->i_atime =
date_dos2unix(CF_LE_W(raw_entry->time),CF_LE_W(raw_entry->date));
inode->i_ctime =
- MSDOS_SB(inode->i_sb)->options.isvfat
+ MSDOS_SB(sb)->options.isvfat
? date_dos2unix(CF_LE_W(raw_entry->ctime),CF_LE_W(raw_entry->cdate))
: inode->i_mtime;
- brelse(bh);
+ fat_brelse(sb, bh);
}
inode->i_dirt = 0;
if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
- if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS,
- SECTOR_SIZE))) {
+ if (!(bh = fat_bread(sb, inode->i_ino >> MSDOS_DPB_BITS))) {
printk("dev = %s, ino = %ld\n",
kdevname(inode->i_dev), inode->i_ino);
panic("msdos_write_inode: unable to read i-node block");
raw_entry->ctime = CT_LE_W(raw_entry->ctime);
raw_entry->cdate = CT_LE_W(raw_entry->cdate);
}
- mark_buffer_dirty(bh, 1);
- brelse(bh);
+ fat_mark_buffer_dirty(sb, bh, 1);
+ fat_brelse(sb, bh);
}
int fat_notify_change(struct inode * inode,struct iattr * attr)
{
+ struct super_block *sb = inode->i_sb;
int error;
error = inode_change_ok(inode, attr);
if (error)
- return MSDOS_SB(inode->i_sb)->options.quiet ? 0 : error;
+ return MSDOS_SB(sb)->options.quiet ? 0 : error;
if (((attr->ia_valid & ATTR_UID) &&
- (attr->ia_uid != MSDOS_SB(inode->i_sb)->options.fs_uid)) ||
+ (attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) ||
((attr->ia_valid & ATTR_GID) &&
- (attr->ia_gid != MSDOS_SB(inode->i_sb)->options.fs_gid)) ||
+ (attr->ia_gid != MSDOS_SB(sb)->options.fs_gid)) ||
((attr->ia_valid & ATTR_MODE) &&
(attr->ia_mode & ~MSDOS_VALID_MODE)))
error = -EPERM;
if (error)
- return MSDOS_SB(inode->i_sb)->options.quiet ? 0 : error;
+ return MSDOS_SB(sb)->options.quiet ? 0 : error;
inode_setattr(inode, attr);
inode->i_mode |= S_IXUGO;
inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
- & ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
- ~MSDOS_SB(inode->i_sb)->options.fs_umask;
+ & ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
+ ~MSDOS_SB(sb)->options.fs_umask;
return 0;
}
struct super_block *sb = inode->i_sb;
int count,nr,limit,last,curr,sector,last_sector,file_cluster;
struct buffer_head *bh;
- int cluster_size = MSDOS_SB(inode->i_sb)->cluster_size;
+ int cluster_size = MSDOS_SB(sb)->cluster_size;
if (inode->i_ino == MSDOS_ROOT_INO) return -ENOSPC;
- if (!MSDOS_SB(inode->i_sb)->free_clusters) return -ENOSPC;
- lock_fat(inode->i_sb);
- limit = MSDOS_SB(inode->i_sb)->clusters;
+ if (!MSDOS_SB(sb)->free_clusters) return -ENOSPC;
+ lock_fat(sb);
+ limit = MSDOS_SB(sb)->clusters;
nr = limit; /* to keep GCC happy */
for (count = 0; count < limit; count++) {
- nr = ((count+MSDOS_SB(inode->i_sb)->prev_free) % limit)+2;
- if (fat_access(inode->i_sb,nr,-1) == 0) break;
+ nr = ((count+MSDOS_SB(sb)->prev_free) % limit)+2;
+ if (fat_access(sb,nr,-1) == 0) break;
}
PRINTK (("cnt = %d --",count));
#ifdef DEBUG
printk("free cluster: %d\n",nr);
#endif
- MSDOS_SB(inode->i_sb)->prev_free = (count+MSDOS_SB(inode->i_sb)->
- prev_free+1) % limit;
+ MSDOS_SB(sb)->prev_free = (count+MSDOS_SB(sb)->prev_free+1) % limit;
if (count >= limit) {
- MSDOS_SB(inode->i_sb)->free_clusters = 0;
- unlock_fat(inode->i_sb);
+ MSDOS_SB(sb)->free_clusters = 0;
+ unlock_fat(sb);
return -ENOSPC;
}
- fat_access(inode->i_sb,nr,MSDOS_SB(inode->i_sb)->fat_bits == 12 ?
+ fat_access(sb,nr,MSDOS_SB(sb)->fat_bits == 12 ?
0xff8 : 0xfff8);
- if (MSDOS_SB(inode->i_sb)->free_clusters != -1)
- MSDOS_SB(inode->i_sb)->free_clusters--;
- unlock_fat(inode->i_sb);
+ if (MSDOS_SB(sb)->free_clusters != -1)
+ MSDOS_SB(sb)->free_clusters--;
+ unlock_fat(sb);
#ifdef DEBUG
-printk("set to %x\n",fat_access(inode->i_sb,nr,-1));
+printk("set to %x\n",fat_access(sb,nr,-1));
#endif
last = 0;
/* We must locate the last cluster of the file to add this
while (curr && curr != -1){
PRINTK (("."));
file_cluster++;
- if (!(curr = fat_access(inode->i_sb,
+ if (!(curr = fat_access(sb,
last = curr,-1))) {
- fat_fs_panic(inode->i_sb,"File without EOF");
+ fat_fs_panic(sb,"File without EOF");
return -ENOSPC;
}
}
#ifdef DEBUG
printk("last = %d\n",last);
#endif
- if (last) fat_access(inode->i_sb,last,nr);
+ if (last) fat_access(sb,last,nr);
else {
MSDOS_I(inode)->i_start = nr;
inode->i_dirt = 1;
}
#ifdef DEBUG
-if (last) printk("next set to %d\n",fat_access(inode->i_sb,last,-1));
+if (last) printk("next set to %d\n",fat_access(sb,last,-1));
#endif
- sector = MSDOS_SB(inode->i_sb)->data_start+(nr-2)*cluster_size;
+ sector = MSDOS_SB(sb)->data_start+(nr-2)*cluster_size;
last_sector = sector + cluster_size;
for ( ; sector < last_sector; sector++) {
#ifdef DEBUG
printk("zeroing sector %d\n",sector);
#endif
- if (!(bh = getblk(inode->i_dev,sector,SECTOR_SIZE)))
+ if (!(bh = fat_getblk(sb, sector)))
printk("getblk failed\n");
else {
memset(bh->b_data,0,SECTOR_SIZE);
- fat_set_uptodate(sb,bh,1);
- mark_buffer_dirty(bh, 1);
- brelse(bh);
+ fat_set_uptodate(sb, bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
+ fat_brelse(sb, bh);
}
}
if (file_cluster != inode->i_blocks/cluster_size){
inode->i_blocks += cluster_size;
if (S_ISDIR(inode->i_mode)) {
if (inode->i_size & (SECTOR_SIZE-1)) {
- fat_fs_panic(inode->i_sb,"Odd directory size");
+ fat_fs_panic(sb,"Odd directory size");
inode->i_size = (inode->i_size+SECTOR_SIZE) &
~(SECTOR_SIZE-1);
}
struct msdos_dir_entry **de)
{
struct super_block *sb = dir->i_sb;
- int sector,offset;
+ int sector, offset;
while (1) {
offset = *pos;
return -1; /* beyond EOF */
*pos += sizeof(struct msdos_dir_entry);
if (*bh)
- brelse(*bh);
+ fat_brelse(sb, *bh);
PRINTK (("get_entry sector apres brelse\n"));
- if (!(*bh = breada(dir->i_dev,sector,SECTOR_SIZE,0,FAT_READAHEAD))) {
+ if (!(*bh = fat_bread(sb, sector))) {
printk("Directory sread (sector %d) failed\n",sector);
continue;
}
struct inode *inode;
int entry,start,done;
- if (!(bh = breada(sb->s_dev,sector,SECTOR_SIZE,0,FAT_READAHEAD))) return -EIO;
+ if (!(bh = fat_bread(sb,sector)))
+ return -EIO;
data = (struct msdos_dir_entry *) bh->b_data;
for (entry = 0; entry < MSDOS_DPS; entry++) {
/* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
if (done) {
if (ino) *ino = sector*MSDOS_DPS+entry;
start = CF_LE_W(data[entry].start);
- if (!res_bh) brelse(bh);
+ if (!res_bh)
+ fat_brelse(sb, bh);
else {
*res_bh = bh;
*res_de = &data[entry];
return start;
}
}
- brelse(bh);
+ fat_brelse(sb, bh);
return -ENOENT;
}
int fat_is_uptodate (struct super_block *sb, struct buffer_head *bh);
void fat_ll_rw_block (struct super_block *sb, int opr,
int nbreq, struct buffer_head *bh[32]);
-
-/* These macros exist to avoid modifying all the code */
-/* They should be removed one day I guess */
-
-/* The versioning mechanism of the modules system defines those macros */
-/* This removes some warnings */
-#ifdef brelse
- #undef brelse
-#endif
-#ifdef bread
- #undef bread
-#endif
-#ifdef getblk
- #undef getblk
-#endif
-
-#define brelse(b) fat_brelse(sb,b)
-#define bread(d,b,s) fat_bread(sb,b)
-#define getblk(d,b,s) fat_getblk(sb,b)
-#define mark_buffer_dirty(b,v) fat_mark_buffer_dirty(sb,b,v)
-
return res;
}
PRINTK (("msdos_lookup 4\n"));
- if (bh) brelse(bh);
+ if (bh)
+ fat_brelse(sb, bh);
PRINTK (("msdos_lookup 4.5\n"));
-/* printk("lookup: ino=%d\n",ino); */
if (!(*result = iget(dir->i_sb,ino))) {
iput(dir);
return -EACCES;
de->start = 0;
fat_date_unix2dos(dir->i_mtime,&de->time,&de->date);
de->size = 0;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
if ((*result = iget(dir->i_sb,ino)) != NULL)
msdos_read_inode(*result);
- brelse(bh);
+ fat_brelse(sb, bh);
if (!*result) return -EIO;
(*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime =
CURRENT_TIME;
*/
if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_HID) >= 0) {
fat_unlock_creation();
- brelse(bh);
+ fat_brelse(sb, bh);
iput(dir);
return is_hid ? -EEXIST : -EINVAL;
}
if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_NOTHID) >= 0) {
fat_unlock_creation();
- brelse(bh);
+ fat_brelse(sb, bh);
iput(dir);
return is_hid ? -EINVAL : -EEXIST;
}
if (!IS_FREE(de->name) && strncmp(de->name,MSDOS_DOT,
MSDOS_NAME) && strncmp(de->name,MSDOS_DOTDOT,
MSDOS_NAME)) {
- brelse(bh);
+ fat_brelse(sb, bh);
return -ENOTEMPTY;
}
if (bh)
- brelse(bh);
+ fat_brelse(sb, bh);
}
return 0;
}
dir->i_nlink--;
inode->i_dirt = dir->i_dirt = 1;
de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
res = 0;
rmdir_done:
- brelse(bh);
+ fat_brelse(sb, bh);
iput(dir);
iput(inode);
return res;
fat_lock_creation();
if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) {
fat_unlock_creation();
- brelse(bh);
+ fat_brelse(sb, bh);
iput(dir);
return -EEXIST;
}
MSDOS_I(inode)->i_busy = 1;
inode->i_dirt = dir->i_dirt = 1;
de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
unlink_done:
- brelse(bh);
+ fat_brelse(sb, bh);
iput(inode);
iput(dir);
return res;
if (!strncmp(old_name,new_name,MSDOS_NAME)) goto set_hid;
exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
if (*(unsigned char *) old_de->name == DELETED_FLAG) {
- if (exists) brelse(new_bh);
+ if (exists)
+ fat_brelse(sb, new_bh);
return -ENOENT;
}
if (exists) {
if (!(new_inode = iget(new_dir->i_sb,new_ino))) {
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
return -EIO;
}
error = S_ISDIR(new_inode->i_mode)
if (!error && (old_de->attr & ATTR_SYS)) error = -EPERM;
if (error) {
iput(new_inode);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
return error;
}
if (S_ISDIR(new_inode->i_mode)) {
MSDOS_I(new_inode)->i_busy = 1;
new_inode->i_dirt = 1;
new_de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(new_bh, 1);
+ fat_mark_buffer_dirty(sb, new_bh, 1);
dcache_add(new_dir, new_name, new_len, new_ino);
iput(new_inode);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
}
memcpy(old_de->name,new_name,MSDOS_NAME);
set_hid:
old_de->attr = is_hid
? (old_de->attr | ATTR_HIDDEN)
: (old_de->attr &~ ATTR_HIDDEN);
- mark_buffer_dirty(old_bh, 1);
+ fat_mark_buffer_dirty(sb, old_bh, 1);
/* update binary info for conversion, i_attrs */
if ((old_inode = iget(old_dir->i_sb,old_ino)) != NULL) {
MSDOS_I(old_inode)->i_attrs = is_hid
}
exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
if (!(old_inode = iget(old_dir->i_sb,old_ino))) {
- brelse(free_bh);
- if (exists) brelse(new_bh);
+ fat_brelse(sb, free_bh);
+ if (exists)
+ fat_brelse(sb, new_bh);
return -EIO;
}
if (*(unsigned char *) old_de->name == DELETED_FLAG) {
iput(old_inode);
- brelse(free_bh);
- if (exists) brelse(new_bh);
+ fat_brelse(sb, free_bh);
+ if (exists)
+ fat_brelse(sb, new_bh);
return -ENOENT;
}
new_inode = NULL; /* to make GCC happy */
if (exists) { /* Trash the old file! */
if (!(new_inode = iget(new_dir->i_sb,new_ino))) {
iput(old_inode);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
return -EIO;
}
error = S_ISDIR(new_inode->i_mode)
if (error) {
iput(new_inode);
iput(old_inode);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
return error;
}
new_inode->i_nlink = 0;
MSDOS_I(new_inode)->i_busy = 1;
new_inode->i_dirt = 1;
new_de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(new_bh, 1);
+ fat_mark_buffer_dirty(sb, new_bh, 1);
}
memcpy(free_de,old_de,sizeof(struct msdos_dir_entry));
memcpy(free_de->name,new_name,MSDOS_NAME);
if (!(free_inode = iget(new_dir->i_sb,free_ino))) {
free_de->name[0] = DELETED_FLAG;
/* Don't mark free_bh as dirty. Both states are supposed to be equivalent. */
- brelse(free_bh);
+ fat_brelse(sb, free_bh);
if (exists) {
iput(new_inode);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
}
return -EIO;
}
fat_cache_inval_inode(old_inode);
old_inode->i_dirt = 1;
old_de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(old_bh, 1);
- mark_buffer_dirty(free_bh, 1);
+ fat_mark_buffer_dirty(sb, old_bh, 1);
+ fat_mark_buffer_dirty(sb, free_bh, 1);
if (exists) {
MSDOS_I(new_inode)->i_depend = free_inode;
MSDOS_I(free_inode)->i_old = new_inode;
/* free_inode is put after putting new_inode and old_inode */
iput(new_inode);
dcache_add(new_dir, new_name, new_len, new_ino);
- brelse(new_bh);
+ fat_brelse(sb, new_bh);
}
if (S_ISDIR(old_inode->i_mode)) {
if ((error = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
&dotdot_de,&dotdot_ino,SCAN_ANY)) < 0) goto rename_done;
if (!(dotdot_inode = iget(old_inode->i_sb,dotdot_ino))) {
- brelse(dotdot_bh);
+ fat_brelse(sb, dotdot_bh);
error = -EIO;
goto rename_done;
}
dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
MSDOS_I(new_dir)->i_start;
dotdot_inode->i_dirt = 1;
- mark_buffer_dirty(dotdot_bh, 1);
+ fat_mark_buffer_dirty(sb, dotdot_bh, 1);
old_dir->i_nlink--;
new_dir->i_nlink++;
/* no need to mark them dirty */
dotdot_inode->i_nlink = new_dir->i_nlink;
iput(dotdot_inode);
- brelse(dotdot_bh);
+ fat_brelse(sb, dotdot_bh);
}
error = 0;
rename_done:
- brelse(free_bh);
+ fat_brelse(sb, free_bh);
iput(old_inode);
return error;
}
else error = rename_diff_dir(old_dir,old_msdos_name,old_len,new_dir,
new_msdos_name,new_len,old_bh,old_de,old_ino,is_hid);
fat_unlock_creation();
- brelse(old_bh);
+ fat_brelse(sb, old_bh);
rename_done:
iput(old_dir);
iput(new_dir);
if (done) {
row++;
if (row == slots) {
- brelse(bh);
+ fat_brelse(sb, bh);
/* printk("----- Free offset at %d\n", offset); */
return offset;
}
return sinfo_out->ino;
}
memcpy(de, ps, sizeof(struct msdos_dir_slot));
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
}
PRINTK(("vfat_find: create file 4\n"));
de->lcase = CASE_LOWER_BASE | CASE_LOWER_EXT;
- mark_buffer_dirty(bh, 1);
- brelse(bh);
+ fat_mark_buffer_dirty(sb, bh, 1);
+ fat_brelse(sb, bh);
sinfo_out->is_long = (slots > 1) ? 1 : 0;
if (sinfo_out->is_long) {
ino = fat_get_entry(dir, &offset, &bh, &de);
if (ino < 0) {
PRINTK(("vfat_mkdir problem\n"));
- if (bh) brelse(bh);
+ if (bh)
+ fat_brelse(sb, bh);
return ino;
}
PRINTK(("vfat_create_entry 3\n"));
if ((*result = iget(dir->i_sb,ino)) != NULL)
vfat_read_inode(*result);
- brelse(bh);
- if (!*result) return -EIO;
+ fat_brelse(sb, bh);
+ if (!*result)
+ return -EIO;
(*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime =
CURRENT_TIME;
(*result)->i_dirt = 1;
de->ctime = de->time;
de->adate = de->cdate = de->date;
de->size = 0;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
if ((dot = iget(dir->i_sb,ino)) != NULL)
vfat_read_inode(dot);
if (!dot) return -EIO;
res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOT, 1);
PRINTK(("vfat_create_dotdirs 4\n"));
if (res < 0) {
- brelse(bh);
+ fat_brelse(sb, bh);
return res;
}
PRINTK(("vfat_create_dotdirs 5\n"));
if ((res = fat_get_entry(dir,&offset,&bh,&de)) < 0) {
- brelse(bh);
+ fat_brelse(sb, bh);
return res;
}
PRINTK(("vfat_create_dotdirs 6\n"));
res = vfat_create_a_dotdir(dir, parent, bh, de, res, MSDOS_DOTDOT, 0);
PRINTK(("vfat_create_dotdirs 7\n"));
- brelse(bh);
+ fat_brelse(sb, bh);
return res;
}
if (!IS_FREE(de->name) && strncmp(de->name,MSDOS_DOT,
MSDOS_NAME) && strncmp(de->name,MSDOS_DOTDOT,
MSDOS_NAME)) {
- brelse(bh);
+ fat_brelse(sb, bh);
return -ENOTEMPTY;
}
}
if (bh)
- brelse(bh);
+ fat_brelse(sb, bh);
}
return 0;
}
dir->i_nlink--;
inode->i_dirt = dir->i_dirt = 1;
de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
iput(inode);
return 0;
MSDOS_I(inode)->i_busy = 1;
inode->i_dirt = dir->i_dirt = 1;
de->name[0] = DELETED_FLAG;
- mark_buffer_dirty(bh, 1);
+ fat_mark_buffer_dirty(sb, bh, 1);
iput(inode);
return 0;
}
(*de)->name[0] = DELETED_FLAG;
(*de)->attr = 0;
- mark_buffer_dirty(*bh, 1);
+ fat_mark_buffer_dirty(sb, *bh, 1);
}
return 0;
}
dir->i_version = ++event;
rmdir_done:
- brelse(bh);
+ fat_brelse(sb, bh);
return res;
}
}
unlink_done:
- brelse(bh);
+ fat_brelse(sb, bh);
return res;
}
}
old_de->name[0] = DELETED_FLAG;
old_de->attr = 0;
- mark_buffer_dirty(old_bh, 1);
+ fat_mark_buffer_dirty(sb, old_bh, 1);
}
PRINTK(("vfat_rename 15b\n"));
- mark_buffer_dirty(new_bh, 1);
+ fat_mark_buffer_dirty(sb, new_bh, 1);
dcache_add(new_dir, new_name, new_len, new_ino);
/* XXX: There is some code in the original MSDOS rename that
if ((res = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
&dotdot_de,&dotdot_ino,SCAN_ANY)) < 0) goto rename_done;
if (!(dotdot_inode = iget(old_inode->i_sb,dotdot_ino))) {
- brelse(dotdot_bh);
+ fat_brelse(sb, dotdot_bh);
res = -EIO;
goto rename_done;
}
dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
MSDOS_I(new_dir)->i_start;
dotdot_inode->i_dirt = 1;
- mark_buffer_dirty(dotdot_bh, 1);
+ fat_mark_buffer_dirty(sb, dotdot_bh, 1);
old_dir->i_nlink--;
new_dir->i_nlink++;
/* no need to mark them dirty */
dotdot_inode->i_nlink = new_dir->i_nlink;
iput(dotdot_inode);
- brelse(dotdot_bh);
+ fat_brelse(sb, dotdot_bh);
}
if (res > 0) res = 0;
rename_done:
- if (locked) fat_unlock_creation();
- if (old_bh) brelse(old_bh);
- if (new_bh) brelse(new_bh);
- if (old_inode) iput(old_inode);
+ if (locked)
+ fat_unlock_creation();
+ if (old_bh)
+ fat_brelse(sb, old_bh);
+ if (new_bh)
+ fat_brelse(sb, new_bh);
+ if (old_inode)
+ iput(old_inode);
iput(old_dir);
iput(new_dir);
return res;
#define B57600 00020
#define B115200 00021
#define B230400 00022
+#define B460800 00023
#define CSIZE 00001400
#define CS5 00000000
--- /dev/null
+#ifndef _LINUX_MATH_EMU_H
+#define _LINUX_MATH_EMU_H
+
+
+void restore_i387_soft(struct _fpstate *buf);
+struct _fpstate * save_i387_soft(struct _fpstate * buf);
+
+struct fpu_reg {
+ char sign;
+ char tag;
+ long exp;
+ unsigned sigl;
+ unsigned sigh;
+};
+
+
+/* This structure matches the layout of the data saved to the stack
+ following a device-not-present interrupt, part of it saved
+ automatically by the 80386/80486.
+ */
+struct info {
+ long ___orig_eip;
+ long ___ret_from_system_call;
+ long ___ebx;
+ long ___ecx;
+ long ___edx;
+ long ___esi;
+ long ___edi;
+ long ___ebp;
+ long ___eax;
+ long ___ds;
+ long ___es;
+ long ___fs;
+ long ___gs;
+ long ___orig_eax;
+ long ___eip;
+ long ___cs;
+ long ___eflags;
+ long ___esp;
+ long ___ss;
+ long ___vm86_es; /* This and the following only in vm86 mode */
+ long ___vm86_ds;
+ long ___vm86_fs;
+ long ___vm86_gs;
+};
+
+#endif
#ifndef __ASM_I386_PROCESSOR_H
#define __ASM_I386_PROCESSOR_H
+#include <asm/vm86.h>
+#include <asm/math_emu.h>
+
/*
* System setup and hardware bug flags..
* [Note we don't test the 386 multiply bug or popad bug]
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
+#define B460800 0010004
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */
--- /dev/null
+#ifndef _LINUX_VM86_H
+#define _LINUX_VM86_H
+
+/*
+ * I'm guessing at the VIF/VIP flag usage, but hope that this is how
+ * the Pentium uses them. Linux will return from vm86 mode when both
+ * VIF and VIP is set.
+ *
+ * On a Pentium, we could probably optimize the virtual flags directly
+ * in the eflags register instead of doing it "by hand" in vflags...
+ *
+ * Linus
+ */
+
+#define TF_MASK 0x00000100
+#define IF_MASK 0x00000200
+#define IOPL_MASK 0x00003000
+#define NT_MASK 0x00004000
+#define VM_MASK 0x00020000
+#define AC_MASK 0x00040000
+#define VIF_MASK 0x00080000 /* virtual interrupt flag */
+#define VIP_MASK 0x00100000 /* virtual interrupt pending */
+#define ID_MASK 0x00200000
+
+#define BIOSSEG 0x0f000
+
+#define CPU_086 0
+#define CPU_186 1
+#define CPU_286 2
+#define CPU_386 3
+#define CPU_486 4
+#define CPU_586 5
+
+/*
+ * Return values for the 'vm86()' system call
+ */
+#define VM86_TYPE(retval) ((retval) & 0xff)
+#define VM86_ARG(retval) ((retval) >> 8)
+
+#define VM86_SIGNAL 0 /* return due to signal */
+#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
+#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */
+#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */
+
+/*
+ * This is the stack-layout when we have done a "SAVE_ALL" from vm86
+ * mode - the main change is that the old segment descriptors aren't
+ * useful any more and are forced to be zero by the kernel (and the
+ * hardware when a trap occurs), and the real segment descriptors are
+ * at the end of the structure. Look at ptrace.h to see the "normal"
+ * setup.
+ */
+
+struct vm86_regs {
+/*
+ * normal regs, with special meaning for the segment descriptors..
+ */
+ long ebx;
+ long ecx;
+ long edx;
+ long esi;
+ long edi;
+ long ebp;
+ long eax;
+ long __null_ds;
+ long __null_es;
+ long __null_fs;
+ long __null_gs;
+ long orig_eax;
+ long eip;
+ unsigned short cs, __csh;
+ long eflags;
+ long esp;
+ unsigned short ss, __ssh;
+/*
+ * these are specific to v86 mode:
+ */
+ unsigned short es, __esh;
+ unsigned short ds, __dsh;
+ unsigned short fs, __fsh;
+ unsigned short gs, __gsh;
+};
+
+struct revectored_struct {
+ unsigned long __map[8]; /* 256 bits */
+};
+
+struct vm86_struct {
+ struct vm86_regs regs;
+ unsigned long flags;
+ unsigned long screen_bitmap;
+ unsigned long cpu_type;
+ struct revectored_struct int_revectored;
+ struct revectored_struct int21_revectored;
+};
+
+/*
+ * flags masks
+ */
+#define VM86_SCREEN_BITMAP 0x0001
+
+#ifdef __KERNEL__
+
+void handle_vm86_fault(struct vm86_regs *, long);
+void handle_vm86_debug(struct vm86_regs *, long);
+
+#endif
+
+#endif
boards carrying several UART's,
like some Amiga boards. */
unsigned short nr_uarts; /* UART-counter, that indicates
- how manu UART's there are on
+ how many UART's there are on
the board. If the board has a
IRQ-register, this can be used
to check if any of the uarts,
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
+#define B460800 0010004
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
+#define B460800 0010004
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */
#endif
#define B57600 00020
#define B115200 00021
#define B230400 00022
+#define B460800 00023
#define CSIZE 00001400
#define CS5 00000000
#define fd_cacheflush(addr, size) /* nothing... */
#define fd_request_irq() sun_fd_request_irq()
#define fd_free_irq() /* nothing... */
+#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
+#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
#define FLOPPY_MOTOR_MASK 0x10
#define B57600 0x00010001
#define B115200 0x00010002
#define B230400 0x00010003
+#define B460800 0x00010004
#define CIBAUD 0x000f0000 /* input baud rate (not used) */
#define CRTSCTS 0x80000000 /* flow control */
int s_bm_count; /* Number of bitmap blocks. */
int s_nextzone; /* Next zone to look for free blocks. */
int s_num_zones; /* Total number of zones. */
- struct affs_zone *s_zones; /* The zones themselfes. */
+ struct affs_zone *s_zones; /* The zones themselves. */
char *s_zonemap; /* Bitmap for zones. */
- char *s_prefix; /* Prefix for volumes and assignes. */
+ char *s_prefix; /* Prefix for volumes and assigns. */
int s_prefix_len; /* Length of prefix. */
char s_volume[32]; /* Volume prefix for absolute symlinks. */
};
#elif defined(__BIG_ENDIAN)
#define BO_EXBITS 0x00UL
#else
-#error Endianess must be known for affs to work.
+#error Endianness must be known for affs to work.
#endif
/* The following constants will be checked against the values read native */
extern int init_elf_binfmt(void);
extern int init_aout_binfmt(void);
extern int init_script_binfmt(void);
+extern int init_java_binfmt(void);
extern int prepare_binprm(struct linux_binprm *);
extern void remove_arg_zero(struct linux_binprm *);
#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
+/*
+ * For controlling a changer. (Used by ATAPI driver.)
+ */
+#define CDROMLOADFROMSLOT 0x531a /* LOAD disk from slot*/
+
+
/*
* CD-ROM-specific SCSI command opcodes
*/
#define KERNELD_BLANKER 7 /* from drivers/char/console.c */
#define KERNELD_ARP 256 /* from net/ipv4/arp.c */
+/*
+ * Uncomment the following line for the new kerneld protocol
+ * This includes the pid of the kernel level requestor into the kerneld header
+ */
+/*
+#define NEW_KERNELD_PROTOCOL
+ */
+#ifdef NEW_KERNELD_PROTOCOL
+#define OLDIPC_KERNELD 00040000 /* use the kerneld message channel */
+#define IPC_KERNELD 00140000 /* use the kerneld message channel, new protocol */
+#define KDHDR (sizeof(long) + sizeof(short) + sizeof(short))
+#define NULL_KDHDR 0, 2, 0
+#else
#define IPC_KERNELD 00040000 /* use the kerneld message channel */
+#define KDHDR (sizeof(long))
+#define NULL_KDHDR 0
+#endif
#define KERNELD_MAXCMD 0x7ffeffff
#define KERNELD_MINSEQ 0x7fff0000 /* "commands" legal up to 0x7ffeffff */
#define KERNELD_WAIT 0x80000000
struct kerneld_msg {
long mtype;
long id;
+#ifdef NEW_KERNELD_PROTOCOL
+ short version;
+ short pid;
+#endif
#ifdef __KERNEL__
char *text;
#else
+++ /dev/null
-#ifndef _LINUX_MATH_EMU_H
-#define _LINUX_MATH_EMU_H
-
-
-void restore_i387_soft(struct _fpstate *buf);
-struct _fpstate * save_i387_soft(struct _fpstate * buf);
-
-struct fpu_reg {
- char sign;
- char tag;
- long exp;
- unsigned sigl;
- unsigned sigh;
-};
-
-
-/* This structure matches the layout of the data saved to the stack
- following a device-not-present interrupt, part of it saved
- automatically by the 80386/80486.
- */
-struct info {
- long ___orig_eip;
- long ___ret_from_system_call;
- long ___ebx;
- long ___ecx;
- long ___edx;
- long ___esi;
- long ___edi;
- long ___ebp;
- long ___eax;
- long ___ds;
- long ___es;
- long ___fs;
- long ___gs;
- long ___orig_eax;
- long ___eip;
- long ___cs;
- long ___eflags;
- long ___esp;
- long ___ss;
- long ___vm86_es; /* This and the following only in vm86 mode */
- long ___vm86_ds;
- long ___vm86_fs;
- long ___vm86_gs;
-};
-
-#endif
struct msg *msg_next; /* next message on queue */
long msg_type;
char *msg_spot; /* message text address */
+ time_t msg_stime; /* msgsnd time */
short msg_ts; /* message text size */
};
#ifndef _LINUX_RANDOM_H
#define _LINUX_RANDOM_H
+#include <linux/ioctl.h>
+
/* ioctl()'s for the random number generator */
/* Get the entropy count. */
-#define RNDGETENTCNT 0x01080000
+#define RNDGETENTCNT _IOR( 'R', 0x00, int )
/* Add to (or subtract from) the entropy count. (Superuser only.) */
-#define RNDADDTOENTCNT 0x01080001
+#define RNDADDTOENTCNT _IOW( 'R', 0x01, int )
/* Get the contents of the entropy pool. (Superuser only.) */
-#define RNDGETPOOL 0x01080002
+#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
/*
* Write bytes into the entropy pool and add to the entropy count.
* (Superuser only.)
*/
-#define RNDADDENTROPY 0x01080003
+#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
/* Clear entropy count to 0. (Superuser only.) */
-#define RNDZAPENTCNT 0x01080004
+#define RNDZAPENTCNT _IO( 'R', 0x04 )
/* Clear the entropy pool and associated counters. (Superuser only.) */
-#define RNDCLEARPOOL 0x01080006
+#define RNDCLEARPOOL _IO( 'R', 0x06 )
struct rand_pool_info {
int entropy_count;
#include <linux/time.h>
#include <linux/param.h>
#include <linux/resource.h>
-#include <linux/vm86.h>
-#include <linux/math_emu.h>
#include <linux/ptrace.h>
#include <linux/timer.h>
+++ /dev/null
-#ifndef _LINUX_VM86_H
-#define _LINUX_VM86_H
-
-/*
- * I'm guessing at the VIF/VIP flag usage, but hope that this is how
- * the Pentium uses them. Linux will return from vm86 mode when both
- * VIF and VIP is set.
- *
- * On a Pentium, we could probably optimize the virtual flags directly
- * in the eflags register instead of doing it "by hand" in vflags...
- *
- * Linus
- */
-
-#define TF_MASK 0x00000100
-#define IF_MASK 0x00000200
-#define IOPL_MASK 0x00003000
-#define NT_MASK 0x00004000
-#define VM_MASK 0x00020000
-#define AC_MASK 0x00040000
-#define VIF_MASK 0x00080000 /* virtual interrupt flag */
-#define VIP_MASK 0x00100000 /* virtual interrupt pending */
-#define ID_MASK 0x00200000
-
-#define BIOSSEG 0x0f000
-
-#define CPU_086 0
-#define CPU_186 1
-#define CPU_286 2
-#define CPU_386 3
-#define CPU_486 4
-#define CPU_586 5
-
-/*
- * Return values for the 'vm86()' system call
- */
-#define VM86_TYPE(retval) ((retval) & 0xff)
-#define VM86_ARG(retval) ((retval) >> 8)
-
-#define VM86_SIGNAL 0 /* return due to signal */
-#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
-#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */
-#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */
-
-/*
- * This is the stack-layout when we have done a "SAVE_ALL" from vm86
- * mode - the main change is that the old segment descriptors aren't
- * useful any more and are forced to be zero by the kernel (and the
- * hardware when a trap occurs), and the real segment descriptors are
- * at the end of the structure. Look at ptrace.h to see the "normal"
- * setup.
- */
-
-struct vm86_regs {
-/*
- * normal regs, with special meaning for the segment descriptors..
- */
- long ebx;
- long ecx;
- long edx;
- long esi;
- long edi;
- long ebp;
- long eax;
- long __null_ds;
- long __null_es;
- long __null_fs;
- long __null_gs;
- long orig_eax;
- long eip;
- unsigned short cs, __csh;
- long eflags;
- long esp;
- unsigned short ss, __ssh;
-/*
- * these are specific to v86 mode:
- */
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned short fs, __fsh;
- unsigned short gs, __gsh;
-};
-
-struct revectored_struct {
- unsigned long __map[8]; /* 256 bits */
-};
-
-struct vm86_struct {
- struct vm86_regs regs;
- unsigned long flags;
- unsigned long screen_bitmap;
- unsigned long cpu_type;
- struct revectored_struct int_revectored;
- struct revectored_struct int21_revectored;
-};
-
-/*
- * flags masks
- */
-#define VM86_SCREEN_BITMAP 0x0001
-
-#ifdef __KERNEL__
-
-void handle_vm86_fault(struct vm86_regs *, long);
-void handle_vm86_debug(struct vm86_regs *, long);
-
-#endif
-
-#endif
#define SCSI_REMOVAL_PREVENT 1
#define SCSI_REMOVAL_ALLOW 0
+#ifdef __KERNEL__
+
extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
#endif
+#endif
+
extern void buff_setup(char *str, int *ints);
extern void panic_setup(char *str, int *ints);
extern void bmouse_setup(char *str, int *ints);
+extern void msmouse_setup(char *str, int *ints);
extern void lp_setup(char *str, int *ints);
extern void eth_setup(char *str, int *ints);
extern void xd_setup(char *str, int *ints);
#ifdef CONFIG_BUSMOUSE
{ "bmouse=", bmouse_setup },
#endif
+#ifdef CONFIG_MS_BUSMOUSE
+ { "msmouse=", msmouse_setup },
+#endif
#ifdef CONFIG_SCSI_SEAGATE
{ "st0x=", st0x_setup },
{ "tmc8xx=", tmc8xx_setup },
* linux/ipc/msg.c
* Copyright (C) 1992 Krishna Balasubramanian
*
- * Kerneld extensions by Bjorn Ekwall <bj0rn@blox.se> in May 1995
+ * Kerneld extensions by Bjorn Ekwall <bj0rn@blox.se> in May 1995, and May 1996
*
+ * See <linux/kerneld.h> for the (optional) new kerneld protocol
*/
#include <linux/config.h>
return;
}
+/*
+ * If the send queue is full, try to free any old messages.
+ * These are most probably unwanted, since noone has picked them up...
+ */
+#define MSG_FLUSH_TIME 10 /* seconds */
+static void flush_msg(struct msqid_ds *msq)
+{
+ struct msg *nmsg;
+ unsigned long flags;
+ int flushed = 0;
+
+ save_flags(flags);
+ cli();
+
+ /* messages were put on the queue in time order */
+ while ( (nmsg = msq->msg_first) &&
+ ((CURRENT_TIME - nmsg->msg_stime) > MSG_FLUSH_TIME)) {
+ msgbytes -= nmsg->msg_ts;
+ msghdrs--;
+ msq->msg_cbytes -= nmsg->msg_ts;
+ msq->msg_qnum--;
+ msq->msg_first = nmsg->msg_next;
+ ++flushed;
+ kfree(nmsg);
+ }
+
+ if (msq->msg_qnum == 0)
+ msq->msg_first = msq->msg_last = NULL;
+ restore_flags(flags);
+ if (flushed)
+ printk(KERN_WARNING "flushed %d old SYSVIPC messages", flushed);
+}
+
static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
{
int id, err;
struct ipc_perm *ipcp;
struct msg *msgh;
long mtype;
+ unsigned long flags;
if (msgsz > MSGMAX || (long) msgsz < 0 || msqid < 0)
return -EINVAL;
if (msq->msg_perm.seq != (unsigned int) msqid / MSGMNI)
return -EIDRM;
/*
- * Non-root processes may send to kerneld!
+ * Non-root kernel level processes may send to kerneld!
* i.e. no permission check if called from the kernel
* otoh we don't want user level non-root snoopers...
*/
return -EACCES;
if (msgsz + msq->msg_cbytes > msq->msg_qbytes) {
- /* no space in queue */
- if (msgflg & IPC_NOWAIT)
- return -EAGAIN;
- if (current->signal & ~current->blocked)
- return -EINTR;
- if (intr_count) {
- /* Very unlikely, but better safe than sorry... */
- printk("Ouch, kerneld:msgsnd wants to sleep at interrupt!\n");
- return -EINTR;
+ if ((kerneld_msqid != -1) && (kerneld_msqid == msqid))
+ flush_msg(msq); /* flush the kerneld channel only */
+ if (msgsz + msq->msg_cbytes > msq->msg_qbytes) {
+ /* still no space in queue */
+ if (msgflg & IPC_NOWAIT)
+ return -EAGAIN;
+ if (current->signal & ~current->blocked)
+ return -EINTR;
+ if (intr_count) {
+ /* Very unlikely, but better safe than sorry */
+ printk(KERN_WARNING "Ouch, kerneld:msgsnd buffers full!\n");
+ return -EINTR;
+ }
+ interruptible_sleep_on (&msq->wwait);
+ goto slept;
}
- interruptible_sleep_on (&msq->wwait);
- goto slept;
}
/* allocate message header and text space*/
- msgh = (struct msg *) kmalloc (sizeof(*msgh) + msgsz,
- (intr_count ? GFP_ATOMIC : GFP_USER));
+ msgh = (struct msg *) kmalloc (sizeof(*msgh) + msgsz, GFP_ATOMIC);
if (!msgh)
return -ENOMEM;
msgh->msg_spot = (char *) (msgh + 1);
* Note that the kernel supplies a pointer
* but the user-level kerneld uses a char array...
*/
- memcpy(msgh->msg_spot, (char *)(&(kdmp->id)), sizeof(long));
- memcpy(msgh->msg_spot + sizeof(long), kdmp->text,
- msgsz - sizeof(long));
+ memcpy(msgh->msg_spot, (char *)(&(kdmp->id)), KDHDR);
+ memcpy(msgh->msg_spot + KDHDR, kdmp->text, msgsz - KDHDR);
}
else
memcpy_fromfs (msgh->msg_spot, msgp->mtext, msgsz);
}
msgh->msg_next = NULL;
+ msgh->msg_ts = msgsz;
+ msgh->msg_type = mtype;
+ msgh->msg_stime = CURRENT_TIME;
+
+ save_flags(flags);
+ cli();
if (!msq->msg_first)
msq->msg_first = msq->msg_last = msgh;
else {
msq->msg_last->msg_next = msgh;
msq->msg_last = msgh;
}
- msgh->msg_ts = msgsz;
- msgh->msg_type = mtype;
msq->msg_cbytes += msgsz;
msgbytes += msgsz;
msghdrs++;
msq->msg_qnum++;
msq->msg_lspid = current->pid;
msq->msg_stime = CURRENT_TIME;
+ restore_flags(flags);
if (msq->rwait)
wake_up (&msq->rwait);
return 0;
{
struct msqid_ds *msq;
struct msg *tmsg;
+ unsigned long flags;
msq = msgque [ (unsigned int) kerneld_msqid % MSGMNI ];
if (msq == IPC_NOID || msq == IPC_UNUSED)
return;
+ save_flags(flags);
+ cli();
for (tmsg = msq->msg_first; tmsg; tmsg = tmsg->msg_next)
if (*(long *)(tmsg->msg_spot) == msgid)
break;
+ restore_flags(flags);
if (tmsg) { /* still there! */
- struct kerneld_msg kmsp = { msgid, -ENODEV, "" };
+ struct kerneld_msg kmsp = { msgid, NULL_KDHDR, "" };
- printk(KERN_ALERT "Ouch, kerneld timed out, message failed\n");
- real_msgsnd(kerneld_msqid, (struct msgbuf *)&kmsp,
- sizeof(long),
+ printk(KERN_ALERT "Ouch, no kerneld for message %ld\n", msgid);
+ kmsp.id = -ENODEV;
+ real_msgsnd(kerneld_msqid, (struct msgbuf *)&kmsp, KDHDR,
S_IRUSR | S_IWUSR | IPC_KERNELD | MSG_NOERROR);
}
}
struct msg *tmsg, *leastp = NULL;
struct msg *nmsg = NULL;
int id, err;
+ unsigned long flags;
if (msqid < 0 || (long) msgsz < 0)
return -EINVAL;
}
if ((msgflg & IPC_KERNELD) == 0) {
/*
- * Non-root processes may receive from kerneld!
+ * All kernel level processes may receive from kerneld!
* i.e. no permission check if called from the kernel
* otoh we don't want user level non-root snoopers...
*/
if (ipcperms (ipcp, S_IRUGO)) {
- DROP_TIMER;
+ DROP_TIMER; /* Not needed, but doesn't hurt */
return -EACCES;
}
}
+
+ save_flags(flags);
+ cli();
if (msgtyp == 0)
nmsg = msq->msg_first;
else if (msgtyp > 0) {
if (leastp && leastp->msg_type <= - msgtyp)
nmsg = leastp;
}
+ restore_flags(flags);
if (nmsg) { /* done finding a message */
DROP_TIMER;
if ((msgsz < nmsg->msg_ts) && !(msgflg & MSG_NOERROR)) {
- DROP_TIMER;
return -E2BIG;
}
msgsz = (msgsz > nmsg->msg_ts)? nmsg->msg_ts : msgsz;
+ save_flags(flags);
+ cli();
if (nmsg == msq->msg_first)
msq->msg_first = nmsg->msg_next;
else {
msgbytes -= nmsg->msg_ts;
msghdrs--;
msq->msg_cbytes -= nmsg->msg_ts;
+ restore_flags(flags);
if (msq->wwait)
wake_up (&msq->wwait);
/*
struct kerneld_msg *kdmp = (struct kerneld_msg *) msgp;
memcpy((char *)(&(kdmp->id)),
- nmsg->msg_spot,
- sizeof(long));
+ nmsg->msg_spot, KDHDR);
/*
* Note that kdmp->text is a pointer
* when called from kernel space!
*/
- if ((msgsz > sizeof(long)) && kdmp->text)
+ if ((msgsz > KDHDR) && kdmp->text)
memcpy(kdmp->text,
- nmsg->msg_spot + sizeof(long),
- msgsz - sizeof(long));
+ nmsg->msg_spot + KDHDR,
+ msgsz - KDHDR);
}
else {
put_user (nmsg->msg_type, &msgp->mtype);
memcpy_tofs (msgp->mtext, nmsg->msg_spot, msgsz);
}
kfree(nmsg);
- DROP_TIMER;
return msgsz;
} else { /* did not find a message */
if (msgflg & IPC_NOWAIT) {
DROP_TIMER;
return -EINTR;
}
- if (intr_count) {
- DROP_TIMER;
- /* Won't happen... */
- printk("Ouch, kerneld:msgrcv wants to sleep at interrupt!\n");
- return -EINTR;
- }
interruptible_sleep_on (&msq->rwait);
}
} /* end while */
asmlinkage int sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
{
- /* IPC_KERNELD is used as a marker for kernel calls */
+ /* IPC_KERNELD is used as a marker for kernel level calls */
return real_msgsnd(msqid, msgp, msgsz, msgflg & ~IPC_KERNELD);
}
asmlinkage int sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,
long msgtyp, int msgflg)
{
- /* IPC_KERNELD is used as a marker for kernel calls */
+ /* IPC_KERNELD is used as a marker for kernel level calls */
return real_msgrcv (msqid, msgp, msgsz, msgtyp, msgflg & ~IPC_KERNELD);
}
int i;
if (!suser())
return -EPERM;
+#ifdef NEW_KERNELD_PROTOCOL
+ if ((msgflg & IPC_KERNELD) == OLDIPC_KERNELD) {
+ printk(KERN_ALERT "Please recompile your kerneld daemons!\n");
+ return -EPERM;
+ }
+#endif
if ((kerneld_msqid == -1) && (kerneld_msqid =
newque(IPC_PRIVATE, msgflg & S_IRWXU)) < 0)
return -ENOSPC;
* The message type from the kernel to kerneld is used to specify _what_
* function we want kerneld to perform.
*
- * The "normal" message area is divided into a long, followed by a char array.
- * The long is used to hold the sequence number of the request, which will
+ * The "normal" message area is divided into a header, followed by a char array.
+ * The header is used to hold the sequence number of the request, which will
* be used as the return message type from kerneld back to the kernel.
- * In the return message, the long will be used to store the exit status
+ * In the return message, the header will be used to store the exit status
* of the kerneld "job", or task.
* The character array is used to pass parameters to kerneld and (optional)
* return information from kerneld back to the kernel.
* ret_size is the size of the (optional) return _value,
* OR-ed with KERNELD_WAIT if we want an answer
* msgsize is the size (in bytes) of the message, not including
- * the long that is always sent first in a kerneld message
+ * the header that is always sent first in a kerneld message
* text is the parameter for the kerneld specific task
* ret_val is NULL or the kernel address where an expected answer
* from kerneld should be placed.
int status = -ENOSYS;
#ifdef CONFIG_KERNELD
static int id = KERNELD_MINSEQ;
- struct kerneld_msg kmsp = { msgtype, 0, (char *)text };
+ struct kerneld_msg kmsp = { msgtype, NULL_KDHDR, (char *)text };
int msgflg = S_IRUSR | S_IWUSR | IPC_KERNELD | MSG_NOERROR;
+ unsigned long flags;
if (kerneld_msqid == -1)
return -ENODEV;
/* Do not wait for an answer at interrupt-time! */
if (intr_count)
ret_size &= ~KERNELD_WAIT;
+#ifdef NEW_KERNELD_PROTOCOL
+ else
+ kmsp.pid = current->pid;
+#endif
- msgsz += sizeof(long);
+ msgsz += KDHDR;
if (ret_size & KERNELD_WAIT) {
- if (++id <= 0)
+ save_flags(flags);
+ cli();
+ if (++id <= 0) /* overflow */
id = KERNELD_MINSEQ;
kmsp.id = id;
+ restore_flags(flags);
}
status = real_msgsnd(kerneld_msqid, (struct msgbuf *)&kmsp, msgsz, msgflg);
ret_size &= ~KERNELD_WAIT;
kmsp.text = (char *)ret_val;
status = real_msgrcv(kerneld_msqid, (struct msgbuf *)&kmsp,
- sizeof(long) + ((ret_val)?ret_size:0),
+ KDHDR + ((ret_val)?ret_size:0),
kmsp.id, msgflg);
if (status > 0) /* a valid answer contains at least a long */
status = kmsp.id;
* all possible race conditions should be resolved by
* cli()/sti() pairs.
*
- * Important note: hhs never disapear from lists, if ARP_LOCKED,
+ * Important note: hhs never disappear from lists, if ARP_LOCKED,
* this fact allows to scan hh lists with enabled interrupts,
* but results in generating duplicate hh entries.
* It is harmless. (and I've never seen such event)
entry->mask = mask;
entry->flags = r->arp_flags;
- entry->next = (*entryp)->next;
+ entry->next = *entryp;
*entryp = entry;
}