Commit 5cf40909 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.81

parent 0057ae60
......@@ -7,6 +7,10 @@
Linus
----------
M: Matti Aarnio
E: mea@utu.fi
D: Dynamicized network socket allocations, LILO for AHA1542
N: Werner Almesberger
E: almesber@bernina.ethz.ch
D: dosfs, LILO, some fd features, various other hacks here and there
......
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 80
SUBLEVEL = 81
ARCH = i386
......
......@@ -73,6 +73,7 @@ bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n
bool 'Adaptec AHA274X/284X support' CONFIG_SCSI_AHA274X n
bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
bool 'EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support' CONFIG_SCSI_EATA_DMA n
bool 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n
bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
......@@ -86,7 +87,7 @@ bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE
bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n
bool 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n
#bool 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n
#bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n
fi
......
......@@ -81,13 +81,13 @@ interface (/dev/hda) and an IDE cdrom drive on the secondary interface
ln -sf /dev/hdc /dev/cdrom
mkdir /cd
mount /dev/cdrom /cd -t iso9660 -o ro,block=2048
mount /dev/cdrom /cd -t iso9660 -o ro
Please pass on any feedback on the cdrom stuff to the author & maintainer,
Scott Snyder (snyder@fnald0.fnal.gov).
Note that present, the kernel is unable to execute demand-paged binaries
directly off of the cdrom (due to the different block size).
The kernel is now be able to execute binaries directly off of the cdrom,
provided it is mounted with the default block size of 1024.
The hdparm.c program for controlling various IDE features is now packaged
separately. Look for it on popular linux FTP sites.
......
This diff is collapsed.
This diff is collapsed.
/*
* linux/drivers/block/ide.c Version 3.6 January 5, 1994
* linux/drivers/block/ide.c Version 3.8 January 12, 1995
*
* Copyright (C) 1994 Linus Torvalds & authors (see below)
* Copyright (C) 1994, 1995 Linus Torvalds & authors (see below)
*/
/*
......@@ -92,6 +92,10 @@
* increase DRQ_WAIT to eliminate nuisance messages
* wait for DRQ_STAT instead of DATA_READY during probing
* (courtesy of Gary Thomas gary@efland.UU.NET)
* Version 3.8 fixed byte-swapping for confused Mitsumi cdrom drives
* update of ide-cd.c from Scott, allows blocksize=1024
* cdrom probe fixes, inspired by jprang@uni-duisburg.de
*
* To do:
* - special 32-bit controller-type detection & support
* - figure out why two WD drives on one i/f sometimes don't identify
......@@ -460,7 +464,7 @@ static void do_ide_reset (ide_dev_t *dev)
printk("%s: do_ide_reset: ", ide_name[DEV_HWIF]);
/* ATAPI devices usually do *not* assert READY after a reset */
if (!OK_STAT(tmp=GET_STAT(DEV_HWIF), 0, BUSY_STAT)) {
printk("timed out, status=0x%02x\n", tmp);
printk("timed-out, status=0x%02x\n", tmp);
} else {
if ((tmp = GET_ERR(DEV_HWIF)) == 1)
printk("success\n");
......@@ -1596,19 +1600,23 @@ static void do_identify (ide_dev_t *dev)
sti();
/*
* Everything except ATAPI seems to use big-endian string ordering,
* whereas the NEC and Vertos ATAPI drives both use little-endian.
* Latest reports indicate that some Mitsumi ATAPI use big-endian.
* Non-ATAPI drives seem to always use big-endian string ordering.
* Most ATAPI cdrom drives, such as the NEC, Vertos, and some Mitsumi
* models, use little-endian. But otherMitsumi models appear to use
* big-endian, confusing the issue. We try to take all of this into
* consideration, "knowing" that Mitsumi drive names begin with "FX".
*/
bswap = (id->config & 0x8000) ? 0 : 1;
if (bswap && id->model[0] == 'F' && id->model[1] == 'X')
bswap = 0;
fixstring (id->serial_no, sizeof(id->serial_no), bswap);
fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
bswap = 1;
if (id->model[0] != 'X' || id->model[1] != 'F') {
if ((id->model[0] == 'F' && id->model[1] == 'X') || (id->config & 0x8000))
bswap = 0;
}
fixstring (id->model, sizeof(id->model), bswap);
fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
fixstring (id->serial_no, sizeof(id->serial_no), bswap);
/*
* Check for ATAPI device (such as an NEC-260 IDE cdrom drive)
* Check for an ATAPI device
*/
if (id->config & 0x8000) {
#ifdef CONFIG_BLK_DEV_IDECD
......@@ -1715,9 +1723,14 @@ static void delay_10ms (void)
static int try_to_identify (ide_dev_t *dev, byte cmd)
/*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
*/
{
int rc;
unsigned long timer, timeout;
unsigned long timeout;
#if PROBE_FOR_IRQS
int irqs = 0;
static byte irq_probed[2] = {0,0};
......@@ -1733,58 +1746,61 @@ static int try_to_identify (ide_dev_t *dev, byte cmd)
delay_10ms(); /* take a deep breath */
OUT_BYTE(cmd,HD_COMMAND); /* ask drive for ID */
delay_10ms(); /* wait for BUSY_STAT */
timeout = (cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY;
for (timer = jiffies + (timeout / 2); timer > jiffies;) {
if ((IN_BYTE(HD_ALTSTATUS,DEV_HWIF) & BUSY_STAT) == 0) {
delay_10ms(); /* wait for IRQ & DATA_READY */
if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)){
cli(); /* some sys need this */
do_identify(dev); /* drive returned ID */
rc = 0;
} else
rc = 1; /* drive refused ID */
timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
for (timeout += jiffies; IN_BYTE(HD_ALTSTATUS,DEV_HWIF) & BUSY_STAT;) {
if (timeout < jiffies) {
#if PROBE_FOR_IRQS
if (!irq_probed[DEV_HWIF]) {
irqs = probe_irq_off(irqs); /* end probe */
if (irqs > 0) {
irq_probed[DEV_HWIF] = 1;
ide_irq[DEV_HWIF] = irqs;
} else
printk("%s: IRQ probe failed (%d)\n", dev->name, irqs);
}
if (!irq_probed[DEV_HWIF])
(void) probe_irq_off(irqs);
#endif /* PROBE_FOR_IRQS */
goto done_try;
return 1; /* drive timed-out */
}
}
rc = 2; /* it ain't responding */
delay_10ms(); /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)) {
cli(); /* some systems need this */
do_identify(dev); /* drive returned ID */
rc = 0; /* success */
} else
rc = 2; /* drive refused ID */
#if PROBE_FOR_IRQS
if (!irq_probed[DEV_HWIF])
(void) probe_irq_off(irqs); /* end probing */
if (!irq_probed[DEV_HWIF]) {
irqs = probe_irq_off(irqs); /* get irq number */
if (irqs > 0) {
irq_probed[DEV_HWIF] = 1;
ide_irq[DEV_HWIF] = irqs;
} else /* Mmmm.. multiple IRQs */
printk("%s: IRQ probe failed (%d)\n", dev->name, irqs);
}
#endif /* PROBE_FOR_IRQS */
done_try:
OUT_BYTE(dev->ctl|2,HD_CMD); /* disable device irq */
return rc;
}
/*
* This routine has the difficult job of finding a drive if it exists,
* without getting hung up if it doesn't exist, and without leaving any IRQs
* dangling to haunt us later. The last point actually occurred in v2.3, and
* is the reason for the slightly complex exit sequence. If a drive is "known"
* to exist (from CMOS or kernel parameters), but does not respond right away,
* the probe will "hang in there" for the maximum wait time (about 30 seconds).
* Otherwise, it will exit much more quickly.
* without getting hung up if it doesn't exist, without trampling on
* ethernet cards, and without leaving any IRQs dangling to haunt us later.
*
* Returns 1 if device present but not identified. Returns 0 otherwise.
* If a drive is "known" to exist (from CMOS or kernel parameters),
* but does not respond right away, the probe will "hang in there"
* for the maximum wait time (about 30 seconds), otherwise it will
* exit much more quickly.
*/
static int do_probe (ide_dev_t *dev, byte cmd)
/*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
* 3 bad status from device (possible for ATAPI drives)
* 4 probe was not attempted
*/
{
int rc;
#ifdef CONFIG_BLK_DEV_IDECD
if (dev->present) { /* avoid waiting for inappropriate probes */
if ((dev->type == disk) ^ (cmd == WIN_IDENTIFY))
return 1;
return 4;
}
#endif /* CONFIG_BLK_DEV_IDECD */
#if DEBUG
......@@ -1794,21 +1810,23 @@ static int do_probe (ide_dev_t *dev, byte cmd)
#endif
OUT_BYTE(dev->select.all,HD_CURRENT); /* select target drive */
delay_10ms(); /* wait for BUSY_STAT */
if (IN_BYTE(HD_CURRENT,DEV_HWIF) != dev->select.all && !dev->present)
return 0; /* no i/f present: avoid killing ethernet cards */
if (IN_BYTE(HD_CURRENT,DEV_HWIF) != dev->select.all && !dev->present) {
OUT_BYTE(0xa0,HD_CURRENT); /* exit with drive0 selected */
return 3; /* no i/f present: avoid killing ethernet cards */
}
if (OK_STAT(GET_STAT(DEV_HWIF),READY_STAT,BUSY_STAT)
|| dev->present || cmd == WIN_PIDENTIFY)
{
if ((rc = try_to_identify(dev, cmd))) /* send cmd and wait */
rc = try_to_identify(dev, cmd); /* try again */
if (rc)
printk("%s: identification %s\n", dev->name,
(rc == 1) ? "refused" : "timed-out");
if ((rc = try_to_identify(dev, cmd))) /* send cmd and wait */
rc = try_to_identify(dev, cmd); /* failed: try again */
if (rc == 1)
printk("%s: no response\n", dev->name);
OUT_BYTE(dev->ctl|2,HD_CMD); /* disable device irq */
delay_10ms();
(void) GET_STAT(DEV_HWIF); /* ensure drive irq is clear */
} else {
rc = 2; /* drive not present */
rc = 3; /* not present or maybe ATAPI */
}
if (dev->select.b.drive == 1) {
OUT_BYTE(0xa0,HD_CURRENT); /* exit with drive0 selected */
......@@ -1821,16 +1839,20 @@ static int do_probe (ide_dev_t *dev, byte cmd)
}
static byte probe_for_drive (ide_dev_t *dev)
/*
* Returns: 0 no device was found
* 1 device was found (note: dev->present might still be 0)
*/
{
if (dev->dont_probe) /* skip probing? */
return dev->present;
if (do_probe(dev, WIN_IDENTIFY) == 1) { /* 1 = drive aborted the cmd */
if (do_probe(dev, WIN_IDENTIFY) >= 2) { /* if !(success || timed-out) */
#ifdef CONFIG_BLK_DEV_IDECD
(void) do_probe(dev, WIN_PIDENTIFY);
(void) do_probe(dev, WIN_PIDENTIFY); /* look for ATAPI device */
#endif /* CONFIG_BLK_DEV_IDECD */
}
if (!dev->present)
return 0; /* drive not present */
return 0; /* drive not found */
if (dev->id == NULL) { /* identification failed? */
if (dev->type == disk) {
printk ("%s: non-IDE device, CHS=%d/%d/%d\n",
......@@ -1843,7 +1865,7 @@ static byte probe_for_drive (ide_dev_t *dev)
#endif /* CONFIG_BLK_DEV_IDECD */
else {
dev->present = 0; /* nuke it */
return 0; /* drive not present */
return 1; /* drive was found */
}
}
#ifdef CONFIG_BLK_DEV_IDECD
......@@ -1857,7 +1879,7 @@ static byte probe_for_drive (ide_dev_t *dev)
dev->present = 0;
}
}
return 1; /* drive present */
return 1; /* drive was found */
}
static void probe_for_drives (byte hwif)
......@@ -1877,15 +1899,15 @@ static void probe_for_drives (byte hwif)
save_flags(flags);
sti(); /* needed for jiffies and irq probing */
/* second drive can only exist if first drive was present */
/* second drive should only exist if first drive was found */
if (probe_for_drive(&devs[0]) || devs[1].present)
(void) probe_for_drive(&devs[1]);
#if PROBE_FOR_IRQS
(void) probe_irq_off(probe_irq_on()); /* clear dangling irqs */
#endif /* PROBE_FOR_IRQS */
if (devs[0].present || devs[1].present) {
request_region(IDE_PORT(HD_DATA,HWIF),8,"ide");
request_region(IDE_PORT(HD_CMD,HWIF),1,"ide");
request_region(IDE_PORT(HD_DATA,HWIF),8,ide_name[HWIF]);
request_region(IDE_PORT(HD_CMD,HWIF),1,ide_name[HWIF]);
}
restore_flags(flags);
}
......
This diff is collapsed.
/*
* duplication of sbpcd.c for multiple interfaces
*/
#define SBPCD_ISSUE 2
#include "sbpcd.c"
/*
* duplication of sbpcd.c for multiple interfaces
*/
#define SBPCD_ISSUE 3
#include "sbpcd.c"
/*
* duplication of sbpcd.c for multiple interfaces
*/
#define SBPCD_ISSUE 4
#include "sbpcd.c"
......@@ -99,11 +99,12 @@ static char *version =
#include <linux/malloc.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
......
Tue Jan 10 10:09:58 1995 Eric Youngdale (eric@andante)
* Linux 1.1.79 released.
Patch from some undetermined individual who needs to get a life :-).
* sr.c: Attacked by spelling bee...
Patches from Gerd Knorr:
* sr.c: make printk messages for photoCD a little more informative.
* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
Mon Jan 9 10:01:37 1995 Eric Youngdale (eric@andante)
* Linux 1.1.78 released.
* Makefile: Add empty modules: target.
* Wheee. Now change register_iomem to request_region.
* in2000.c: Bugfix - apparently this is the fix that we have
all been waiting for. It fixes a problem whereby the driver
is not stable under heavy load. Race condition and all that.
Patch from Peter Lu.
Wed Jan 4 21:17:40 1995 Eric Youngdale (eric@andante)
* Linux 1.1.77 released.
* 53c7,8xx.c: Fix from Linus - emulate splx.
Throughout:
Change "snarf_region" with "register_iomem".
* scsi_module.c: New file. Contains support for low-level loadable
scsi drivers. [ERY].
* sd.c: More s/int/long/ changes.
* seagate.c: Explicitly include linux/config.h
* sg.c: Increment/decrement module usage count on open/close.
* sg.c: Be a bit more careful about the user not supplying enough
information for a valid command. Pass correct size down to
scsi_do_cmd.
* sr.c: More changes for Photo-CD. This apparently breaks NEC drives.
* sr_ioctl.c: Support CDROMMULTISESSION ioctl.
Sun Jan 1 19:55:21 1995 Eric Youngdale (eric@andante)
* Linux 1.1.76 released.
* constants.c: Add type cast in switch statement.
* scsi.c (scsi_free): Change datatype of "offset" to long.
(scsi_malloc): Change a few more variables to long. Who
did this and why was it important? 64 bit machines?
Lots of changes to use save_state/restore_state instead of cli/sti.
Files changed include:
* aha1542.c:
* aha1740.c:
* buslogic.c:
* in2000.c:
* scsi.c:
* scsi_debug.c:
* sd.c:
* sr.c:
* st.c:
Wed Dec 28 16:38:29 1994 Eric Youngdale (eric@andante)
* Linux 1.1.75 released.
* buslogic.c: Spelling fix.
* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
* scsi.c: Spelling fixup.
* sd.c: Add support for sd_hardsizes (hard sector sizes).
* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
Fri Dec 23 13:36:25 1994 Eric Youngdale (eric@andante)
* Linux 1.1.74 released.
* README.st: Update from Kai Makisara.
* eata.c: New version from Dario - version 1.11.
use scsicam bios_param routine. Add support for 2011
and 2021 boards.
* hosts.c: Add support for blocking. Linked list automatically
generated when shpnt->block is set.
* scsi.c: Add sankyo & HP scanjet to blacklist. Add support for
kicking things loose when we deadlock.
* scsi.c: Recognize scanners and processors in scan_scsis.
* scsi_ioctl.h: Increase timeout to 9 seconds.
* st.c: New version from Kai - add better support for backspace.
* u14-34f.c: New version from Dario. Supports blocking.
Wed Dec 14 14:46:30 1994 Eric Youngdale (eric@andante)
* Linux 1.1.73 released.
* buslogic.c: Update from Dave Gentzel. Version 1.14.
Add module related stuff. More fault tolerant if out of
DMA memory.
* fdomain.c: New version from Rik Faith - version 5.22. Add support
for ISA-200S SCSI adapter.
* hosts.c: Spelling.
* qlogic.c: Update to version 0.38a. Add more support for PCMIA.
* scsi.c: Mask device type with 0x1f during scan_scsis.
Add support for deadlocking, err, make that getting out of
deadlock situations that are created when we allow the user
to limit requests to one host adapter at a time.
* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
scsi_times_out.
* scsi.c: Restore interrupt state to previous value instead of using
cli/sti pairs.
* scsi.c: Add a bunch of module stuff (all commented out for now).
* scsi.c: Clean up scsi_dump_status.
Tue Dec 6 12:34:20 1994 Eric Youngdale (eric@andante)
* Linux 1.1.72 released.
......
......@@ -25,6 +25,7 @@ endif
SCSI_OBJS =
SCSI_SRCS =
SCSI_MODULE_OBJS =
ifdef CONFIG_SCSI
......@@ -61,9 +62,11 @@ SCSI_OBJS := $(SCSI_OBJS) aha152x.o
SCSI_SRCS := $(SCSI_SRCS) aha152x.c
endif
SCSI_SRCS := $(SCSI_SRCS) aha1542.c
ifdef CONFIG_SCSI_AHA1542
SCSI_OBJS := $(SCSI_OBJS) aha1542.o
SCSI_SRCS := $(SCSI_SRCS) aha1542.c
else
SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) aha1542.o
endif
ifdef CONFIG_SCSI_AHA1740
......@@ -81,14 +84,21 @@ SCSI_OBJS := $(SCSI_OBJS) buslogic.o
SCSI_SRCS := $(SCSI_SRCS) buslogic.c
endif
ifdef CONFIG_SCSI_EATA_DMA
SCSI_OBJS := $(SCSI_OBJS) eata_dma.o
SCSI_SRCS := $(SCSI_SRCS) eata_dma.c
endif
ifdef CONFIG_SCSI_U14_34F
SCSI_OBJS := $(SCSI_OBJS) u14-34f.o
SCSI_SRCS := $(SCSI_SRCS) u14-34f.c
endif
SCSI_SRCS := $(SCSI_SRCS) scsi_debug.c
ifdef CONFIG_SCSI_DEBUG
SCSI_OBJS := $(SCSI_OBJS) scsi_debug.o
SCSI_SRCS := $(SCSI_SRCS) scsi_debug.c
else
SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) scsi_debug.o
endif
ifdef CONFIG_SCSI_FUTURE_DOMAIN
......@@ -96,9 +106,11 @@ SCSI_OBJS := $(SCSI_OBJS) fdomain.o
SCSI_SRCS := $(SCSI_SRCS) fdomain.c
endif
SCSI_SRCS := $(SCSI_SRCS) in2000.c
ifdef CONFIG_SCSI_IN2000
SCSI_OBJS := $(SCSI_OBJS) in2000.o
SCSI_SRCS := $(SCSI_SRCS) in2000.c
else
SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) in2000.o
endif
ifdef CONFIG_SCSI_GENERIC_NCR5380
......@@ -175,6 +187,10 @@ seagate.o: seagate.c
mv scriptu.h 53c8xx_u.h
rm fake.c
modules: $(SCSI_MODULE_OBJS)
echo $(SCSI_MODULE_OBJS) > ../../modules/SCSI_MODULES
(cd ../../modules;for i in $(SCSI_MODULE_OBJS); do ln -sf ../drivers/scsi/$$i .; done)
dep:
$(CPP) -M $(AHA152X) $(SCSI_SRCS) > .depend
......@@ -189,8 +205,6 @@ dep:
endif
modules:
#
# include a dependency file if one exists
#
......
This file contains brief information about the SCSI tape driver.
Last modified: Sat Dec 17 13:38:43 1994 by root@kai.home
Last modified: Tue Jan 10 21:32:35 1995 by root@kai.home
BASICS
......@@ -107,7 +107,8 @@ MTSETDRVBUFFER
Sets the buffering options. The bits are the new states
(enabled/disabled) of the write buffering (MT_ST_BUFFER_WRITES),
asynchronous writes (MT_ST_ASYNC_WRITES), read ahead
(MT_ST_READ_AHEAD), writing of two filemark (ST_TWO_FM), and
(MT_ST_READ_AHEAD), writing of two filemark (ST_TWO_FM),
using the SCSI spacing to EOD (MT_ST_FAST_EOM), and
debugging (MT_ST_DEBUGGING ; debugging must be compiled into the
driver).
MT_ST_WRITE_THRESHOLD
......@@ -142,6 +143,12 @@ is defined.
Immediate return from tape positioning SCSI commands can be enabled by
defining ST_NOWAIT.
The MTEOM command is by default implemented as spacing over 32767
filemarks. With this method the file number in the status is
correct. The user can request using direct spacing to EOD by setting
ST_FAST_EOM 1 (or using the MTSTOPTIONS ioctl). In this case the file
number will be invalid.
When using read ahead or buffered writes the position within the file
may not be correct after the file is closed (correct position may
require backspacing over more than one record). The correct position
......
This diff is collapsed.
This diff is collapsed.
......@@ -47,6 +47,10 @@
#include "buslogic.h"
#endif
#ifdef CONFIG_SCSI_EATA_DMA
#include "eata_dma.h"
#endif
#ifdef CONFIG_SCSI_U14_34F
#include "u14-34f.h"
#endif
......@@ -178,6 +182,9 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_NCR53C7xx
NCR53c7xx,
#endif
#ifdef CONFIG_SCSI_EATA_DMA
EATA_DMA,
#endif
#ifdef CONFIG_SCSI_7000FASST
WD7000,
#endif
......@@ -199,7 +206,7 @@ struct Scsi_Host * scsi_hostlist = NULL;
struct Scsi_Device_Template * scsi_devicelist;
int max_scsi_hosts = 0;
static int next_host = 0;
int next_scsi_host = 0;
void
scsi_unregister(struct Scsi_Host * sh){
......@@ -215,7 +222,7 @@ scsi_unregister(struct Scsi_Host * sh){
while(shpnt->next != sh) shpnt = shpnt->next;
shpnt->next = shpnt->next->next;
};
next_host--;
next_scsi_host--;
scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + j);
}
......@@ -225,13 +232,14 @@ scsi_unregister(struct Scsi_Host * sh){
struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
struct Scsi_Host * retval, *shpnt;
retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j);
retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j,
(tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC);
retval->host_busy = 0;
retval->block = NULL;
if(j > 0xffff) panic("Too many extra bytes requested\n");
retval->extra_bytes = j;
retval->loaded_as_module = scsi_loadable_module_flag;
retval->host_no = next_host++;
retval->host_no = next_scsi_host++;
retval->host_queue = NULL;
retval->host_wait = NULL;
retval->last_reset = 0;
......@@ -241,7 +249,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
retval->hostt = tpnt;
retval->next = NULL;
#ifdef DEBUG
printk("Register %x %x: %d\n", retval, retval->hostt, j);
printk("Register %x %x: %d\n", (int)retval, (int)retval->hostt, j);
#endif
/* The next four are the default values which can be overridden
......@@ -276,9 +284,10 @@ scsi_register_device(struct Scsi_Device_Template * sdpnt)
unsigned int scsi_init()
{
static int called = 0;
int i, j, count, pcount;
int i, pcount;
Scsi_Host_Template * tpnt;
count = 0;
struct Scsi_Host * shpnt;
const char * name;
if(called) return 0;
......@@ -290,28 +299,37 @@ unsigned int scsi_init()
* "inactive" - where as 0 will indicate a time out condition.
*/
pcount = next_host;
pcount = next_scsi_host;
if ((tpnt->detect) &&
(tpnt->present =
tpnt->detect(tpnt)))
{
/* The only time this should come up is when people use
some kind of patched driver of some kind or another. */
if(pcount == next_host) {
if(pcount == next_scsi_host) {
if(tpnt->present > 1)
panic("Failure to register low-level scsi driver");
/* The low-level driver failed to register a driver. We
can do this now. */
can do this now. */
scsi_register(tpnt,0);
};
tpnt->next = scsi_hosts;
scsi_hosts = tpnt;
for(j = 0; j < tpnt->present; j++)
printk ("scsi%d : %s\n",
count++, tpnt->name);
}
}
printk ("scsi : %d hosts.\n", count);
for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
{
if(shpnt->hostt->info)
name = shpnt->hostt->info(shpnt);
else
name = shpnt->hostt->name;
printk ("scsi%d : %s\n", /* And print a little message */
shpnt->host_no, name);
}
printk ("scsi : %d hosts.\n", next_scsi_host);
{
int block_count = 0, index;
......@@ -351,7 +369,7 @@ unsigned int scsi_init()
scsi_register_device(&sg_template);
#endif
max_scsi_hosts = count;
max_scsi_hosts = next_scsi_host;
return 0;
}
......
......@@ -292,9 +292,12 @@ extern Scsi_Host_Template * scsi_hosts;
looks normal. Also, it makes it possible to use the same code for a
loadable module. */
extern void * scsi_init_malloc(unsigned int size);
extern void * scsi_init_malloc(unsigned int size, int priority);
extern void scsi_init_free(char * ptr, unsigned int size);
void scan_scsis (struct Scsi_Host * shpnt);
extern int next_scsi_host;
extern int scsi_loadable_module_flag;
unsigned int scsi_init(void);
......@@ -317,7 +320,7 @@ struct Scsi_Device_Template
int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
void (*init)(void); /* Sizes arrays based upon number of devices detected */
void (*finish)(void); /* Perform initialization after attachment */
void (*attach)(Scsi_Device *); /* Attach devices to arrays */
int (*attach)(Scsi_Device *); /* Attach devices to arrays */
void (*detach)(Scsi_Device *);
};
......@@ -328,4 +331,26 @@ extern struct Scsi_Device_Template sg_template;
int scsi_register_device(struct Scsi_Device_Template * sdpnt);
/* These are used by loadable modules */
extern int scsi_register_module(int, void *);
extern void scsi_unregister_module(int, void *);
/* The different types of modules that we can load and unload */
#define MODULE_SCSI_HA 1
#define MODULE_SCSI_CONST 2
#define MODULE_SCSI_IOCTL 3
#define MODULE_SCSI_DEV 4
/*
* This is an ugly hack. If we expect to be able to load devices at run time, we need
* to leave extra room in some of the data structures. Doing a realloc to enlarge
* the structures would be riddled with race conditions, so until a better solution
* is discovered, we use this crude approach
*/
#define SD_EXTRA_DEVS 2
#define ST_EXTRA_DEVS 2
#define SR_EXTRA_DEVS 2
#define SG_EXTRA_DEVS (SD_EXTRA_DEVS + SR_EXTRA_DEVS + ST_EXTRA_DEVS)
#endif
This diff is collapsed.
......@@ -30,7 +30,7 @@
*/
#include <linux/module.h>
#include "../../tools/version.h"
#include <linux/version.h>
char kernel_version[] = UTS_RELEASE;
......
......@@ -45,8 +45,9 @@ static const char RCSid[] = "$Header:";
SC->device->type != TYPE_MOD)
struct hd_struct * sd;
int revalidate_scsidisk(int dev, int maxusage);
Scsi_Disk * rscsi_disks;
Scsi_Disk * rscsi_disks = NULL;
static int * sd_sizes;
static int * sd_blocksizes;
static int * sd_hardsizes; /* Hardware sector size */
......@@ -62,13 +63,14 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt);
static void sd_init(void);
static void sd_finish(void);
static void sd_attach(Scsi_Device *);
static int sd_attach(Scsi_Device *);
static int sd_detect(Scsi_Device *);
static void sd_detach(Scsi_Device *);
struct Scsi_Device_Template sd_template = {NULL, "disk", "sd", TYPE_DISK,
SCSI_DISK_MAJOR, 0, 0, 0, 1,
sd_detect, sd_init,
sd_finish, sd_attach, NULL};
sd_finish, sd_attach, sd_detach};
static int sd_open(struct inode * inode, struct file * filp)
{
......@@ -90,6 +92,8 @@ static int sd_open(struct inode * inode, struct file * filp)
sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
};
rscsi_disks[target].device->access_count++;
if (rscsi_disks[target].device->host->hostt->usage_count)
(*rscsi_disks[target].device->host->hostt->usage_count)++;
return 0;
}
......@@ -101,6 +105,8 @@ static void sd_release(struct inode * inode, struct file * file)
target = DEVICE_NR(MINOR(inode->i_rdev));
rscsi_disks[target].device->access_count--;
if (rscsi_disks[target].device->host->hostt->usage_count)
(*rscsi_disks[target].device->host->hostt->usage_count)--;
if(rscsi_disks[target].device->removable) {
if(!rscsi_disks[target].device->access_count)
......@@ -147,7 +153,10 @@ static void sd_geninit (void)
for (i = 0; i < sd_template.dev_max; ++i)
if(rscsi_disks[i].device)
sd[i << 4].nr_sects = rscsi_disks[i].capacity;
#if 0
/* No longer needed - we keep track of this as we attach/detach */
sd_gendisk.nr_real = sd_template.dev_max;
#endif
}
/*
......@@ -1048,22 +1057,24 @@ static void sd_init()
}
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
if(rscsi_disks) return;
sd_template.dev_max = sd_template.dev_noticed;
sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
rscsi_disks = (Scsi_Disk *)
scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk));
scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
sizeof(int));
sizeof(int), GFP_ATOMIC);
memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
sizeof(int));
sizeof(int), GFP_ATOMIC);
sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
sizeof(int));
sizeof(struct hd_struct), GFP_ATOMIC);
for(i=0;i<(sd_template.dev_max << 4);i++){
sd_blocksizes[i] = 1024;
sd_hardsizes[i] = 512;
......@@ -1071,7 +1082,8 @@ static void sd_init()
blksize_size[MAJOR_NR] = sd_blocksizes;
hardsect_size[MAJOR_NR] = sd_hardsizes;
sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
sizeof(struct hd_struct));
sizeof(struct hd_struct),
GFP_ATOMIC);
sd_gendisk.max_nr = sd_template.dev_max;
......@@ -1085,28 +1097,37 @@ static void sd_finish()
{
int i;
for (i = 0; i < sd_template.dev_max; ++i)
if (rscsi_disks[i].device) i = sd_init_onedisk(i);
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
sd_gendisk.next = gendisk_head;
gendisk_head = &sd_gendisk;
for (i = 0; i < sd_template.dev_max; ++i)
if (!rscsi_disks[i].capacity &&
rscsi_disks[i].device)
{
i = sd_init_onedisk(i);
if (scsi_loadable_module_flag
&& !rscsi_disks[i].has_part_table) {
sd_sizes[i << 4] = rscsi_disks[i].capacity;
revalidate_scsidisk(i << 4, 0);
}
rscsi_disks[i].has_part_table = 1;
}
/* If our host adapter is capable of scatter-gather, then we increase
the read-ahead to 16 blocks (32 sectors). If not, we use
a two block (4 sector) read ahead. */
if(rscsi_disks[0].device->host->sg_tablesize)
if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)
read_ahead[MAJOR_NR] = 120;
/* 64 sector read-ahead */
else
read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */
sd_gendisk.next = gendisk_head;
gendisk_head = &sd_gendisk;
return;
}
static int sd_detect(Scsi_Device * SDp){
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return 0;
if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n",
......@@ -1117,17 +1138,17 @@ static int sd_detect(Scsi_Device * SDp){
}
static void sd_attach(Scsi_Device * SDp){
static int sd_attach(Scsi_Device * SDp){
Scsi_Disk * dpnt;
int i;
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return;
if(sd_template.nr_dev >= sd_template.dev_max)
panic ("scsi_devices corrupt (sd)");
if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
if(sd_template.nr_dev >= sd_template.dev_max) {
SDp->attached--;
return 1;
}
for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)
if(!dpnt->device) break;
......@@ -1135,8 +1156,11 @@ static void sd_attach(Scsi_Device * SDp){
SDp->scsi_request_fn = do_sd_request;
rscsi_disks[i].device = SDp;
rscsi_disks[i].has_part_table = 0;
sd_template.nr_dev++;
};
sd_gendisk.nr_real++;
return 0;
}
#define DEVICE_BUSY rscsi_disks[target].device->busy
#define USAGE rscsi_disks[target].device->access_count
......@@ -1199,3 +1223,40 @@ static int fop_revalidate_scsidisk(dev_t dev){
return revalidate_scsidisk(dev, 0);
}
static void sd_detach(Scsi_Device * SDp)
{
Scsi_Disk * dpnt;
int i;
int max_p;
int major;
int start;
for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)
if(dpnt->device == SDp) {
/* If we are disconnecting a disk driver, sync and invalidate everything */
max_p = sd_gendisk.max_p;
start = i << sd_gendisk.minor_shift;
major = MAJOR_NR << 8;
for (i=max_p - 1; i >=0 ; i--) {
sync_dev(major | start | i);
invalidate_inodes(major | start | i);
invalidate_buffers(major | start | i);
sd_gendisk.part[start+i].start_sect = 0;
sd_gendisk.part[start+i].nr_sects = 0;
sd_sizes[start+i] = 0;
};
dpnt->has_part_table = 0;
dpnt->device = NULL;
dpnt->capacity = 0;
SDp->attached--;
sd_template.dev_noticed--;
sd_template.nr_dev--;
sd_gendisk.nr_real--;
return;
}
return;
}
......@@ -26,14 +26,15 @@
#include "sg.h"
static void sg_init(void);
static void sg_attach(Scsi_Device *);
static int sg_attach(Scsi_Device *);
static int sg_detect(Scsi_Device *);
static void sg_detach(Scsi_Device *);
struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", 0xff,
SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
sg_detect, sg_init,
NULL, sg_attach, NULL};
NULL, sg_attach, sg_detach};
#ifdef SG_BIG_BUFF
static char *big_buff;
......@@ -334,9 +335,6 @@ static struct file_operations sg_fops = {
static int sg_detect(Scsi_Device * SDp){
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return 0;
++sg_template.dev_noticed;
return 1;
}
......@@ -358,33 +356,36 @@ static void sg_init()
sg_registered++;
}
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
/* If we have already been through here, return */
if(scsi_generics) return;
#ifdef DEBUG
printk("sg: Init generic device.\n");
#endif
#ifdef SG_BIG_BUFF
big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF);
big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
#endif
scsi_generics = (struct scsi_generic *)
scsi_init_malloc(sg_template.dev_noticed * sizeof(struct scsi_generic));
memset(scsi_generics, 0, sg_template.dev_noticed * sizeof(struct scsi_generic));
scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
* sizeof(struct scsi_generic), GFP_ATOMIC);
memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
* sizeof(struct scsi_generic));
sg_template.dev_max = sg_template.dev_noticed;
}
static void sg_attach(Scsi_Device * SDp)
static int sg_attach(Scsi_Device * SDp)
{
struct scsi_generic * gpnt;
int i;
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
if(sg_template.nr_dev >= sg_template.dev_max)
panic ("scsi_devices corrupt (sg)");
{
SDp->attached--;
return 1;
}
for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
if(!gpnt->device) break;
......@@ -401,4 +402,22 @@ static void sg_attach(Scsi_Device * SDp)
scsi_generics[i].pending=0;
scsi_generics[i].timeout=SG_DEFAULT_TIMEOUT;
sg_template.nr_dev++;
return 0;
};
static void sg_detach(Scsi_Device * SDp)
{
struct scsi_generic * gpnt;
int i;
for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
if(gpnt->device == SDp) {
gpnt->device = NULL;
SDp->attached--;
sg_template.nr_dev--;
return;
}
return;
}
......@@ -35,13 +35,14 @@
static void sr_init(void);
static void sr_finish(void);
static void sr_attach(Scsi_Device *);
static int sr_attach(Scsi_Device *);
static int sr_detect(Scsi_Device *);
static void sr_detach(Scsi_Device *);
struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", TYPE_ROM,
SCSI_CDROM_MAJOR, 0, 0, 0, 1,
sr_detect, sr_init,
sr_finish, sr_attach, NULL};
sr_finish, sr_attach, sr_detach};
Scsi_CD * scsi_CDs;
static int * sr_sizes;
......@@ -61,6 +62,8 @@ static void sr_release(struct inode * inode, struct file * file)
sync_dev(inode->i_rdev);
if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
(*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)--;
}
static struct file_operations sr_fops =
......@@ -413,6 +416,8 @@ static int sr_open(struct inode * inode, struct file * filp)
if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
(*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
/* If this device did not have media in the drive at boot time, then
we would have been unable to get the sector size. Check to see if
......@@ -795,8 +800,6 @@ are any multiple of 512 bytes long. */
static int sr_detect(Scsi_Device * SDp){
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return 0;
if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n",
......@@ -806,17 +809,17 @@ static int sr_detect(Scsi_Device * SDp){
return 1;
}
static void sr_attach(Scsi_Device * SDp){
static int sr_attach(Scsi_Device * SDp){
Scsi_CD * cpnt;
int i;
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return;
if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
if (sr_template.nr_dev >= sr_template.dev_max)
panic ("scsi_devices corrupt (sr)");
{
SDp->attached--;
return 1;
}
for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
if(!cpnt->device) break;
......@@ -828,6 +831,7 @@ static void sr_attach(Scsi_Device * SDp){
sr_template.nr_dev++;
if(sr_template.nr_dev > sr_template.dev_max)
panic ("scsi_devices corrupt (sr)");
return 0;
}
......@@ -923,20 +927,20 @@ static void sr_init()
printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
return;
}
sr_registered++;
}
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
sr_template.dev_max = sr_template.dev_noticed;
scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD));
if (scsi_CDs) return;
sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int));
sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max *
sizeof(int));
sizeof(int), GFP_ATOMIC);
for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
blksize_size[MAJOR_NR] = sr_blocksizes;
......@@ -946,26 +950,61 @@ void sr_finish()
{
int i;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blk_size[MAJOR_NR] = sr_sizes;
for (i = 0; i < sr_template.nr_dev; ++i)
{
/* If we have already seen this, then skip it. Comes up
with loadable modules. */
if (scsi_CDs[i].capacity) continue;
get_sectorsize(i);
printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
scsi_CDs[i].use = 1;
scsi_CDs[i].ten = 1;
scsi_CDs[i].remap = 1;
sr_sizes[i] = scsi_CDs[i].capacity;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blk_size[MAJOR_NR] = sr_sizes;
/* If our host adapter is capable of scatter-gather, then we increase
the read-ahead to 16 blocks (32 sectors). If not, we use
a two block (4 sector) read ahead. */
if(scsi_CDs[0].device->host->sg_tablesize)
if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
read_ahead[MAJOR_NR] = 32; /* 32 sector read-ahead. Always removable. */
else
read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */
return;
}
static void sr_detach(Scsi_Device * SDp)
{
Scsi_CD * cpnt;
int i, major;
major = MAJOR_NR << 8;
for(cpnt = scsi_CDs, i=0; i<sg_template.dev_max; i++, cpnt++)
if(cpnt->device == SDp) {
/*
* Since the cdrom is read-only, no need to sync the device.
* We should be kind to our buffer cache, however.
*/
invalidate_inodes(major | i);
invalidate_buffers(major | i);
/*
* Reset things back to a sane state so that one can re-load a new
* driver (perhaps the same one).
*/
cpnt->device = NULL;
cpnt->capacity = 0;
SDp->attached--;
sr_template.nr_dev--;
sr_template.dev_noticed--;
sr_sizes[i] = 0;
return;
}
return;
}
......@@ -5,13 +5,13 @@
History:
Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
Contribution and ideas from several people including (in alphabetical
order) Klaus Ehrenfried, Wolfgang Denk, Andreas Koppenh"ofer, J"org Weule,
and Eric Youngdale.
order) Klaus Ehrenfried, Steve Hirsch, Wolfgang Denk, Andreas Koppenh"ofer,
J"org Weule, and Eric Youngdale.
Copyright 1992, 1993, 1994 Kai Makisara
email makisara@vtinsx.ins.vtt.fi or Kai.Makisara@vtt.fi
Copyright 1992, 1993, 1994, 1995 Kai Makisara
email Kai.Makisara@metla.fi
Last modified: Sun Dec 18 10:15:33 1994 by root@kai.home
Last modified: Wed Jan 11 22:02:20 1995 by root@kai.home
*/
#include <linux/fs.h>
......@@ -43,6 +43,8 @@
#define ST_TWO_FM 0
#define ST_FAST_MTEOM 0
#define ST_BUFFER_WRITES 1
#define ST_ASYNC_WRITES 1
......@@ -86,13 +88,14 @@ static int st_max_buffers = ST_MAX_BUFFERS;
static Scsi_Tape * scsi_tapes;
static void st_init(void);
static void st_attach(Scsi_Device *);
static int st_attach(Scsi_Device *);
static int st_detect(Scsi_Device *);
static void st_detach(Scsi_Device *);
struct Scsi_Device_Template st_template = {NULL, "tape", "st", TYPE_TAPE,
SCSI_TAPE_MAJOR, 0, 0, 0, 0,
st_detect, st_init,
NULL, st_attach, NULL};
NULL, st_attach, st_detach};
static int st_int_ioctl(struct inode * inode,struct file * file,
unsigned int cmd_in, unsigned long arg);
......@@ -366,7 +369,6 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next)
STp->block_size;
(STp->buffer)->buffer_bytes = 0;
(STp->buffer)->read_pointer = 0;
STp->drv_block -= backspace;
result = 0;
if (!seek_next) {
if ((STp->eof == ST_FM) && !STp->eof_hit) {
......@@ -592,6 +594,9 @@ scsi_tape_open(struct inode * inode, struct file * filp)
#endif
}
if (scsi_tapes[dev].device->host->hostt->usage_count)
(*scsi_tapes[dev].device->host->hostt->usage_count)++;
return 0;
}
......@@ -671,6 +676,9 @@ scsi_tape_close(struct inode * inode, struct file * filp)
(STp->buffer)->in_use = 0;
STp->in_use = 0;
if (scsi_tapes[dev].device->host->hostt->usage_count)
(*scsi_tapes[dev].device->host->hostt->usage_count)--;
return;
}
......@@ -1164,14 +1172,15 @@ st_set_options(struct inode * inode, long options)
STp->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
STp->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
STp->two_fm = (options & MT_ST_TWO_FM) != 0;
STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
#ifdef DEBUG
debugging = (options & MT_ST_DEBUGGING) != 0;
printk(
"st%d: options: buffer writes: %d, async writes: %d, read ahead: %d\n",
dev, STp->do_buffer_writes, STp->do_async_writes,
STp->do_read_ahead);
printk(" two FMs: %d, debugging: %d\n", STp->two_fm,
debugging);
printk(" two FMs: %d, fast mteom: %d debugging: %d\n",
STp->two_fm, STp->fast_mteom, debugging);
#endif
}
else if ((options & MT_ST_OPTIONS) == MT_ST_WRITE_THRESHOLD) {
......@@ -1398,15 +1407,19 @@ st_int_ioctl(struct inode * inode,struct file * file,
fileno = blkno = at_sm = 0;
break;
case MTEOM:
/* space to the end of tape */
ioctl_result = st_int_ioctl(inode, file, MTFSF, 0x3fff);
fileno = (STp->mt_status)->mt_fileno ;
if (STp->eof == ST_EOD || STp->eof == ST_EOM_OK)
return 0;
/* The next lines would hide the number of spaced FileMarks
That's why I inserted the previous lines. I had no luck
with detecting EOM with FSF, so we go now to EOM.
Joerg Weule */
if (!STp->fast_mteom) {
/* space to the end of tape */
ioctl_result = st_int_ioctl(inode, file, MTFSF, 0x3fff);
fileno = (STp->mt_status)->mt_fileno ;
if (STp->eof == ST_EOD || STp->eof == ST_EOM_OK)
return 0;
/* The next lines would hide the number of spaced FileMarks
That's why I inserted the previous lines. I had no luck
with detecting EOM with FSF, so we go now to EOM.
Joerg Weule */
}
else
fileno = (-1);
cmd[0] = SPACE;
cmd[1] = 3;
#ifdef DEBUG
......@@ -1566,7 +1579,7 @@ st_int_ioctl(struct inode * inode,struct file * file,
else if (cmd_in == MTSETDENSITY)
STp->density = arg;
else if (cmd_in == MTEOM) {
STp->eof = ST_EOM_OK;
STp->eof = ST_EOD;
STp->eof_hit = 0;
}
else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
......@@ -1607,6 +1620,10 @@ st_int_ioctl(struct inode * inode,struct file * file,
else
STp->drv_block = (-1);
}
else if (cmd_in == MTEOM) {
(STp->mt_status)->mt_fileno = (-1);
STp->drv_block = (-1);
}
if (STp->eof == ST_NOEOF &&
(SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK)
STp->eof = ST_EOD;
......@@ -1699,7 +1716,7 @@ st_ioctl(struct inode * inode,struct file * file,
}
if (STp->eof == ST_EOM_OK || STp->eof == ST_EOM_ERROR)
(STp->mt_status)->mt_gstat |= GMT_EOT(0xffffffff);
else if (STp->eof == ST_EOD || STp->eof == ST_EOM_OK)
else if (STp->eof == ST_EOD)
(STp->mt_status)->mt_gstat |= GMT_EOD(0xffffffff);
if (STp->density == 1)
(STp->mt_status)->mt_gstat |= GMT_D_800(0xffffffff);
......@@ -1823,16 +1840,17 @@ static struct file_operations st_fops = {
NULL /* fsync */
};
static void st_attach(Scsi_Device * SDp){
static int st_attach(Scsi_Device * SDp){
Scsi_Tape * tpnt;
int i;
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
if(SDp->type != TYPE_TAPE) return;
if(SDp->type != TYPE_TAPE) return 1;
if(st_template.nr_dev >= st_template.dev_max)
panic ("scsi_devices corrupt (st)");
{
SDp->attached--;
return 1;
}
for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++)
if(!tpnt->device) break;
......@@ -1840,13 +1858,17 @@ static void st_attach(Scsi_Device * SDp){
if(i >= st_template.dev_max) panic ("scsi_devices corrupt (st)");
scsi_tapes[i].device = SDp;
if (SDp->scsi_level <= 2)
scsi_tapes[i].mt_status->mt_type = MT_ISSCSI1;
else
scsi_tapes[i].mt_status->mt_type = MT_ISSCSI2;
st_template.nr_dev++;
return 0;
};
static int st_detect(Scsi_Device * SDp){
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return 0;
static int st_detect(Scsi_Device * SDp)
{
if(SDp->type != TYPE_TAPE) return 0;
printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n",
......@@ -1874,19 +1896,18 @@ static void st_init()
st_registered++;
}
/* We do not support attaching loadable devices yet. */
if(scsi_loadable_module_flag) return;
scsi_tapes = (Scsi_Tape *) scsi_init_malloc(st_template.dev_noticed *
sizeof(Scsi_Tape));
st_template.dev_max = st_template.dev_noticed;
if (scsi_tapes) return;
scsi_tapes = (Scsi_Tape *) scsi_init_malloc(
(st_template.dev_noticed + ST_EXTRA_DEVS) *
sizeof(Scsi_Tape), GFP_ATOMIC);
st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
#ifdef DEBUG
printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
st_buffer_size, st_write_threshold);
#endif
for (i=0, SDp = scsi_devices; i < st_template.dev_noticed; ++i) {
for (i=0; i < st_template.dev_max; ++i) {
STp = &(scsi_tapes[i]);
STp->device = NULL;
STp->capacity = 0xfffff;
......@@ -1901,25 +1922,14 @@ static void st_init()
STp->do_async_writes = ST_ASYNC_WRITES;
STp->do_read_ahead = ST_READ_AHEAD;
STp->two_fm = ST_TWO_FM;
STp->fast_mteom = ST_FAST_MTEOM;
STp->write_threshold = st_write_threshold;
STp->drv_block = 0;
STp->moves_after_eof = 1;
STp->at_sm = 0;
STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget));
STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget), GFP_ATOMIC);
/* Initialize status */
memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
for (; SDp; SDp = SDp->next)
if (SDp->type == TYPE_TAPE)
break;
if (!SDp)
printk("st%d: ERROR: Not found in scsi chain.\n", i);
else {
if (SDp->scsi_level <= 2)
STp->mt_status->mt_type = MT_ISSCSI1;
else
STp->mt_status->mt_type = MT_ISSCSI2;
}
SDp = SDp->next;
}
/* Allocate the buffers */
......@@ -1927,10 +1937,15 @@ static void st_init()
if (st_nbr_buffers > st_max_buffers)
st_nbr_buffers = st_max_buffers;
st_buffers = (ST_buffer **) scsi_init_malloc(st_nbr_buffers *
sizeof(ST_buffer *));
sizeof(ST_buffer *), GFP_ATOMIC);
/* FIXME - if we are hitting this because we are loading a tape module
as a loadable driver, we should not use kmalloc - it will allocate
a 64Kb region in order to buffer about 32Kb. Try using 31 blocks
instead. */
for (i=0; i < st_nbr_buffers; i++) {
st_buffers[i] = (ST_buffer *) scsi_init_malloc(sizeof(ST_buffer) -
1 + st_buffer_size);
1 + st_buffer_size, GFP_ATOMIC | GFP_DMA);
#ifdef DEBUG
/* printk("st: Buffer address: %p\n", st_buffers[i]); */
#endif
......@@ -1939,3 +1954,19 @@ static void st_init()
}
return;
}
static void st_detach(Scsi_Device * SDp)
{
Scsi_Tape * tpnt;
int i;
for(tpnt = scsi_tapes, i=0; i<st_template.dev_max; i++, tpnt++)
if(tpnt->device == SDp) {
tpnt->device = NULL;
SDp->attached--;
st_template.nr_dev--;
st_template.dev_noticed--;
return;
}
return;
}
......@@ -38,6 +38,7 @@ typedef struct {
unsigned char do_async_writes;
unsigned char do_read_ahead;
unsigned char two_fm;
unsigned char fast_mteom;
unsigned char density;
ST_buffer * buffer;
int block_size;
......
......@@ -225,13 +225,13 @@ struct inode {
struct inode * i_hash_next, * i_hash_prev;
struct inode * i_bound_to, * i_bound_by;
struct inode * i_mount;
struct socket * i_socket;
unsigned short i_count;
unsigned short i_wcount;
unsigned short i_flags;
unsigned char i_lock;
unsigned char i_dirt;
unsigned char i_pipe;
unsigned char i_sock;
unsigned char i_seek;
unsigned char i_update;
union {
......@@ -246,6 +246,7 @@ struct inode {
struct nfs_inode_info nfs_i;
struct xiafs_inode_info xiafs_i;
struct sysv_inode_info sysv_i;
struct socket socket_i;
void * generic_ip;
} u;
};
......
/* $Id: mtio.h,v 1.13 1994/07/19 19:35:52 root Exp $
/* $Id: /usr/src/linux-1.1.64/include/linux/mtio.h at Tue Jan 10 21:02:51 1995 by root@kai.home$
*
* linux/mtio.h header file for Linux. Written by H. Bergman
*/
......@@ -220,5 +220,6 @@ struct mtpos {
#define MT_ST_READ_AHEAD 0x4
#define MT_ST_DEBUGGING 0x8
#define MT_ST_TWO_FM 0x10
#define MT_ST_FAST_MTEOM 0x20
#endif /* _LINUX_MTIO_H */
......@@ -81,8 +81,6 @@ struct socket {
struct wait_queue **wait; /* ptr to place to wait on */
struct inode *inode;
struct fasync_struct *fasync_list; /* Asynchronous wake up list */
struct socket *nextsock; /* next on the allocated socks */
struct socket *prevsock; /* precious on the allocated socks */
};
#define SOCK_INODE(S) ((S)->inode)
......
......@@ -72,6 +72,10 @@
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
revision */
#define PCI_REVISION_ID 0x08 /* Revision ID */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
......@@ -197,6 +201,9 @@ struct pci_class_type {
#define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_DEVICE_ID_ADAPTEC_2940 0x7178
#define PCI_VENDOR_ID_DPT 0x1044
#define PCI_DEVICE_ID_DPT 0xa400
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_864_1 0x88c0
#define PCI_DEVICE_ID_S3_864_2 0x88c1
......@@ -261,10 +268,11 @@ struct pci_vendor_type {
};
#define PCI_VENDOR_NUM 17
#define PCI_VENDOR_NUM 18
#define PCI_VENDOR_TYPE { \
{PCI_VENDOR_ID_NCR, "NCR"}, \
{PCI_VENDOR_ID_ADAPTEC, "Adaptec"}, \
{PCI_VENDOR_ID_DPT, "DPT"}, \
{PCI_VENDOR_ID_S3, "S3 Inc."}, \
{PCI_VENDOR_ID_OPTI, "OPTI"}, \
{PCI_VENDOR_ID_UMC, "UMC"}, \
......@@ -289,13 +297,14 @@ struct pci_device_type {
char *device_name;
};
#define PCI_DEVICE_NUM 33
#define PCI_DEVICE_NUM 34
#define PCI_DEVICE_TYPE { \
{PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, "53c810"}, \
{PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C815, "53c815"}, \
{PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C820, "53c820"}, \
{PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C825, "53c825"}, \
{PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_2940, "2940"}, \
{PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, "SmartCache/Raid"}, \
{PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_1, "Vision 864-P"}, \
{PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_2, "Vision 864-P"}, \
{PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_928, "Vision 928-P"}, \
......@@ -327,6 +336,7 @@ struct pci_device_type {
{0,0,"UNKNOWN DEVICE.PLEASE FIND OUT AND MAIL POTTER@CAO-VLSI.IBP.FR"} \
}
/* PCI BIOS */
extern int pcibios_present (void);
......
......@@ -59,16 +59,16 @@
/* ignore the rest if you have only one interface board & driver */
#if !(SBPCD_ISSUE-2) /* second interface board: */
#define CDROM_PORT 0x0370
#define CDROM_PORT 0x0320
#define SBPRO 0
#endif
#if !(SBPCD_ISSUE-3) /* third interface board: */
#define CDROM_PORT 0x0330
#define SBPRO 0
#define CDROM_PORT 0x0630
#define SBPRO 1
#endif
#if !(SBPCD_ISSUE-4) /* fourth interface board: */
#define CDROM_PORT 0x0230
#define SBPRO 1
#define CDROM_PORT 0x0634
#define SBPRO 0
#endif
/*==========================================================================*/
......@@ -545,8 +545,7 @@ Read XA Parameter:
#define CMD1_x08 0x08
#define CMD2_x08 0x08
#define CMDT_x08 0x08
#define CMD2_xD4 0xd4
#define CMD2_xDA 0xda
#define CMD2_SETSPEED 0xda
#define CMD0_PATH_CHECK 0x00
#define CMD1_PATH_CHECK 0x00
......@@ -563,6 +562,7 @@ Read XA Parameter:
#define CMDL_READ 0x02
#define CMDT_READ 0x28
#define CMD0_READ_XA 0x03
#define CMD2_READ_XA 0xd4
#define CMDL_READ_XA 0x03 /* really ?? */
#define CMD0_READ_HEAD 0x04
#define CMD0_SPINUP 0x05
......
......@@ -98,7 +98,6 @@ extern void aha274x_setup(char *str, int *ints);
extern void buslogic_setup(char *str, int *ints);
extern void scsi_luns_setup(char *str, int *ints);
extern void sound_setup(char *str, int *ints);
extern void sock_setup(char *str, int *ints);
#ifdef CONFIG_SBPCD
extern void sbpcd_setup(char *str, int *ints);
#endif CONFIG_SBPCD
......
......@@ -57,6 +57,11 @@ extern char * ftape_big_buffer;
extern void (*do_floppy)(void);
#endif
#ifdef CONFIG_SCSI
#include "../drivers/scsi/scsi.h"
#include "../drivers/scsi/hosts.h"
#endif
extern int sys_tz;
extern int request_dma(unsigned int dmanr, char * deviceID);
extern void free_dma(unsigned int dmanr);
......@@ -267,6 +272,15 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X(dev_ioctl),
X(dev_queue_xmit),
X(dev_base),
#endif
#ifdef CONFIG_SCSI
/* Supports loadable scsi drivers */
X(scsi_register_module),
X(scsi_unregister_module),
X(scsi_free),
X(scsi_malloc),
X(scsi_register),
X(scsi_unregister),
#endif
/* Added to make file system as module */
X(set_writetime),
......
......@@ -94,7 +94,7 @@ void request_region(unsigned int from, unsigned int num, const char *name)
/*
* This is for compatibility with older drivers.
* It can be removed when all driver call the new function.
* It can be removed when all drivers call the new function.
*/
void snarf_region(unsigned int from, unsigned int num)
{
......
This diff is collapsed.
......@@ -49,7 +49,7 @@ int unix_get_info(char *buffer, char **start, off_t offset, int length)
len += sprintf(buffer, "Num RefCount Protocol Flags Type St Path\n");
for(i = 0; i < NSOCKETS; i++)
for(i = 0; i < NSOCKETS_UNIX; i++)
{
save_flags(flags);
cli();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment