Commit b5eaf6ce authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.72

parent cf996dcf
...@@ -180,6 +180,13 @@ S: 48287 Sawleaf ...@@ -180,6 +180,13 @@ S: 48287 Sawleaf
S: Fremont, California 94539 S: Fremont, California 94539
S: USA S: USA
N: Gordon Chaffee
E: chaffee@plateau.cs.berkeley.edu
D: vfat filesystem
S: 3674 Oakwood Terrace #201
S: Fremont, CA 94536
S: USA
N: Raymond Chen N: Raymond Chen
E: raymondc@microsoft.com E: raymondc@microsoft.com
D: Author of Configure script D: Author of Configure script
...@@ -235,6 +242,15 @@ S: Zuidsingel 10A ...@@ -235,6 +242,15 @@ S: Zuidsingel 10A
S: 2312 SB Leiden S: 2312 SB Leiden
S: The Netherlands S: The Netherlands
N: David Davies
E: davies@wanton.lkg.dec.com
S: Digital Equipment Corporation
S: 550 King Street
S: Littleton, MA 01460
S: U.S.A.
D: Network driver author - depca, ewrk3 and de4x5
D: Wrote shared interrupt support
N: Wayne Davison N: Wayne Davison
E: davison@borland.com E: davison@borland.com
D: Second extended file system co-designer D: Second extended file system co-designer
...@@ -378,10 +394,19 @@ N: Philip Gladstone ...@@ -378,10 +394,19 @@ N: Philip Gladstone
E: philipg@onsett.com E: philipg@onsett.com
D: Kernel / timekeeping stuff D: Kernel / timekeeping stuff
N: Miquel van Smoorenburg
E: miquels@cistron.nl
D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff.
S: Cistron Internet Services
S: PO-Box 297
S: 2400 AG, Alphen aan den Rijn
S: The Netherlands
N: Danny ter Haar N: Danny ter Haar
E: dth@cistron.nl E: dth@cistron.nl
D: /proc/procinfo, reboot on panic , kernel pre-patch tester ;) D: /proc/procinfo, reboot on panic , kernel pre-patch tester ;)
S: PObox 297 S: Cistron Internet Services
S: PO-Box 297
S: 2400 AG, Alphen aan den Rijn S: 2400 AG, Alphen aan den Rijn
S: The Netherlands S: The Netherlands
......
...@@ -1039,6 +1039,13 @@ CONFIG_SCSI_CONSTANTS ...@@ -1039,6 +1039,13 @@ CONFIG_SCSI_CONSTANTS
understand if you enable this; it will enlarge your kernel by about understand if you enable this; it will enlarge your kernel by about
12KB. If in doubt, say Y. 12KB. If in doubt, say Y.
Automatic Disk Geometery Translation
CONFIG_SCSI_AUTO_BIOSP
When this is set to Y, Linux will examine the parition table to
determine the mapping used under the other operating systems (e.g.
DOS), and set these parameters to the determined values, or if the
disk has no valid partition table, to an optimal value.
AdvanSys SCSI support AdvanSys SCSI support
CONFIG_SCSI_ADVANSYS CONFIG_SCSI_ADVANSYS
This is a driver for all SCSI host adaptors manufactured by This is a driver for all SCSI host adaptors manufactured by
...@@ -1534,6 +1541,21 @@ CONFIG_ULTRA ...@@ -1534,6 +1541,21 @@ CONFIG_ULTRA
Multiple-Ethernet-mini-HOWTO, available from Multiple-Ethernet-mini-HOWTO, available from
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
SMC 9194 Support
CONFIG_SMC9194
This has support for the SMC9xxx based Ethernet cards. Choose this option
if you have a DELL laptop with the docking station, or another SMC9192/9194
based chipset. Say Y if you want it compiled into the kernel, and read
the Ethernet-HOWTO, available via ftp (user: anonymous) in
sunsite.unc.edu:/pub/Linux/docs/HOWTO. This driver is also
available as a module ( = code which can be inserted in and removed
from the running kernel whenever you want). If you want to compile
it as a module, say M here and read Documentation/modules.txt as
well as Documentation/networking/net-modules.txt. If you plan to use
more than one network card under linux, read the
Multiple-Ethernet-mini-HOWTO, available from
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
AMD LANCE and PCnet (AT1500 and NE2100) support AMD LANCE and PCnet (AT1500 and NE2100) support
CONFIG_LANCE CONFIG_LANCE
If you have a network (ethernet) card of this type, say Y and read If you have a network (ethernet) card of this type, say Y and read
...@@ -2626,22 +2648,19 @@ CONFIG_QIC02_DYNCONF ...@@ -2626,22 +2648,19 @@ CONFIG_QIC02_DYNCONF
program via anonymous ftp which is able to configure this driver program via anonymous ftp which is able to configure this driver
during runtime. If you want this, say Y. during runtime. If you want this, say Y.
QIC-117 tape support Ftape (QIC-80/Travan) support
CONFIG_FTAPE CONFIG_FTAPE
This option is obsolete as of Linux v1.3.34. If you would like to If you have a tape drive that is connected to your floppy
use a tape drive that uses the floppy disk controller, like QIC-40, controller, say Y here. Some tape drives (like the Iomega Ditto
QIC-80, QIC-117, QIC-3010 (examples: Colorado Jumbo or Conner 3200) come with a high speed controller of its own. These drives
Tape-Stor), you want to read the Ftape-HOWTO, available via ftp (and their companion controller) is also supported. If you have a
(user: anonymous) from sunsite.unc.edu:/pub/Linux/docs/HOWTO. Then special controller (such as the CMS FC-10, FC-20, Iomega Mach-II, or
get the ftape distribution v2.04 or higher from Ditto Dash), you must configure it by editing the file
sunsite.unc.edu:/pub/Linux/kernel/tapes/. Tape drives that attach to drivers/char/ftape/Makefile. This driver is also available as a
the parallel port, like the Colorado Tracker, are not yet supported runtime loadable module ( = code which can be inserted in and
by Linux. removed from the running kernel whenever you want). If you want to
compile it as a module, say M here and read
number of ftape buffers Documentation/modules.txt.
NR_FTAPE_BUFFERS 3
This option is obsolete since Linux v1.3.34. Upgrade your ftape
distribution to v2.04.
Zilog serial support Zilog serial support
CONFIG_SUN_ZS CONFIG_SUN_ZS
......
This diff is collapsed.
The PPP support for this kernel requires the 2.2.0a version of the The PPP support for this kernel requires the 2.2.0 version of the
pppd daemon. You will find the current version of the daemon on pppd daemon. You will find the current version of the daemon on
sunsite.unc.edu in the /pub/Linux/system/Network/serial directory. sunsite.unc.edu in the /pub/Linux/system/Network/serial directory.
......
...@@ -59,13 +59,18 @@ S: Status ...@@ -59,13 +59,18 @@ S: Status
Obsolete: Ex code. Something tagged obsolete generally means Obsolete: Ex code. Something tagged obsolete generally means
its been replaced by a better system and you should its been replaced by a better system and you should
be using that. be using that.
3C501 NETWORK DRIVER 3C501 NETWORK DRIVER
P: Alan Cox P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu L: linux-net@vger.rutgers.edu
S: Maintained S: Maintained
APM DRIVER
P: Rik Faith
M: faith@cs.unc.edu
L: linux-laptop@vger.rutgers.edu
S: Maintained
APPLETALK NETWORK LAYER APPLETALK NETWORK LAYER
P: Alan Cox & University Of Michigan P: Alan Cox & University Of Michigan
M: net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu M: net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
...@@ -78,6 +83,18 @@ M: jsn@cs.nott.ac.uk ...@@ -78,6 +83,18 @@ M: jsn@cs.nott.ac.uk
L: linux-hams@vger.rutges.edu L: linux-hams@vger.rutges.edu
S: Maintained S: Maintained
FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
P: Rik Faith
M: faith@cs.unc.edu
L: linux-scsi@vger.rutgers.edu
S: Odd fixes (e.g., new signatures)
FTAPE/QIC-117:
P: Kai Harrekilde-Petersen
M: khp@pip.dknet.dk [from 960401: khp@dolphinics.no]
L: linux-tape@vger.rutgers.edu
S: Maintained
IPX NETWORK LAYER IPX NETWORK LAYER
P: Alan Cox [for the moment] P: Alan Cox [for the moment]
M: net-patches@lxorguk.ukuu.org.uk M: net-patches@lxorguk.ukuu.org.uk
...@@ -90,6 +107,12 @@ M: fritz@wuemaus.franken.de ...@@ -90,6 +107,12 @@ M: fritz@wuemaus.franken.de
L: isdn4linux@hub-wue.franken.de L: isdn4linux@hub-wue.franken.de
S: Maintained S: Maintained
MODULE SUPPORT [GENERAL], KERNELD
P: Bjorn Ekwall
M: bj0rn@blox.se
L: linux-kernel@vger.rutgers.edu
S: Maintained
NETROM NETWORK LAYER NETROM NETWORK LAYER
P: Jon Naylor P: Jon Naylor
M: jsn@cs.nott.ac.uk M: jsn@cs.nott.ac.uk
...@@ -102,6 +125,12 @@ M: net-patches@lxorguk.ukuu.org.uk ...@@ -102,6 +125,12 @@ M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu L: linux-net@vger.rutgers.edu
S: Odd Fixes <-> Maintained subject to workloads S: Odd Fixes <-> Maintained subject to workloads
PPP PROTOCOL DRIVERS AND COMPRESSORS
P: Al Longyear
M: longyear@netcom.com, Cc: longyear@sii.com
L: linux-ppp@vger.rutgers.edu
S: Maintained
SMP: SMP:
P: Alan Cox P: Alan Cox
M: smp-patches@lxorguk.ukuu.org.uk M: smp-patches@lxorguk.ukuu.org.uk
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 71 SUBLEVEL = 72
ARCH = i386 ARCH = i386
......
...@@ -145,6 +145,7 @@ CONFIG_SERIAL=y ...@@ -145,6 +145,7 @@ CONFIG_SERIAL=y
# CONFIG_MS_BUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set
# CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set # CONFIG_QIC02_TAPE is not set
# CONFIG_FTAPE is not set
# CONFIG_APM is not set # CONFIG_APM is not set
# CONFIG_WATCHDOG is not set # CONFIG_WATCHDOG is not set
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <asm/smp.h> #include <asm/smp.h>
#define CR0_NE 32 #define CR0_NE 32
#define TIMER_IRQ 0 /* Keep this in sync with time.c */
static unsigned char cache_21 = 0xff; static unsigned char cache_21 = 0xff;
static unsigned char cache_A1 = 0xff; static unsigned char cache_A1 = 0xff;
...@@ -96,8 +95,16 @@ void enable_irq(unsigned int irq_nr) ...@@ -96,8 +95,16 @@ void enable_irq(unsigned int irq_nr)
* atomic. The specific handler is chosen depending on the SA_INTERRUPT * atomic. The specific handler is chosen depending on the SA_INTERRUPT
* flag when installing a handler. Finally, one "bad interrupt" handler, that * flag when installing a handler. Finally, one "bad interrupt" handler, that
* is used when no handler is present. * is used when no handler is present.
*
* The timer interrupt is handled specially to insure that the jiffies
* variable is updated at all times. Specifically, the timer interrupt is
* just like the complete handlers except that it is invoked with interrupts
* disabled and should never re-enable them. If other interrupts were
* allowed to be processed while the timer interrupt is active, then the
* other interrupts would have to avoid using the jiffies variable for delay
* and interval timing operations to avoid hanging the system.
*/ */
BUILD_IRQ(FIRST,0,0x01) BUILD_TIMER_IRQ(FIRST,0,0x01)
BUILD_IRQ(FIRST,1,0x02) BUILD_IRQ(FIRST,1,0x02)
BUILD_IRQ(FIRST,2,0x04) BUILD_IRQ(FIRST,2,0x04)
BUILD_IRQ(FIRST,3,0x08) BUILD_IRQ(FIRST,3,0x08)
......
...@@ -34,11 +34,35 @@ static int read_ldt(void * ptr, unsigned long bytecount) ...@@ -34,11 +34,35 @@ static int read_ldt(void * ptr, unsigned long bytecount)
return size; return size;
} }
static inline int limits_ok(struct modify_ldt_ldt_s *ldt_info)
{
unsigned long base, limit;
/* linear address of first and last accessible byte */
unsigned long first, last;
base = ldt_info->base_addr;
limit = ldt_info->limit;
if (ldt_info->limit_in_pages)
limit = limit * PAGE_SIZE + PAGE_SIZE - 1;
first = base;
last = limit + base;
/* segment grows down? */
if (ldt_info->contents == 1) {
/* data segment grows down */
first = base+limit+1;
last = base+65535;
if (ldt_info->seg_32bit)
last = base-1;
}
return (last >= first && last < TASK_SIZE);
}
static int write_ldt(void * ptr, unsigned long bytecount) static int write_ldt(void * ptr, unsigned long bytecount)
{ {
struct modify_ldt_ldt_s ldt_info; struct modify_ldt_ldt_s ldt_info;
unsigned long *lp; unsigned long *lp;
unsigned long base, limit;
int error, i; int error, i;
if (bytecount != sizeof(ldt_info)) if (bytecount != sizeof(ldt_info))
...@@ -52,13 +76,7 @@ static int write_ldt(void * ptr, unsigned long bytecount) ...@@ -52,13 +76,7 @@ static int write_ldt(void * ptr, unsigned long bytecount)
if (ldt_info.contents == 3 || ldt_info.entry_number >= LDT_ENTRIES) if (ldt_info.contents == 3 || ldt_info.entry_number >= LDT_ENTRIES)
return -EINVAL; return -EINVAL;
limit = ldt_info.limit; if (!limits_ok(&ldt_info))
base = ldt_info.base_addr;
if (ldt_info.limit_in_pages)
limit *= PAGE_SIZE;
limit += base;
if (limit < base || limit >= 0xC0000000)
return -EINVAL; return -EINVAL;
if (!current->ldt) { if (!current->ldt) {
......
...@@ -20,13 +20,12 @@ ...@@ -20,13 +20,12 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h>
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/config.h> #include <linux/config.h>
#define TIMER_IRQ 0
/* Cycle counter value at the previous timer interrupt.. */ /* Cycle counter value at the previous timer interrupt.. */
static unsigned long long last_timer_cc = 0; static unsigned long long last_timer_cc = 0;
static unsigned long long init_timer_cc = 0; static unsigned long long init_timer_cc = 0;
......
...@@ -524,7 +524,7 @@ static void ide_geninit (struct gendisk *gd) ...@@ -524,7 +524,7 @@ static void ide_geninit (struct gendisk *gd)
*/ */
static void init_gendisk (ide_hwif_t *hwif) static void init_gendisk (ide_hwif_t *hwif)
{ {
struct gendisk *gd; struct gendisk *gd, **gdp;
unsigned int unit, units, minors; unsigned int unit, units, minors;
int *bs; int *bs;
...@@ -556,8 +556,9 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -556,8 +556,9 @@ static void init_gendisk (ide_hwif_t *hwif)
gd->init = ide_geninit; /* initialization function */ gd->init = ide_geninit; /* initialization function */
gd->real_devices= hwif; /* ptr to internal data */ gd->real_devices= hwif; /* ptr to internal data */
gd->next = gendisk_head; /* link new major into list */ for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ;
hwif->gd = gendisk_head = gd; gd->next = NULL; /* link to tail of list */
hwif->gd = *gdp = gd;
} }
static void do_reset1 (ide_drive_t *, int); /* needed below */ static void do_reset1 (ide_drive_t *, int); /* needed below */
...@@ -2168,6 +2169,15 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -2168,6 +2169,15 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
drive->removeable = 1; drive->removeable = 1;
} }
/* SunDisk drives: treat as non-removeable, force one unit */
if (id->model[0] == 'S' && id->model[1] == 'u') {
drive->removeable = 0;
if (drive->select.all & (1<<4)) {
drive->present = 0;
return;
}
}
drive->media = ide_disk; drive->media = ide_disk;
/* Extract geometry if we did not already have one for the drive */ /* Extract geometry if we did not already have one for the drive */
if (!drive->present) { if (!drive->present) {
...@@ -3004,54 +3014,33 @@ static void probe_for_hwifs (void) ...@@ -3004,54 +3014,33 @@ static void probe_for_hwifs (void)
#endif #endif
} }
/* static int hwif_init (int h)
* This is gets invoked once during initialization, to set *everything* up
*/
int ide_init (void)
{ {
int h;
init_ide_data ();
/*
* Probe for special "known" interface chipsets
*/
probe_for_hwifs ();
/*
* Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
*/
for (h = 0; h < MAX_HWIFS; ++h) {
ide_hwif_t *hwif = &ide_hwifs[h]; ide_hwif_t *hwif = &ide_hwifs[h];
if (!hwif->noprobe) { void (*rfn)(void);
if (hwif->noprobe)
return 0;
else {
if (hwif->io_base == HD_DATA) if (hwif->io_base == HD_DATA)
probe_cmos_for_drives (hwif); probe_cmos_for_drives (hwif);
probe_hwif (hwif); probe_hwif (hwif);
if (!hwif->present)
return 0;
} }
if (hwif->present) {
if (!hwif->irq) { if (!hwif->irq) {
if (!(hwif->irq = default_irqs[h])) { if (!(hwif->irq = default_irqs[h])) {
printk("%s: DISABLED, NO IRQ\n", hwif->name); printk("%s: DISABLED, NO IRQ\n", hwif->name);
hwif->present = 0; return (hwif->present = 0);
continue;
} }
} }
#ifdef CONFIG_BLK_DEV_HD #ifdef CONFIG_BLK_DEV_HD
if (hwif->irq == HD_IRQ && hwif->io_base != HD_DATA) { if (hwif->irq == HD_IRQ && hwif->io_base != HD_DATA) {
printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name); printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name);
hwif->present = 0; return (hwif->present = 0);
} }
#endif /* CONFIG_BLK_DEV_HD */ #endif /* CONFIG_BLK_DEV_HD */
}
}
/*
* Now we try to set up irqs and major devices for what was found
*/
for (h = MAX_HWIFS-1; h >= 0; --h) {
void (*rfn)(void);
ide_hwif_t *hwif = &ide_hwifs[h];
if (!hwif->present)
continue;
hwif->present = 0; /* we set it back to 1 if all is ok below */ hwif->present = 0; /* we set it back to 1 if all is ok below */
switch (hwif->major) { switch (hwif->major) {
case IDE0_MAJOR: rfn = &do_ide0_request; break; case IDE0_MAJOR: rfn = &do_ide0_request; break;
...@@ -3066,7 +3055,7 @@ int ide_init (void) ...@@ -3066,7 +3055,7 @@ int ide_init (void)
#endif #endif
default: default:
printk("%s: request_fn NOT DEFINED\n", hwif->name); printk("%s: request_fn NOT DEFINED\n", hwif->name);
continue; return (hwif->present = 0);
} }
if (register_blkdev (hwif->major, hwif->name, &ide_fops)) { if (register_blkdev (hwif->major, hwif->name, &ide_fops)) {
printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major); printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);
...@@ -3079,7 +3068,27 @@ int ide_init (void) ...@@ -3079,7 +3068,27 @@ int ide_init (void)
read_ahead[hwif->major] = 8; /* (4kB) */ read_ahead[hwif->major] = 8; /* (4kB) */
hwif->present = 1; /* success */ hwif->present = 1; /* success */
} }
} return hwif->present;
}
/*
* This is gets invoked once during initialization, to set *everything* up
*/
int ide_init (void)
{
int h;
init_ide_data ();
/*
* Probe for special "known" interface chipsets
*/
probe_for_hwifs ();
/*
* Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
*/
for (h = 0; h < MAX_HWIFS; ++h)
hwif_init(h);
#ifdef CONFIG_BLK_DEV_IDETAPE #ifdef CONFIG_BLK_DEV_IDETAPE
idetape_register_chrdev(); /* Register character device interface to the ide tape */ idetape_register_chrdev(); /* Register character device interface to the ide tape */
...@@ -3087,3 +3096,62 @@ int ide_init (void) ...@@ -3087,3 +3096,62 @@ int ide_init (void)
return 0; return 0;
} }
int ide_register(int io_base, int ctl_port, int irq)
{
int h, i;
ide_hwif_t *hwif;
for (h = 0; h < MAX_HWIFS; ++h) {
hwif = &ide_hwifs[h];
if (hwif->present == 0) break;
}
hwif->io_base = io_base;
hwif->ctl_port = ctl_port;
hwif->irq = irq;
hwif->noprobe = 0;
if (hwif_init(h) != 0) {
hwif->gd->real_devices = hwif->drives[0].name;
for (i = 0; i < hwif->gd->nr_real; i++)
revalidate_disk(MKDEV(hwif->major, i<<PARTN_BITS));
return h;
}
else
return -1;
}
void ide_unregister(int h)
{
struct gendisk *prev_gd, *gd;
ide_hwif_t *hwif;
if ((h < 0) || (h >= MAX_HWIFS))
return;
hwif = &ide_hwifs[h];
if (hwif->present) {
hwif->present = 0;
/* This assumes that there is only one group member */
free_irq(hwif->irq, NULL);
kfree(hwif->hwgroup);
irq_to_hwgroup[hwif->irq] = NULL;
unregister_blkdev(hwif->major, hwif->name);
kfree(blksize_size[hwif->major]);
blk_dev[hwif->major].request_fn = NULL;
blksize_size[hwif->major] = NULL;
gd = gendisk_head; prev_gd = NULL;
while (gd && (gd != hwif->gd)) {
prev_gd = gd;
gd = gd->next;
}
if (gd != hwif->gd)
printk("gd not in disk chain!\n");
else {
if (prev_gd != NULL)
prev_gd->next = gd->next;
else
gendisk_head = gd->next;
kfree(gd->sizes);
kfree(gd->part);
kfree(gd);
}
}
}
...@@ -31,6 +31,12 @@ if [ "$CONFIG_QIC02_TAPE" = "y" ]; then ...@@ -31,6 +31,12 @@ if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
comment 'ftp://titus.cfw.com/pub/Linux/util/' comment 'ftp://titus.cfw.com/pub/Linux/util/'
fi fi
fi fi
tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE
if [ "$CONFIG_FTAPE" != "n" ]; then
comment 'Set IObase/IRQ/DMA for ftape in ./drivers/char/ftape/Makefile'
fi
bool 'Advanced Power Management BIOS support' CONFIG_APM bool 'Advanced Power Management BIOS support' CONFIG_APM
if [ "$CONFIG_APM" = "y" ]; then if [ "$CONFIG_APM" = "y" ]; then
bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
# parent makes.. # parent makes..
# #
SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS) ftape
# #
# This file contains the font map for the default (hardware) font # This file contains the font map for the default (hardware) font
# #
...@@ -116,6 +120,15 @@ ifdef CONFIG_QIC02_TAPE ...@@ -116,6 +120,15 @@ ifdef CONFIG_QIC02_TAPE
L_OBJS += tpqic02.o L_OBJS += tpqic02.o
endif endif
ifeq ($(CONFIG_FTAPE),y)
SUB_DIRS += ftape
L_OBJS += ftape/ftape.o
else
ifeq ($(CONFIG_FTAPE),m)
MOD_SUB_DIRS += ftape
endif
endif
ifdef CONFIG_APM ifdef CONFIG_APM
LX_OBJS += apm_bios.o LX_OBJS += apm_bios.o
endif endif
......
...@@ -19,11 +19,15 @@ ...@@ -19,11 +19,15 @@
* Documentation * Documentation
* January 1996, Rik Faith (faith@cs.unc.edu): * January 1996, Rik Faith (faith@cs.unc.edu):
* Make /proc/apm easy to format (bump driver version) * Make /proc/apm easy to format (bump driver version)
* March 1996, Rik Faith (faith@cs.unc.edu):
* Prohibit APM BIOS calls unless apm_enabled.
* (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
* *
* History: * History:
* 0.6b: first version in official kernel, Linux 1.3.46 * 0.6b: first version in official kernel, Linux 1.3.46
* 0.7: changed /proc/apm format, Linux 1.3.58 * 0.7: changed /proc/apm format, Linux 1.3.58
* 0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59 * 0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59
* 0.9: only call bios if bios is present, Linux 1.3.72
* *
* Reference: * Reference:
* *
...@@ -307,7 +311,7 @@ static struct apm_bios_struct * user_list = NULL; ...@@ -307,7 +311,7 @@ static struct apm_bios_struct * user_list = NULL;
static struct timer_list apm_timer; static struct timer_list apm_timer;
static char driver_version[] = "0.8";/* no spaces */ static char driver_version[] = "0.9";/* no spaces */
#ifdef APM_DEBUG #ifdef APM_DEBUG
static char * apm_event_name[] = { static char * apm_event_name[] = {
...@@ -403,6 +407,7 @@ static int apm_set_power_state(u_short state) ...@@ -403,6 +407,7 @@ static int apm_set_power_state(u_short state)
} }
#ifdef CONFIG_APM_DISPLAY_BLANK #ifdef CONFIG_APM_DISPLAY_BLANK
/* Called by apm_display_blank and apm_display_unblank when apm_enabled. */
static int apm_set_display_power_state(u_short state) static int apm_set_display_power_state(u_short state)
{ {
u_short error; u_short error;
...@@ -415,6 +420,7 @@ static int apm_set_display_power_state(u_short state) ...@@ -415,6 +420,7 @@ static int apm_set_display_power_state(u_short state)
#endif #endif
#ifdef CONFIG_APM_DO_ENABLE #ifdef CONFIG_APM_DO_ENABLE
/* Called by apm_setup if apm_enabled will be true. */
static int apm_enable_power_management(void) static int apm_enable_power_management(void)
{ {
u_short error; u_short error;
...@@ -460,12 +466,13 @@ static void apm_error(char *str, int err) ...@@ -460,12 +466,13 @@ static void apm_error(char *str, int err)
printk("apm_bios: %s: unknown error code %#2.2x\n", str, err); printk("apm_bios: %s: unknown error code %#2.2x\n", str, err);
} }
/* Called from console driver -- must make sure apm_enabled. */
int apm_display_blank(void) int apm_display_blank(void)
{ {
#ifdef CONFIG_APM_DISPLAY_BLANK #ifdef CONFIG_APM_DISPLAY_BLANK
int error; int error;
if (apm_bios_info.version == 0) if (!apm_enabled || apm_bios_info.version == 0)
return 0; return 0;
error = apm_set_display_power_state(APM_STATE_STANDBY); error = apm_set_display_power_state(APM_STATE_STANDBY);
if (error == APM_SUCCESS) if (error == APM_SUCCESS)
...@@ -475,12 +482,13 @@ int apm_display_blank(void) ...@@ -475,12 +482,13 @@ int apm_display_blank(void)
return 0; return 0;
} }
/* Called from console driver -- must make sure apm_enabled. */
int apm_display_unblank(void) int apm_display_unblank(void)
{ {
#ifdef CONFIG_APM_DISPLAY_BLANK #ifdef CONFIG_APM_DISPLAY_BLANK
int error; int error;
if (apm_bios_info.version == 0) if (!apm_enabled || apm_bios_info.version == 0)
return 0; return 0;
error = apm_set_display_power_state(APM_STATE_READY); error = apm_set_display_power_state(APM_STATE_READY);
if (error == APM_SUCCESS) if (error == APM_SUCCESS)
...@@ -715,6 +723,7 @@ static void do_apm_timer(unsigned long unused) ...@@ -715,6 +723,7 @@ static void do_apm_timer(unsigned long unused)
add_timer(&apm_timer); add_timer(&apm_timer);
} }
/* Called from sys_idle, must make sure apm_enabled. */
int apm_do_idle(void) int apm_do_idle(void)
{ {
#ifdef CONFIG_APM_CPU_IDLE #ifdef CONFIG_APM_CPU_IDLE
...@@ -734,17 +743,18 @@ int apm_do_idle(void) ...@@ -734,17 +743,18 @@ int apm_do_idle(void)
#endif #endif
} }
/* Called from sys_idle, must make sure apm_enabled. */
void apm_do_busy(void) void apm_do_busy(void)
{ {
#ifdef CONFIG_APM_CPU_IDLE #ifdef CONFIG_APM_CPU_IDLE
unsigned short error; unsigned short error;
if (!apm_enabled)
return;
#ifndef ALWAYS_CALL_BUSY #ifndef ALWAYS_CALL_BUSY
if (!clock_slowed) if (!clock_slowed)
return; return;
#else
if (!apm_enabled)
return;
#endif #endif
APM_SET_CPU_BUSY(error); APM_SET_CPU_BUSY(error);
......
static char rcsid[] = static char rcsid[] =
"$Revision: 1.36.3.4 $$Date: 1995/11/13 20:45:10 $"; "$Revision: 1.36.3.5 $$Date: 1996/03/07 15:20:17 $";
/* /*
* linux/drivers/char/cyclades.c * linux/drivers/char/cyclades.c
* *
...@@ -24,6 +24,12 @@ static char rcsid[] = ...@@ -24,6 +24,12 @@ static char rcsid[] =
* int cy_open(struct tty_struct *tty, struct file *filp); * int cy_open(struct tty_struct *tty, struct file *filp);
* *
* $Log: cyclades.c,v $ * $Log: cyclades.c,v $
* Revision 1.36.3.5 1996/03/07 15:20:17 bentson
* Some global changes to interrupt handling spilled into
* this driver--mostly unused arguments in system function
* calls. Also added change by Marcio Saito which should
* reduce lost interrupts at startup by fast processors.
*
* Revision 1.36.3.4 1995/11/13 20:45:10 bentson * Revision 1.36.3.4 1995/11/13 20:45:10 bentson
* Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
* in 1.3.41 kernel to remove a possible race condition, extend * in 1.3.41 kernel to remove a possible race condition, extend
...@@ -627,8 +633,8 @@ cy_probe(int irq, void *dev_id, struct pt_regs *regs) ...@@ -627,8 +633,8 @@ cy_probe(int irq, void *dev_id, struct pt_regs *regs)
intr_base_addr[CySRER<<index] &= ~CyTxMpty; intr_base_addr[CySRER<<index] &= ~CyTxMpty;
intr_base_addr[CyTIR<<index] = (save_xir & 0x3f); intr_base_addr[CyTIR<<index] = (save_xir & 0x3f);
intr_base_addr[CyCAR<<index] = (save_car); intr_base_addr[CyCAR<<index] = (save_car);
*(intr_base_addr + (Cy_ClrIntr<<index)) = 0; /* Cy_ClrIntr is 0x1800 */
} }
*(intr_base_addr + (Cy_ClrIntr<<index)) = 0; /* Cy_ClrIntr is 0x1800 */
return; return;
} /* cy_probe */ } /* cy_probe */
......
#
# Makefile for the ftape device driver.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now inherited from the
# parent makes..
#
# Valid ftape options are:
# NO_TRACE - if defined, only information and errors show up.
# NO_TRACE_AT_ALL - if defined, no trace output shows up.
# GCC_2_4_5_BUG - must be set if using gcc-2.4.5 to prevent
# bad assembler-code for the dma handling.
# NR_BUFFERS - Number of ftape DMA buffers (keep it at 3!)
# VERIFY_HEADERS - if set the headers segments are verified after
# being written.
# PROBE_FC10 - if defined will look for a FC-10 card at specified
# settings (FDC_BASE,FDC_IRQ,FDC_DMA) before using
# the standard fd controller.
# FDC_BASE - sets base address (only!) if using non-standard fdc
# FDC_IRQ - sets interrupt if FDC_BASE is defined
# FDC_DMA - sets dma channel if FDC_BASE is defined
# MACH2 - Support for Mountain MACH-2 contoller at either 1E0
# or 3E0, don't forget the FDC_OPT's !
# CLK_48MHZ - Set to 1. If you have a i82078-1 FDC and it does not
# work, try setting it to 0. (only used for i82078-1's)
# FDC_82078SL - If you have a 82078SL, define this.
FTAPE_OPT = -DVERIFY_HEADERS -DNR_BUFFERS=3 -DCLK_48MHZ=1 \
-DFDC_82078SL -DNO_TRACE
# If you're using a non-standard floppy disk controller for the
# tape drive, enable one (only!) of the following lines and set
# the FDC_BASE, FDC_IRQ and FDC_DMA parameters to the actual values.
#
# Note1: A FC-10/FC-20 controller must use either of DMA 1, 2, or 3.
# DMA 5 and 7 does NOT work!.
#
# Note2: IRQ 2 and IRQ 9 can be considered the same. When using IRQ 2
# on a controller you must specify IRQ 9 here!
#
# For a Mountain MACH-2 controller, try
#FDC_OPT = -DMACH2 -DFDC_BASE=0x1E0 -DFDC_IRQ=6 -DFDC_DMA=2
#
# For Colorado CMS FC-10 or FC-20 controllers:
#FDC_OPT = -DPROBE_FC10 -DFDC_BASE=0x180 -DFDC_IRQ=9 -DFDC_DMA=3
#
# Secondary floppy disk controller:
#FDC_OPT = -DFDC_BASE=0x370 -DFDC_IRQ=9 -DFDC_DMA=3
#
# This enables some (most?) 2Mbps controllers:
#FDC_OPT = -DFDC_BASE=0x3E0 -DFDC_IRQ=6 -DFDC_DMA=2
EXTRA_CFLAGS := $(FTAPE_OPT) $(FDC_OPT) -D__NO_VERSION__
O_TARGET := ftape.o
O_OBJS = kernel-interface.o tracing.o fdc-io.o fdc-isr.o \
ftape-bsm.o ftape-ctl.o ftape-eof.o ftape-read.o ftape-rw.o \
ftape-write.o ftape-io.o calibr.o ecc.o fc-10.o
M_OBJS = $(O_TARGET)
include $(TOPDIR)/Rules.make
Some notes for ftape users with PCI motherboards:
=================================================
The problem:
------------
There have been some problem reports from people using PCI-bus based
systems getting overrun errors.
I wasn't able to reproduce these until I ran ftape on a Intel Plato
(Premiere PCI II) motherboard with bios version 1.00.08AX1.
It turned out that if GAT (Guaranteed Access Timing) is enabled (?)
ftape gets a lot of overrun errors.
The problem disappears when disabling GAT in the bios.
Note that Intel removed this setting (permanently disabled) from the
1.00.10AX1 bios !
It looks like that if GAT is enabled there are often large periods
(greater than 120 us !??) on the ISA bus that the DMA controller cannot
service the floppy disk controller.
I cannot imagine this being acceptable in a decent PCI implementation.
Maybe this is a `feature' of the chipset. I can only speculate why
Intel choose to remove the option from the latest Bios...
The lesson of this all is that there may be other motherboard
implementations having the same of similar problems.
If you experience a lot of overrun errors during a backup to tape,
see if there is some setting in the Bios that may influence the
bus timing.
I judge this a hardware problem and not a limitation of ftape ;-)
My DOS backup software seems to be suffering from the same problems
and even refuses to run at 1 Mbps !
Ftape will reduce the datarate from 1 Mbps to 500 Kbps if the number
of overrun errors on a track exceeds a threshold.
Possible solutions:
-------------------
Some of the problems were solved by upgrading the (flash) bios.
Other suggest that it has to do with the FDC being on the PCI
bus, but that is not the case with the Intel Premiere II boards.
[If upgrading the bios doesn't solve the problem you could try
a floppy disk controller on the isa-bus].
Here is a list of systems and recommended BIOS settings:
Intel Premiere PCI (Revenge):
Bios version 1.00.09.AF2 is reported to work.
Intel Premiere PCI II (Plato):
Bios version 1.00.10.AX1 and version 11 beta are ok.
If using version 1.00.08.AX1, GAT must be disabled !
ASUS PCI/I-SP3G:
Preferred settings: ISA-GAT-mode : disabled
DMA-linebuffer-mode : standard
ISA-masterbuffer-mode : standard
DELL Dimension XPS P90
Bios version A2 is reported to be broken, while bios version A5 works.
You can get a flash bios upgrade from http://www.dell.com
To see if you're having the GAT problem, try making a backup
under DOS. If it's very slow and often repositions you're
probably having this problem.
--//--
This diff is collapsed.
/* Yo, Emacs! we're -*- Linux-C -*-
*
* Copyright (C) 1993-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* GP calibration routine for processor speed dependent
* functions.
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/ftape.h>
#include <asm/system.h>
#include <asm/io.h>
#include "tracing.h"
#include "calibr.h"
#include "fdc-io.h"
#undef DEBUG
unsigned timestamp(void)
{
unsigned count;
unsigned long flags;
save_flags(flags);
cli();
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
restore_flags(flags);
return (LATCH - count); /* normal: downcounter */
}
int timediff(int t0, int t1)
{
/* Calculate difference in usec for timestamp results t0 & t1.
* Note that the maximum timespan allowed is 1/HZ or we'll lose ticks!
*/
if (t1 < t0) {
t1 += LATCH;
}
return (1000 * (t1 - t0)) / ((CLOCK_TICK_RATE + 500) / 1000);
}
/* To get an indication of the I/O performance,
* measure the duration of the inb() function.
*/
void time_inb(void)
{
TRACE_FUN(8, "time_inb");
int i;
int t0, t1;
unsigned long flags;
int status;
save_flags(flags);
cli();
t0 = timestamp();
for (i = 0; i < 1000; ++i) {
status = inb(fdc.msr);
}
t1 = timestamp();
restore_flags(flags);
if (t1 - t0 <= 0) {
t1 += LATCH;
}
TRACEx1(4, "inb() duration: %d nsec", timediff(t0, t1));
TRACE_EXIT;
}
/* Haven't studied on why, but there sometimes is a problem
* with the tick timer readout. The two bytes get swapped.
* This hack solves that problem by doing one extra input.
*/
void fix_clock(void)
{
TRACE_FUN(8, "fix_clock");
int t;
int i;
for (i = 0; i < 1000; ++i) {
t = timestamp();
if (t < 0) {
inb_p(0x40); /* get in sync again */
TRACE(2, "clock counter fixed");
break;
}
}
TRACE_EXIT;
}
/*
* Input: function taking int count as parameter.
* pointers to calculated calibration variables.
*/
int calibrate(char *name, void (*fun) (int), int *calibr_count, int *calibr_time)
{
TRACE_FUN(5, "calibrate");
static int first_time = 1;
int i;
int old_tc = 0;
int old_count = 1;
int old_time = 1;
if (first_time) { /* get idea of I/O performance */
fix_clock();
time_inb();
first_time = 0;
}
/* value of timeout must be set so that on very slow systems
* it will give a time less than one jiffy, and on
* very fast systems it'll give reasonable precision.
*/
*calibr_count = 10;
for (i = 0; i < 15; ++i) {
int t0, t1;
unsigned long flags;
int once;
int multiple;
int tc;
*calibr_time = *calibr_count; /* set TC to 1 */
fun(0); /* dummy, get code into cache */
save_flags(flags);
cli();
t0 = timestamp();
fun(0); /* overhead + one test */
t1 = timestamp();
if (t1 < t0) {
t1 += LATCH;
}
once = t1 - t0;
t0 = timestamp();
fun(*calibr_count); /* overhead + multiple tests */
t1 = timestamp();
if (t1 < t0) {
t1 += LATCH;
}
multiple = t1 - t0;
restore_flags(flags);
*calibr_time = (10000 * (multiple - once)) / (CLOCK_TICK_RATE / 100);
--*calibr_count; /* because delta corresponds to this count */
tc = (1000 * *calibr_time) / *calibr_count;
TRACEx4(8, "once:%4d us,%5d times:%6d us, TC:%5d ns",
(10000 * once) / (CLOCK_TICK_RATE / 100),
*calibr_count,
(10000 * multiple) / (CLOCK_TICK_RATE / 100),
tc);
/*
* increase the count until the resulting time nears 2/HZ,
* then the tc will drop sharply because we lose LATCH counts.
*/
if (tc <= old_tc / 2) {
*calibr_time = old_time;
*calibr_count = old_count;
break;
}
old_tc = tc;
old_count = *calibr_count;
old_time = *calibr_time;
*calibr_count *= 2;
}
TRACEx3(4, "TC for `%s()' = %d nsec (at %d counts)",
name, (1000 * *calibr_time) / *calibr_count, *calibr_count);
TRACE_EXIT;
return 0;
}
#ifndef _CALIBRATE_H
#define _CALIBRATE_H
/*
* Copyright (C) 1993-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/calibr.h,v $
$Author: bas $
*
$Revision: 1.20 $
$Date: 1995/04/22 07:30:15 $
$State: Beta $
*
* This file contains a gp calibration routine for
* hardware dependent timeout functions.
*/
#include <linux/timex.h>
extern int calibrate(char *name, void (*fun) (int), int *calibr_count, int *calibr_time);
extern unsigned timestamp(void);
extern int timediff(int t0, int t1);
#endif
This diff is collapsed.
/*
* Copyright (C) 1993 Ning and David Mosberger.
* Original:
* Copyright (C) 1993 Bas Laarhoven.
* Copyright (C) 1992 David L. Brown, Jr.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
* USA.
*
*
* $Source: /home/bas/distr/ftape-2.03b/RCS/ecc.h,v $
* $Author: bas $
*
* $Revision: 1.20 $
* $Date: 1995/01/08 14:16:21 $
* $State: Beta $
*
* This file contains the definitions for the
* Reed-Solomon error correction code
* for the QIC-40/80 tape streamer device driver.
*/
#ifndef _ecc_h_
#define _ecc_h_
typedef unsigned long BAD_SECTOR;
#define BAD_CLEAR(entry) ((entry)=0)
#define BAD_SET(entry,sector) ((entry)|=(1<<(sector)))
#define BAD_CHECK(entry,sector) ((entry)&(1<<(sector)))
/*
* Return values for ecc_correct_data:
*/
enum {
ECC_OK, /* Data was correct. */
ECC_CORRECTED, /* Correctable error in data. */
ECC_FAILED, /* Could not correct data. */
};
/*
* Representation of an in memory segment. MARKED_BAD lists the
* sectors that were marked bad during formatting. If the N-th sector
* in a segment is marked bad, bit 1<<N will be set in MARKED_BAD.
* The sectors should be read in from the disk and packed, as if the
* bad sectors were not there, and the segment just contained fewer
* sectors. READ_SECTORS is a bitmap of errors encountered while
* reading the data. These offsets are relative to the packed data.
* BLOCKS is a count of the sectors not marked bad. This is just to
* prevent having to count the zero bits in MARKED_BAD each time this
* is needed. DATA is the actual sector packed data from (or to) the
* tape.
*/
struct memory_segment {
BAD_SECTOR marked_bad;
BAD_SECTOR read_bad;
int blocks;
unsigned char *data;
BAD_SECTOR corrected;
};
/*
* ecc.c defined global variables:
*/
#ifdef TEST
extern int ftape_ecc_tracing;
#endif
/*
* ecc.c defined global functions:
*/
extern int ecc_correct_data(struct memory_segment *data);
extern int ecc_set_segment_parity(struct memory_segment *data);
#endif /* _ecc_h_ */
/* Yo, Emacs! we're -*- Linux-C -*-
*
Copyright (C) 1993,1994 Jon Tombs.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The entire guts of this program was written by dosemu, modified to
record reads and writes to the ports in the 0x180-0x188 address space,
while running the CMS program TAPE.EXE V2.0.5 supplied with the drive.
Modified to use an array of addresses and generally cleaned up (made
much shorter) 4 June 94, dosemu isn't that good at writing short code it
would seem :-). Made independant of 0x180, but I doubt it will work
at any other address.
Modified for distribution with ftape source. 21 June 94, SJL.
Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu):
Modified to support different DMA, IRQ, and IO Ports. Borland's
Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints
provided by the TDH386.SYS Device Driver) was used on the CMS program
TAPE V4.0.5. I set breakpoints on I/O to ports 0x180-0x187. Note that
CMS's program will not successfully configure the tape drive if you set
breakpoints on IO Reads, but you can set them on IO Writes without problems.
Known problems:
- You can not use DMA Channels 5 or 7.
Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu):
Modified to only accept IRQs 3 - 7, or 9. Since we can only send a 3 bit
number representing the IRQ to the card, special handling is required when
IRQ 9 is selected. IRQ 2 and 9 are the same, and we should request IRQ 9
from the kernel while telling the card to use IRQ 2. Thanks to Greg
Crider (gcrider@iclnet.org) for finding and locating this bug, as well as
testing the patch.
*
* This file contains code for the CMS FC-10/FC-20 card.
*/
#include <linux/module.h>
#include <linux/ftape.h>
#include <asm/io.h>
#include "tracing.h"
#include "fdc-io.h"
#include "fc-10.h"
#ifdef PROBE_FC10
/* This code will only work if the FC-10 (or FC-20) is set to
* use DMA channels 1, 2, or 3. DMA channels 5 and 7 seem to be
* initialized by the same command as channels 1 and 3, respectively.
*/
#if (FDC_DMA > 3)
#error : The FC-10/20 must be set to use DMA channels 1, 2, or 3!
#endif
/* Only allow the FC-10/20 to use IRQ 3-7, or 9. Note that CMS's program
* only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9.
*/
#if (FDC_IRQ < 3 || FDC_IRQ == 8 || FDC_IRQ > 9)
#error : The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!
#error : Note IRQ 9 is the same as IRQ 2
#endif
unsigned short inbs_magic[] = {
0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
};
unsigned short fc10_ports[] = {
0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
};
int fc10_enable(void)
{
int i;
byte cardConfig = 0x00;
byte x;
/* Clear state machine ???
*/
for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
inb(FDC_BASE + inbs_magic[i]);
}
outb(0x0, FDC_BASE);
x = inb(FDC_BASE);
if (x == 0x13 || x == 0x93) {
for (i = 1; i < 8; i++) {
if (inb(FDC_BASE + i) != x) {
return 0;
}
}
} else {
return 0;
}
outb(0x8, FDC_BASE);
for (i = 0; i < 8; i++) {
if (inb(FDC_BASE + i) != 0x0) {
return 0;
}
}
outb(0x10, FDC_BASE);
for (i = 0; i < 8; i++) {
if (inb(FDC_BASE + i) != 0xff) {
return 0;
}
}
/* Okay, we found a FC-10 card ! ???
*/
outb(0x0, fdc.ccr);
/* Clear state machine again ???
*/
for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
inb(FDC_BASE + inbs_magic[i]);
}
/* Send io port */
for (i = 0; i < NR_ITEMS(fc10_ports); i++)
if (FDC_BASE == fc10_ports[i])
cardConfig = i + 1;
if (cardConfig == 0)
return 0; /* Invalid I/O Port */
/* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */
if (FDC_IRQ != 9)
cardConfig |= FDC_IRQ << 3;
else
cardConfig |= 2 << 3;
/* and finally DMA Channel */
cardConfig |= FDC_DMA << 6;
outb(cardConfig, FDC_BASE); /* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */
/* Enable FC-10 ???
*/
outb(0, fdc.ccr);
outb(0, FDC_BASE + 0x6);
outb(8, fdc.dor);
outb(8, fdc.dor);
outb(1, FDC_BASE + 0x6);
/* Initialize fdc, select drive B:
*/
outb(0x08, fdc.dor); /* assert reset, dma & irq enabled */
outb(0x0c, fdc.dor); /* release reset */
outb(0x2d, fdc.dor); /* select drive 1 */
return (x == 0x93) ? 2 : 1;
}
#endif /* CMS_FC10_CONTROLLER */
#ifndef _FC_10_H
#define _FC_10_H
/*
* Copyright (C) 1994 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/fc-10.h,v $
$Author: bas $
*
$Revision: 1.3 $
$Date: 1995/01/08 14:16:21 $
$State: Beta $
*
* This file contains definitions for the FC-10 code
* of the QIC-40/80 floppy-tape driver for Linux.
*/
/*
* fc-10.c defined global vars.
*/
/*
* fc-10.c defined global functions.
*/
extern int fc10_enable(void);
#endif
This diff is collapsed.
#ifndef _FDC_IO_H
#define _FDC_IO_H
/*
* Copyright (C) 1993-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/fdc-io.h,v $
$Author: bas $
*
$Revision: 1.38 $
$Date: 1995/05/10 16:09:36 $
$State: Beta $
*
* This file contains the low level functions
* that communicate with the floppy disk controller,
* for the QIC-40/80 floppy-tape driver for Linux.
*/
#include <linux/fdreg.h>
#define FDC_SK_BIT (0x20)
#define FDC_MT_BIT (0x80)
#define FDC_READ (FD_READ & ~(FDC_SK_BIT | FDC_MT_BIT))
#define FDC_WRITE (FD_WRITE & ~FDC_MT_BIT)
#define FDC_READ_DELETED (0x4c)
#define FDC_WRITE_DELETED (0x49)
#define FDC_READID (0x4a)
#define FDC_SENSED (0x04)
#define FDC_SENSEI (FD_SENSEI)
#define FDC_RECAL (FD_RECALIBRATE)
#define FDC_SEEK (FD_SEEK)
#define FDC_SPECIFY (FD_SPECIFY)
#define FDC_RECALIBR (FD_RECALIBRATE)
#define FDC_VERSION (FD_VERSION)
#define FDC_PERPEND (FD_PERPENDICULAR)
#define FDC_DUMPREGS (FD_DUMPREGS)
#define FDC_LOCK (FD_LOCK)
#define FDC_UNLOCK (FD_UNLOCK)
#define FDC_CONFIGURE (FD_CONFIGURE)
#define FDC_DRIVE_SPEC (0x8e) /* i82078 has this (any others?) */
#define FDC_PARTID (0x18) /* i82078 has this */
#define FDC_SAVE (0x2e) /* i82078 has this (any others?) */
#define FDC_RESTORE (0x4e) /* i82078 has this (any others?) */
#define FDC_STATUS_MASK (STATUS_BUSY | STATUS_DMA | STATUS_DIR | STATUS_READY)
#define FDC_DATA_READY (STATUS_READY)
#define FDC_DATA_OUTPUT (STATUS_DIR)
#define FDC_DATA_READY_MASK (STATUS_READY | STATUS_DIR)
#define FDC_DATA_OUT_READY (STATUS_READY | STATUS_DIR)
#define FDC_DATA_IN_READY (STATUS_READY)
#define FDC_BUSY (STATUS_BUSY)
#define FDC_CLK48_BIT (0x80)
#define FDC_SEL3V_BIT (0x40)
#define ST0_INT_MASK (ST0_INTR)
#define FDC_INT_NORMAL (ST0_INTR & 0x00)
#define FDC_INT_ABNORMAL (ST0_INTR & 0x40)
#define FDC_INT_INVALID (ST0_INTR & 0x80)
#define FDC_INT_READYCH (ST0_INTR & 0xC0)
#define ST0_SEEK_END (ST0_SE)
#define ST3_TRACK_0 (ST3_TZ)
#define FDC_RESET_NOT (0x04)
#define FDC_DMA_MODE (0x08)
#define FDC_MOTOR_0 (0x10)
#define FDC_MOTOR_1 (0x20)
typedef struct {
void (**hook) (void); /* our wedge into the isr */
enum {
no_fdc, i8272, i82077, i82077AA, fc10,
i82078, i82078_1
} type; /* FDC type */
unsigned char irq; /* FDC irq nr */
unsigned char dma; /* FDC dma channel nr */
unsigned short sra; /* Status register A (PS/2 only) */
unsigned short srb; /* Status register B (PS/2 only) */
unsigned short dor; /* Digital output register */
unsigned short tdr; /* Tape Drive Register (82077SL-1 &
82078 only) */
unsigned short msr; /* Main Status Register */
unsigned short dsr; /* Datarate Select Register (8207x only) */
unsigned short fifo; /* Data register / Fifo on 8207x */
unsigned short dir; /* Digital Input Register */
unsigned short ccr; /* Configuration Control Register */
unsigned short dor2; /* Alternate dor on MACH-2 controller,
also used with FC-10, meaning unknown */
} fdc_config_info;
typedef enum {
fdc_data_rate_250 = 2,
fdc_data_rate_500 = 0,
fdc_data_rate_1000 = 3,
fdc_data_rate_2000 = 1, /* i82078-1: remember to use Data Rate Table #2 */
} fdc_data_rate_type;
typedef enum {
waiting = 0,
reading,
writing,
done,
error,
} buffer_state_enum;
typedef volatile enum {
fdc_idle = 0,
fdc_reading_data = FDC_READ,
fdc_seeking = FDC_SEEK,
fdc_writing_data = FDC_WRITE,
fdc_reading_id = FDC_READID,
fdc_recalibrating = FDC_RECAL,
} fdc_mode_enum;
/*
* fdc-io.c defined public variables
*/
extern fdc_mode_enum fdc_mode;
extern volatile enum runner_status_enum runner_status;
extern int old_vfo;
extern volatile int head;
extern volatile int tail;
extern int fdc_setup_error; /* outdated ??? */
extern struct wait_queue *wait_intr;
extern volatile unsigned int next_segment; /* next segment for read ahead */
extern int ftape_unit; /* fdc unit specified at ftape_open() */
extern int ftape_motor; /* fdc motor line state */
extern int current_cylinder; /* track nr the FDC thinks we're on */
extern volatile byte fdc_head; /* FDC head */
extern volatile byte fdc_cyl; /* FDC track */
extern volatile byte fdc_sect; /* FDC sector */
extern fdc_config_info fdc; /* FDC hardware configuration */
/*
* fdc-io.c defined public functions
*/
extern void fdc_catch_stray_interrupts(unsigned count);
extern int fdc_ready_wait(int timeout);
extern int fdc_write(byte data);
extern int fdc_read(byte * data);
extern int fdc_command(byte * cmd_data, int cmd_len);
extern int fdc_result(byte * res_data, int res_len);
extern int fdc_issue_command(byte * out_data, int out_count, \
byte * in_data, int in_count);
extern void fdc_isr(void);
extern int fdc_interrupt_wait(int time);
extern void fdt_sleep(unsigned int time);
extern int fdc_specify(int head_unload_time, int seek_rate,
int head_load_time, int non_dma);
extern int fdc_set_seek_rate(int seek_rate);
extern int fdc_seek(int track);
extern int fdc_sense_drive_status(int *st3);
extern void fdc_motor(int motor);
extern void fdc_reset(void);
extern int fdc_recalibrate(void);
extern void fdc_disable(void);
extern int fdc_wait_calibrate(void);
extern int fdc_sense_interrupt_status(int *st0, int *current_cylinder);
extern void fdc_save_drive_specs(void);
extern void fdc_restore_drive_specs(void);
extern void fdc_set_data_rate(int rate);
extern int fdc_release_irq_and_dma(void);
extern int fdc_init(void);
extern int fdc_uninit(void);
extern void fdc_set_write_precomp(int precomp);
#endif
This diff is collapsed.
#ifndef _FDC_ISR_H
#define _FDC_ISR_H
/*
* Copyright (C) 1993-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/fdc-isr.h,v $
$Author: bas $
*
$Revision: 1.8 $
$Date: 1995/04/22 07:30:15 $
$State: Beta $
*
* This file contains the low level functions
* that communicate with the floppy disk controller,
* for the QIC-40/80 floppy-tape driver for Linux.
*/
/*
* fdc-isr.c defined public variables
*/
extern volatile int expected_stray_interrupts; /* masks stray interrupts */
extern volatile int seek_completed; /* flag set by isr */
extern volatile int interrupt_seen; /* flag set by isr */
extern volatile int expect_stray_interrupt;
/*
* fdc-io.c defined public functions
*/
extern void fdc_isr(void);
/*
* A kernel hook that steals one interrupt from the floppy
* driver (Should be fixed when the new fdc driver gets ready)
* See the linux kernel source files:
* drivers/block/floppy.c & drivers/block/blk.h
* for the details.
*/
extern void (*do_floppy) (void);
#endif
This diff is collapsed.
#ifndef _FTAPE_BSM_H
#define _FTAPE_BSM_H
/*
* Copyright (C) 1994-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/ftape-bsm.h,v $
$Author: bas $
*
$Revision: 1.5 $
$Date: 1995/04/22 07:30:15 $
$State: Beta $
*
* This file contains definitions for the bad sector map handling
* routines for the QIC-117 floppy-tape driver for Linux.
*/
#define EMPTY_SEGMENT (0xffffffff)
#define FAKE_SEGMENT (0xfffffffe)
/* failed sector log size (only used if format code != 4).
*/
#define FAILED_SECTOR_LOG_SIZE (2 * SECTOR_SIZE - 256)
/* maximum (format code 4) bad sector map size (bytes).
*/
#define BAD_SECTOR_MAP_SIZE (29 * SECTOR_SIZE - 256)
/*
* ftape-io.c defined global vars.
*/
extern bad_sector_map_changed;
/*
* ftape-io.c defined global functions.
*/
extern void update_bad_sector_map(byte * buffer);
extern void store_bad_sector_map(byte * buffer);
extern void extract_bad_sector_map(byte * buffer);
extern unsigned long get_bad_sector_entry(int segment_id);
extern void put_bad_sector_entry(int segment_id, unsigned long mask);
extern void add_segment_to_bad_sector_map(unsigned segment);
extern void clear_bad_sector_map(int count);
extern byte *find_end_of_bsm_list(byte * ptr, byte * limit);
extern void ftape_init_bsm(void);
#endif
This diff is collapsed.
#ifndef _FTAPE_CTL_H
#define _FTAPE_CTL_H
/*
* Copyright (C) 1993-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/ftape-ctl.h,v $
$Author: bas $
*
$Revision: 1.4 $
$Date: 1995/05/03 18:04:03 $
$State: Beta $
*
* This file contains the non-standard IOCTL related definitions
* for the QIC-40/80 floppy-tape driver for Linux.
*/
#include <linux/ioctl.h>
#include <linux/mtio.h>
#include "vendors.h"
typedef struct {
int used; /* any reading or writing done */
/* isr statistics */
unsigned int id_am_errors; /* id address mark not found */
unsigned int id_crc_errors; /* crc error in id address mark */
unsigned int data_am_errors; /* data address mark not found */
unsigned int data_crc_errors; /* crc error in data field */
unsigned int overrun_errors; /* fdc access timing problem */
unsigned int no_data_errors; /* sector not found */
unsigned int retries; /* number of tape retries */
/* ecc statistics */
unsigned int crc_errors; /* crc error in data */
unsigned int crc_failures; /* bad data without crc error */
unsigned int ecc_failures; /* failed to correct */
unsigned int corrected; /* total sectors corrected */
/* general statistics */
unsigned int rewinds; /* number of tape rewinds */
unsigned int defects; /* bad sectors due to media defects */
} history_record;
/*
* ftape-ctl.c defined global vars.
*/
extern int ftape_failure;
extern int write_protected;
extern ftape_offline;
extern int formatted;
extern int no_tape;
extern history_record history;
extern int ftape_data_rate;
extern int going_offline;
extern vendor_struct drive_type;
extern int segments_per_track;
extern int segments_per_head;
extern int segments_per_cylinder;
extern int tracks_per_tape;
extern int ftape_seg_pos;
extern int first_data_segment;
extern int ftape_state;
extern int read_only;
/*
* ftape-ctl.c defined global functions.
*/
extern int _ftape_open(void);
extern int _ftape_close(void);
extern int _ftape_ioctl(unsigned int command, void *arg);
extern int ftape_seek_to_bot(void);
extern int ftape_seek_to_eot(void);
extern int ftape_new_cartridge(void);
extern int ftape_abort_operation(void);
extern void ftape_reset_position(void);
extern void ftape_calc_timeouts(void);
extern void ftape_init_driver(void);
#endif
This diff is collapsed.
#ifndef _FTAPE_EOF_H
#define _FTAPE_EOF_H
/*
* Copyright (C) 1994-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/ftape-eof.h,v $
$Author: bas $
*
$Revision: 1.12 $
$Date: 1995/04/22 07:30:15 $
$State: Beta $
*
* Definitions and declarations for the end of file markers
* for the QIC-40/80 floppy-tape driver for Linux.
*/
/* ftape-eof.c defined global vars.
*/
extern int failed_sector_log_changed;
extern int eof_mark;
/* ftape-eof.c defined global functions.
*/
extern void clear_eof_mark_if_set(unsigned segment, unsigned byte_count);
extern void reset_eof_list(void);
extern int check_for_eof(unsigned segment);
extern int ftape_weof(unsigned count, unsigned segment, unsigned sector);
extern int ftape_erase(void);
extern void put_file_mark_in_map(unsigned segment, unsigned sector);
extern void extract_file_marks(byte * address);
extern int update_failed_sector_log(byte * buffer);
extern int ftape_seek_eom(void);
extern int ftape_seek_eof(unsigned count);
extern int ftape_file_no(daddr_t * file, daddr_t * block);
extern int ftape_validate_label(char *label);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef _FTAPE_READ_H
#define _FTAPE_READ_H
/*
* Copyright (C) 1994-1995 Bas Laarhoven.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
$Source: /home/bas/distr/ftape-2.03b/RCS/ftape-read.h,v $
$Author: bas $
*
$Revision: 1.13 $
$Date: 1995/05/10 16:09:36 $
$State: Beta $
*
* This file contains the definitions for the read functions
* for the QIC-117 floppy-tape driver for Linux.
*
*/
/* ftape-read.c defined global vars.
*/
/* ftape-read.c defined global functions.
*/
extern int _ftape_read(char *buff, int req_len);
extern int read_header_segment(byte * address);
extern int read_segment(unsigned segment, byte * address, int *eof_mark,
int read_ahead);
extern void ftape_zap_read_buffers(void);
#endif /* _FTAPE_READ_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -19,6 +19,7 @@ bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC ...@@ -19,6 +19,7 @@ bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
tristate 'WD80*3 support' CONFIG_WD80x3 tristate 'WD80*3 support' CONFIG_WD80x3
tristate 'SMC Ultra support' CONFIG_ULTRA tristate 'SMC Ultra support' CONFIG_ULTRA
tristate 'SMC 9194 support' CONFIG_SMC9194
fi fi
bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
bool '3COM cards' CONFIG_NET_VENDOR_3COM bool '3COM cards' CONFIG_NET_VENDOR_3COM
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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