Commit 5992007d authored by Linus Torvalds's avatar Linus Torvalds

Import 1.2.9

parent be164636
VERSION = 1
PATCHLEVEL = 2
SUBLEVEL = 8
SUBLEVEL = 9
ARCH = i386
......
......@@ -45,13 +45,15 @@ void enable_hlt(void)
asmlinkage int sys_idle(void)
{
int i;
pmd_t * pmd;
if (current->pid != 0)
return -EPERM;
/* Map out the low memory: it's no longer needed */
pmd = pmd_offset(swapper_pg_dir, 0);
for (i = 0 ; i < 768 ; i++)
pgd_clear(swapper_pg_dir + i);
pmd_clear(pmd++);
/* endless idle loop with no priority at all */
current->counter = -100;
......
#define THREE_LEVEL
/* ptrace.c */
/* By Ross Biro 1/23/92 */
/* edited by Linus Torvalds */
......
......@@ -21,17 +21,35 @@ Major features of ide.c & ide-cd.c:
- support for interrupt unmasking during I/O (better than hd.c)
- improved handshaking and error detection/recovery
- can co-exist with hd.c to control only the secondary interface
NEW! - support for reliable operation of buggy CMD-640 interfaces
- use kernel command line option: hda=serialize
NEW! - experimental support for DTC-2278D interfaces
- use kernel command line option: hda=dtc2278
NEW! - run-time selectible 32bit interface support (using hdparm-2.3)
Under construction:
- improved CMD support: tech info is supposedly "in the mail"
- support for interface speed selection on jumperless interfaces
- improved detection of non-standard IDE ATAPI cdrom drives
- support for non-standard 3rd/4th drive interface on Promise cards
***
IMPORTANT NOTICE: "CMD" EIDE Interfaces will not (by default) work *reliably*
when drives are attached to the second interface. To "fix" this, supply the
special kernel "command line" parameter to LILO: hda=serialize
Failure to do so can cause severe data corruption!
***
To access devices on the second interface, device entries must first be
created in /dev for them. To create such entries, simply run the included
shell script: MAKEDEV.ide1
Apparently the early releases of Slackware 2.2 have incorrect entries
in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide1
ide.c automatically probes for the primary and secondary interfaces,
for the drives/geometries attached to those interfaces, and for the
IRQ numbers being used by the interfaces (normally IRQ14 & IRQ15).
......
......@@ -90,6 +90,7 @@ static void extended_partition(struct gendisk *hd, int dev)
!(hd->part[current_minor].nr_sects = p->nr_sects))
goto done; /* no more logicals in this partition */
hd->part[current_minor].start_sect = first_sector + p->start_sect;
hd->sizes[current_minor] = p->nr_sects >> (BLOCK_SIZE_BITS - 9);
this_sector = first_sector + p->start_sect;
dev = ((hd->major) << 8) | current_minor;
brelse(bh);
......
......@@ -24,7 +24,7 @@
* Thanks to Nick Saw <cwsaw@pts7.pts.mot.com> for
* help in figuring this out. Ditto for Acer and
* Aztech drives, which seem to have the same problem.
*
* 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
*
* ATAPI cd-rom driver. To be used with ide.c.
*
......@@ -41,8 +41,13 @@
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#if 1 /* "old" method */
#define OUT_WORDS(b,n) outsw (IDE_PORT (HD_DATA, dev->hwif), (b), (n))
#define IN_WORDS(b,n) insw (IDE_PORT (HD_DATA, dev->hwif), (b), (n))
#else /* "new" method -- should really fix each instance instead of this */
#define OUT_WORDS(b,n) output_ide_data(dev,b,(n)/2)
#define IN_WORDS(b,n) input_ide_data(dev,b,(n)/2)
#endif
/* special command codes for strategy routine. */
#define PACKET_COMMAND 4315
......@@ -196,7 +201,7 @@ static int cdrom_decode_status (ide_dev_t *dev, int good_stat, int *stat_ret)
stat = GET_STAT (dev->hwif);
*stat_ret = stat;
if (OK_STAT (stat, good_stat, BAD_RW_STAT))
if (OK_STAT (stat, good_stat, BAD_R_STAT))
return 0;
/* Got an error. */
......
/*
* linux/drivers/block/ide.c Version 3.14 March 7, 1995
* linux/drivers/block/ide.c Version 3.16 May 30, 1995
*
* Copyright (C) 1994, 1995 Linus Torvalds & authors (see below)
*/
......@@ -107,8 +107,22 @@
* Version 3.14 fix ide_error() handling of BUSY_STAT
* fix byte-swapped cdrom strings (again.. arghh!)
* ignore INDEX bit when checking the ALTSTATUS reg
* Version 3.15 add SINGLE_THREADED flag for use with dual-CMD i/f
* ignore WRERR_STAT for non-write operations
* added VLB_SYNC support for DC-2000A & others,
* (incl. some Promise chips), courtesy of Frank Gockel
* Version 3.16 convert VLB_32BIT and VLB_SYNC into runtime flags
* add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET)
* rename SINGLE_THREADED to SUPPORT_SERIALIZE,
* add boot flag to "serialize" operation for CMD i/f
* add optional support for DTC2278 interfaces,
* courtesy of andy@cercle.cts.com (Dyan Wile).
* add boot flag to enable "dtc2278" probe
* add probe to avoid EATA (SCSI) interfaces,
* courtesy of neuffer@goofy.zdv.uni-mainz.de.
*
* To do:
* - improved CMD support: tech info is supposedly "in the mail"
* - special 32-bit controller-type detection & support
* - figure out how to support oddball "intelligent" caching cards
* - reverse-engineer 3/4 drive support on fancy "Promise" cards
......@@ -142,12 +156,15 @@
#include <asm/io.h>
#undef REALLY_FAST_IO /* define if ide ports are perfect */
#define INITIAL_MULT_COUNT 0 /* use zero to disable block mode */
#ifndef VLB_32BIT_IDE /* 0 for safety, 1 for 32-bit chipset:*/
#define VLB_32BIT_IDE 0 /* Winbond 83759F or OPTi 82C621 */
#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */
#ifndef SUPPORT_VLB_32BIT /* 1 to support 32bit I/O on VLB */
#define SUPPORT_VLB_32BIT 1 /* 0 to reduce kernel size */
#endif
#ifndef DISK_RECOVERY_TIME /* min. delay between IO for hardware */
#define DISK_RECOVERY_TIME 0 /* that needs it. */
#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */
#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */
#endif
#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */
#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */
#endif
#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */
......@@ -158,9 +175,15 @@
#ifndef OPTIMIZE_IRQS /* 1 for slightly faster code */
#define OPTIMIZE_IRQS 1 /* 0 to reduce kernel size */
#endif
#ifndef SUPPORT_SERIALIZE /* 1 to support CMD dual interfaces */
#define SUPPORT_SERIALIZE 1 /* 0 to reduce kernel size */
#endif
#ifndef SUPPORT_SHARING_IRQ /* 1 to allow two IDE i/f on one IRQ */
#define SUPPORT_SHARING_IRQ 1 /* 0 to reduce kernel size */
#endif
#ifndef SUPPORT_DTC2278 /* 1 to support DTC2278 chipset */
#define SUPPORT_DTC2278 1 /* 0 to reduce kernel size */
#endif
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif
......@@ -194,10 +217,17 @@
#undef SUPPORT_TWO_INTERFACES
#define SUPPORT_TWO_INTERFACES 0
#endif /* CONFIG_BLK_DEV_HD */
#if SUPPORT_TWO_INTERFACES
#define HWIF hwif
#define DEV_HWIF (dev->hwif)
#if SUPPORT_SERIALIZE
#undef SUPPORT_SHARING_IRQ
#define SUPPORT_SHARING_IRQ 1
#endif
#else
#undef SUPPORT_SERIALIZE
#define SUPPORT_SERIALIZE 0
#undef OPTIMIZE_IRQS
#define OPTIMIZE_IRQS 0
#undef SUPPORT_SHARING_IRQ
......@@ -224,19 +254,22 @@ typedef unsigned char byte; /* used everywhere */
#define IN_BYTE(p,hwif) (byte)inb_p(IDE_PORT(p,hwif))
#endif /* REALLY_FAST_IO */
#if VLB_32BIT_IDE
#define OUT_SECTORS(b,n) outsl(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<7)
#define IN_SECTORS(b,n) insl(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<7)
#else
#define OUT_SECTORS(b,n) outsw(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<8)
#define IN_SECTORS(b,n) insw(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<8)
#endif /* VLB_32BIT_IDE */
#if SUPPORT_VLB_32BIT
#if SUPPORT_VLB_SYNC
#define VLB_SYNC __asm__ __volatile__ ("pusha\n movl $0x01f2,%edx\n inb (%dx),%al\n inb (%dx),%al\n inb (%dx),%al\n popa\n")
#endif /* SUPPORT_VLB_SYNC */
#endif /* SUPPORT_VLB_32BIT */
#if SUPPORT_DTC2278
static uint probe_dtc2278 = 0;
#endif
#define GET_ERR(hwif) IN_BYTE(HD_ERROR,hwif)
#define GET_STAT(hwif) IN_BYTE(HD_STATUS,hwif)
#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
#define BAD_RW_STAT (BUSY_STAT | ERR_STAT | WRERR_STAT)
#define BAD_STAT (BAD_RW_STAT | DRQ_STAT)
#define BAD_R_STAT (BUSY_STAT | ERR_STAT)
#define BAD_W_STAT (BUSY_STAT | ERR_STAT | WRERR_STAT)
#define BAD_STAT (BAD_R_STAT | DRQ_STAT)
#define DRIVE_READY (READY_STAT | SEEK_STAT)
#define DATA_READY (DRIVE_READY | DRQ_STAT)
......@@ -248,6 +281,7 @@ typedef unsigned char byte; /* used everywhere */
#define PARTN_BITS 6 /* number of minor dev bits for partitions */
#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */
#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector */
/*
* Timeouts for various operations:
......@@ -296,10 +330,12 @@ typedef struct {
unsigned dont_probe : 1; /* from: hdx=noprobe */
unsigned keep_settings : 1; /* restore settings after drive reset */
unsigned busy : 1; /* mutex for ide_open, revalidate_.. */
unsigned reserved0 : 3; /* unused */
unsigned vlb_32bit : 1; /* use 32bit in/out for data */
unsigned vlb_sync : 1; /* needed for some 32bit chip sets */
unsigned reserved0 : 1; /* unused */
special_t special; /* special action flags */
select_t select; /* basic drive/head select reg value */
byte mult_count, reserved1, reserved2;
byte mult_count, chipset, reserved2;
byte usage, mult_req, wpcom, ctl;
byte head, sect, bios_head, bios_sect;
unsigned short cyl, bios_cyl;
......@@ -329,9 +365,10 @@ static const char *ide_devname [2][MAX_DRIVES] = /* for printk()'s */
{{HD_NAME "a", HD_NAME "b"}, {HD_NAME "c", HD_NAME "d"}};
static const char *unsupported = " not supported by this kernel\n";
static byte single_threaded = 0;
#if SUPPORT_SHARING_IRQ
static byte sharing_single_irq = 0; /* for two i/f on one IRQ */
static volatile byte current_hwif = 0; /* for two i/f on one IRQ */
static volatile byte current_hwif = 0; /* for single_threaded==1 */
#endif /* SUPPORT_SHARING_IRQ */
/*
......@@ -428,6 +465,50 @@ static void do_request (byte hwif);
} \
}
/*
* This is used for all data transfers *from* the IDE interface
*/
void input_ide_data (ide_dev_t *dev, void *buffer, uint wcount)
{
#if SUPPORT_VLB_32BIT
if (dev->vlb_32bit) {
#if SUPPORT_VLB_SYNC
if (dev->vlb_sync) {
cli();
VLB_SYNC;
insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
if (dev->unmask)
sti();
} else
#endif /* SUPPORT_VLB_SYNC */
insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
} else
#endif /* SUPPORT_VLB_32BIT */
insw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1);
}
/*
* This is used for all data transfers *to* the IDE interface
*/
void output_ide_data (ide_dev_t *dev, void *buffer, uint wcount)
{
#if SUPPORT_VLB_32BIT
if (dev->vlb_32bit) {
#if SUPPORT_VLB_SYNC
if (dev->vlb_sync) {
cli();
VLB_SYNC;
outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
if (dev->unmask)
sti();
} else
outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
#endif /* SUPPORT_VLB_SYNC */
} else
#endif /* SUPPORT_VLB_32BIT */
outsw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1);
}
/*
* This should get invoked on every exit path from the driver.
*/
......@@ -652,7 +733,7 @@ static void read_intr (ide_dev_t *dev)
unsigned int msect, nsect;
struct request *rq;
if (!OK_STAT(stat=GET_STAT(DEV_HWIF),DATA_READY,BAD_RW_STAT)) {
if (!OK_STAT(stat=GET_STAT(DEV_HWIF),DATA_READY,BAD_R_STAT)) {
sti();
ide_error(dev, "read_intr", stat);
DO_REQUEST;
......@@ -667,7 +748,7 @@ static void read_intr (ide_dev_t *dev)
msect -= nsect;
} else
nsect = 1;
IN_SECTORS(rq->buffer,nsect);
input_ide_data(dev, rq->buffer, nsect * SECTOR_WORDS);
#ifdef DEBUG
printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
dev->name, rq->sector, rq->sector+nsect-1,
......@@ -695,7 +776,7 @@ static void write_intr (ide_dev_t *dev)
int i;
struct request *rq = ide_cur_rq[DEV_HWIF];
if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_RW_STAT)) {
if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_W_STAT)) {
#ifdef DEBUG
printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
dev->name, rq->sector, (unsigned long) rq->buffer,
......@@ -711,7 +792,7 @@ static void write_intr (ide_dev_t *dev)
end_request(1, DEV_HWIF);
if (i > 0) {
ide_handler[DEV_HWIF] = &write_intr;
OUT_SECTORS(rq->buffer,1);
output_ide_data(dev, rq->buffer, SECTOR_WORDS);
return;
}
DO_REQUEST;
......@@ -734,7 +815,7 @@ static void multwrite (ide_dev_t *dev)
nsect = mcount;
mcount -= nsect;
OUT_SECTORS(rq->buffer,nsect);
output_ide_data(dev, rq->buffer, nsect<<7);
#ifdef DEBUG
printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n",
dev->name, rq->sector, (unsigned long) rq->buffer,
......@@ -762,7 +843,7 @@ static void multwrite_intr (ide_dev_t *dev)
int i;
struct request *rq = &ide_write_rq[DEV_HWIF];
if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_RW_STAT)) {
if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_W_STAT)) {
if (stat & DRQ_STAT) {
if (rq->nr_sectors) {
if (dev->mult_count)
......@@ -814,7 +895,7 @@ static void set_multmode_intr (ide_dev_t *dev)
printk (" %s: enabled %d-sector multiple mode\n",
dev->name, dev->mult_count);
else
printk (" %s: disabled multiple mode\n", dev->name);
printk (" %s: multiple mode turned off\n", dev->name);
}
DO_REQUEST;
}
......@@ -865,16 +946,24 @@ static void timer_expiry (byte hwif)
} else {
ide_handler[HWIF] = NULL;
disable_irq(ide_irq[HWIF]);
#if SUPPORT_SERIALIZE
if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1])
disable_irq(ide_irq[HWIF^1]);
#endif /* SUPPORT_SERIALIZE */
sti();
ide_error(ide_cur_dev[HWIF], "timeout", GET_STAT(HWIF));
do_request(HWIF);
#if SUPPORT_SHARING_IRQ
if (sharing_single_irq) /* this line is indeed necessary */
if (single_threaded) /* this line is indeed necessary */
hwif = current_hwif;
#endif /* SUPPORT_SHARING_IRQ */
cli();
start_ide_timer(HWIF);
enable_irq(ide_irq[HWIF]);
#if SUPPORT_SERIALIZE
if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1])
enable_irq(ide_irq[HWIF^1]);
#endif /* SUPPORT_SERIALIZE */
}
restore_flags(flags);
}
......@@ -983,7 +1072,7 @@ static inline int do_rw_disk (ide_dev_t *dev, struct request *rq, unsigned long
if (rq->cmd == WRITE) {
OUT_BYTE(dev->wpcom,HD_PRECOMP); /* for ancient drives */
OUT_BYTE(dev->mult_count ? WIN_MULTWRITE : WIN_WRITE, HD_COMMAND);
WAIT_STAT(dev, DATA_READY, BAD_RW_STAT, WAIT_DRQ, "DRQ", error);
WAIT_STAT(dev, DATA_READY, BAD_W_STAT, WAIT_DRQ, "DRQ", error);
if (!dev->unmask)
cli();
if (dev->mult_count) {
......@@ -991,7 +1080,7 @@ static inline int do_rw_disk (ide_dev_t *dev, struct request *rq, unsigned long
multwrite(dev);
ide_handler[DEV_HWIF] = &multwrite_intr;
} else {
OUT_SECTORS(rq->buffer,1);
output_ide_data(dev, rq->buffer, SECTOR_WORDS);
ide_handler[DEV_HWIF] = &write_intr;
}
return 0;
......@@ -1040,14 +1129,14 @@ static void do_request (byte hwif)
repeat:
sti();
#if SUPPORT_SHARING_IRQ
current_hwif = hwif; /* used *only* when sharing_single_irq==1 */
current_hwif = hwif; /* used *only* when single_threaded==1 */
#endif /* SUPPORT_SHARING_IRQ */
if ((rq = ide_cur_rq[HWIF]) == NULL) {
rq = blk_dev[ide_major[HWIF]].current_request;
if ((rq == NULL) || (rq->dev < 0)) {
#if SUPPORT_SHARING_IRQ
if (sharing_single_irq) {
if ((dev = ide_cur_dev[hwif])) /* disable irq */
if (single_threaded) {
if (sharing_single_irq && (dev = ide_cur_dev[hwif])) /* disable irq */
OUT_BYTE(dev->ctl|2,HD_CMD);
rq = blk_dev[ide_major[hwif^=1]].current_request;
if ((rq != NULL) && (rq->dev >= 0))
......@@ -1121,10 +1210,14 @@ static void do_request (byte hwif)
{ \
if (ide_handler[hwif] == NULL) { \
disable_irq(ide_irq[hwif]); \
if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \
disable_irq(ide_irq[hwif^1]); \
do_request(hwif); \
cli(); \
start_ide_timer(hwif); \
enable_irq(ide_irq[hwif]); \
if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \
enable_irq(ide_irq[hwif^1]); \
} \
}
......@@ -1169,10 +1262,12 @@ static void unexpected_intr (byte hwif)
if (!OK_STAT(stat=GET_STAT(HWIF), DRIVE_READY, BAD_STAT))
(void) dump_status(HWIF, "unexpected_intr", stat);
outb_p(2,IDE_PORT(HD_CMD,hwif)); /* disable device irq */
#if SUPPORT_SHARING_IRQ
if (sharing_single_irq) {
if (single_threaded && ide_irq[hwif] == ide_irq[hwif^1]) {
if (!OK_STAT(stat=GET_STAT(hwif^1), DRIVE_READY, BAD_STAT))
(void) dump_status(hwif^1, "unexpected_intr", stat);
outb_p(2,IDE_PORT(HD_CMD,hwif^1)); /* disable device irq */
}
#endif /* SUPPORT_SHARING_IRQ */
}
......@@ -1197,21 +1292,32 @@ static void unexpected_intr (byte hwif)
} else \
unexpected_intr(hwif); \
cli(); \
start_ide_timer(hwif); \
}
#if SUPPORT_SERIALIZE
/* entry point for all interrupts when single_threaded==1 */
static void ide_seq_intr (int irq, struct pt_regs *regs)
{
byte hwif = (irq != ide_irq[0]);
IDE_INTR(HWIF);
start_ide_timer(current_hwif);
}
#endif /* SUPPORT_SERIALIZE */
#if OPTIMIZE_IRQS
/* entry point for all interrupts on ide0 when sharing_single_irq==0 */
/* entry point for all interrupts on ide0 when single_threaded==0 */
static void ide0_intr (int irq, struct pt_regs *regs)
{
IDE_INTR(0);
start_ide_timer(0);
}
/* entry point for all interrupts on ide1 when sharing_single_irq==0 */
/* entry point for all interrupts on ide1 when single_threaded==0 */
static void ide1_intr (int irq, struct pt_regs *regs)
{
IDE_INTR(1);
start_ide_timer(1);
}
#else /* OPTIMIZE_IRQS */
......@@ -1219,13 +1325,14 @@ static void ide1_intr (int irq, struct pt_regs *regs)
#define ide0_intr ide_intr
#define ide1_intr ide_intr
/* entry point for all interrupts when sharing_single_irq==0 */
/* entry point for all interrupts when single_threaded==0 */
static void ide_intr (int irq, struct pt_regs *regs)
{
#if SUPPORT_TWO_INTERFACES
byte hwif = (irq != ide_irq[0]);
#endif /* SUPPORT_TWO_INTERFACES */
IDE_INTR(HWIF);
start_ide_timer(HWIF);
}
#endif /* OPTIMIZE_IRQS */
......@@ -1235,6 +1342,7 @@ static void ide_intr (int irq, struct pt_regs *regs)
static void ide_shared_intr (int irq, struct pt_regs * regs)
{
IDE_INTR(current_hwif);
start_ide_timer(current_hwif);
}
#endif /* SUPPORT_SHARING_IRQ */
......@@ -1454,6 +1562,9 @@ static int ide_ioctl (struct inode *inode, struct file *file,
case HDIO_GET_UNMASKINTR:
return write_fs_long(arg, dev->unmask);
case HDIO_GET_CHIPSET:
return write_fs_long(arg, dev->chipset);
case HDIO_GET_MULTCOUNT:
return write_fs_long(arg, dev->mult_count);
......@@ -1468,22 +1579,28 @@ static int ide_ioctl (struct inode *inode, struct file *file,
return 0;
case HDIO_SET_KEEPSETTINGS:
case HDIO_SET_UNMASKINTR:
if (!suser()) return -EACCES;
if ((arg > 1) || (MINOR(inode->i_rdev) & PARTN_MASK))
return -EINVAL;
save_flags(flags);
cli();
dev->keep_settings = arg;
if (cmd == HDIO_SET_KEEPSETTINGS)
dev->keep_settings = arg;
else
dev->unmask = arg;
restore_flags(flags);
return 0;
case HDIO_SET_UNMASKINTR:
case HDIO_SET_CHIPSET:
if (!suser()) return -EACCES;
if ((arg > 1) || (MINOR(inode->i_rdev) & PARTN_MASK))
if ((arg > 3) || (MINOR(inode->i_rdev) & PARTN_MASK))
return -EINVAL;
save_flags(flags);
cli();
dev->unmask = arg;
dev->chipset = arg;
dev->vlb_sync = (arg & 2) >> 1;
dev->vlb_32bit = (arg & 1);
restore_flags(flags);
return 0;
......@@ -1614,9 +1731,19 @@ static void do_identify (ide_dev_t *dev, byte cmd)
id = dev->id = (struct hd_driveid *) probe_mem_start; /* kmalloc() */
probe_mem_start += 512;
IN_SECTORS(id,1); /* read 512 bytes of id info */
input_ide_data(dev, id, SECTOR_WORDS); /* read 512 bytes of id info */
sti();
/*
* EATA SCSI controllers do a hardware ATA emulation: ignore them
*/
if ((id->model[0] == 'P' && id->model[1] == 'M')
|| (id->model[0] == 'S' && id->model[1] == 'K')) {
printk("%s: EATA SCSI HBA %.10s\n", dev->name, id->model);
dev->present = 0;
return;
}
/*
* WIN_IDENTIFY returns little-endian info,
* WIN_PIDENTIFY *usually* returns little-endian info.
......@@ -1769,7 +1896,7 @@ static int try_to_identify (ide_dev_t *dev, byte cmd)
delay_10ms(); /* give drive a breather */
} while (IN_BYTE(hd_status,DEV_HWIF) & BUSY_STAT);
delay_10ms(); /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)) {
if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_R_STAT)) {
cli(); /* some systems need this */
do_identify(dev, cmd); /* drive returned ID */
rc = 0; /* success */
......@@ -1957,8 +2084,22 @@ void ide_setup(char *str, int *ints)
if (dev->present)
printk("(redefined) ");
if (ints[0] == 0) {
#if SUPPORT_DTC2278
if (!strcmp(str,"dtc2278")) {
printk("%s\n",str);
probe_dtc2278 = 1; /* try to init DTC-2278 at boot */
return;
}
#endif /* SUPPORT_DTC2278 */
#if SUPPORT_SERIALIZE
if (!strcmp(str,"serialize") || !strcmp(str,"cmd")) {
printk("%s\n",str);
single_threaded = 1; /* serialize all drive access */
return;
}
#endif /* SUPPORT_SERIALIZE */
if (!strcmp(str,"noprobe")) {
printk("noprobe\n");
printk("%s\n",str);
dev->dont_probe = 1; /* don't probe for this drive */
return;
}
......@@ -2070,6 +2211,8 @@ static void init_ide_data (byte hwif)
dev->mult_count = 0; /* set by do_identify() */
dev->mult_req = 0; /* set by do_identify() */
dev->usage = 0;
dev->vlb_32bit = 0;
dev->vlb_sync = 0;
dev->id = NULL;
dev->ctl = 0x08;
dev->wqueue = NULL;
......@@ -2103,6 +2246,13 @@ static byte setup_irq (byte hwif)
}
handler = &ide_shared_intr;
}
#if SUPPORT_SERIALIZE
else if (single_threaded) {
handler = &ide_seq_intr;
if (HWIF != 0)
msg = " (single-threaded with ide0)";
}
#endif /* SUPPORT_SERIALIZE */
#endif /* SUPPORT_SHARING_IRQ */
save_flags(flags);
cli();
......@@ -2160,6 +2310,54 @@ static struct file_operations ide_fops = {
#endif CONFIG_BLK_DEV_IDECD
};
#if SUPPORT_DTC2278
/*
* From: andy@cercle.cts.com (Dyan Wile)
*
* Below is a patch for DTC-2278 - alike software-programmable controllers
* The code enables the secondary IDE controller and the PIO4 (3?) timings on
* the primary (EIDE). You may probably have to enable the 32-bit support to
* get the full speed. You better get the disk interrupts disabled ( hdparm -u0
* /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
* filesystem corrupted with -u 1, but under heavy disk load only :-)
*/
static void sub22 (char b, char c)
{
int i;
for(i = 0; i < 3; i++) {
__inb(0x3f6);
outb_p(b,0xb0);
__inb(0x3f6);
outb_p(c,0xb4);
__inb(0x3f6);
if(__inb(0xb4) == c) {
outb_p(7,0xb0);
__inb(0x3f6);
return; /* success */
}
}
}
static void try_to_init_dtc2278 (void)
{
/* This (presumably) enables PIO mode4 (3?) on the first interface */
cli();
sub22(1,0xc3);
sub22(0,0xa0);
sti();
/* This enables the second interface */
outb_p(4,0xb0);
__inb(0x3f6);
outb_p(0x20,0xb4);
__inb(0x3f6);
}
#endif /* SUPPORT_DTC2278 */
/*
* This is gets invoked once during initialization, to set *everything* up
*/
......@@ -2167,6 +2365,11 @@ unsigned long ide_init (unsigned long mem_start, unsigned long mem_end)
{
byte hwif;
#if SUPPORT_DTC2278
if (probe_dtc2278)
try_to_init_dtc2278();
#endif /* SUPPORT_DTC2278 */
/* single_threaded = 0; */ /* zero by default, override at boot */
for (hwif = 0; hwif < 2; hwif++) {
init_ide_data (hwif);
if (SUPPORT_TWO_INTERFACES || hwif == HWIF) {
......@@ -2191,6 +2394,7 @@ unsigned long ide_init (unsigned long mem_start, unsigned long mem_end)
} else {
#if SUPPORT_SHARING_IRQ
sharing_single_irq = 1;
single_threaded = 1;
#else /* SUPPORT_SHARING_IRQ */
printk("%s: ide irq-sharing%s", ide_name[1], unsupported);
return mem_start;
......@@ -2218,7 +2422,7 @@ unsigned long ide_init (unsigned long mem_start, unsigned long mem_end)
timer_table[ide_timer[HWIF]].fn
= HWIF ? ide1_timer_expiry : ide0_timer_expiry;
#if SUPPORT_SHARING_IRQ
if (sharing_single_irq)
if (single_threaded)
blk_dev[major].request_fn = &do_shared_request;
else
#endif /* SUPPORT_SHARING_IRQ */
......
static char rcsid[] =
"$Revision: 1.36.1.3 $$Date: 1995/03/23 22:15:35 $";
"$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $";
/*
* linux/kernel/cyclades.c
*
......@@ -18,6 +18,9 @@ static char rcsid[] =
* int cy_open(struct tty_struct *tty, struct file *filp);
*
* $Log: cyclades.c,v $
* Revision 1.36.1.4 1995/03/29 06:14:14 bentson
* disambiguate between Cyclom-16Y and Cyclom-32Ye;
*
* Revision 1.36.1.3 1995/03/23 22:15:35 bentson
* add missing break in modem control block in ioctl switch statement
* (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
......@@ -2638,6 +2641,17 @@ cy_init_card(unsigned char *true_base_addr)
base_addr[CyGFRCR] = 0;
udelay(10L);
/* The Cyclom-16Y does not decode address bit 9 and therefore
cannot distinguish between references to chip 0 and a non-
existent chip 4. If the preceeding clearing of the supposed
chip 4 GFRCR register appears at chip 0, there is no chip 4
and this must be a Cyclom-16Y, not a Cyclom-32Ye.
*/
if (chip_number == 4
&& *(true_base_addr + cy_chip_offset[0] + CyGFRCR) == 0){
return chip_number;
}
base_addr[CyCCR] = CyCHIP_RESET;
udelay(1000L);
......
......@@ -71,12 +71,6 @@ loopback_xmit(struct sk_buff *skb, struct device *dev)
dev->tbusy = 0;
if (!intr_count && (bh_active & bh_mask)) {
start_bh_atomic();
do_bottom_half();
end_bh_atomic();
}
return(0);
}
......
......@@ -2,7 +2,7 @@ Wed Apr 12 15:25:52 1995 Eric Youngdale (eric@andante)
* Linux 1.2.5 released.
* buslogic.c: Update to version 1.15 (From Dave G, I expect).
* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
Fixed interrupt routine to avoid races when handling multiple
complete commands per interrupt. Seems to come up with faster
cards.
......
......@@ -1555,7 +1555,7 @@ void buslogic_setup(char *str, int *ints)
bases[setup_idx] = 0;
return;
}
buslogic_printk("invalid base 0x%X specified.\n", ints[i]);
buslogic_printk("invalid base 0x%X specified.\n", ints[1]);
}
#ifdef MODULE
......
......@@ -124,22 +124,22 @@ st_chk_result(Scsi_Cmnd * SCpnt)
SCpnt->request_bufflen);
if (driver_byte(result) & DRIVER_SENSE)
print_sense("st", SCpnt);
} else
}
#endif
scode = sense[2] & 0x0f;
if (!(driver_byte(result) & DRIVER_SENSE) ||
((sense[0] & 0x70) == 0x70 &&
scode != NO_SENSE &&
scode != RECOVERED_ERROR &&
scode != UNIT_ATTENTION &&
scode != BLANK_CHECK &&
scode != VOLUME_OVERFLOW)) { /* Abnormal conditions for tape */
printk("st%d: Error %x. ", dev, result);
if (driver_byte(result) & DRIVER_SENSE)
print_sense("st", SCpnt);
else
printk("\n");
}
scode = sense[2] & 0x0f;
if (!(driver_byte(result) & DRIVER_SENSE) ||
((sense[0] & 0x70) == 0x70 &&
scode != NO_SENSE &&
scode != RECOVERED_ERROR &&
scode != UNIT_ATTENTION &&
scode != BLANK_CHECK &&
scode != VOLUME_OVERFLOW)) { /* Abnormal conditions for tape */
printk("st%d: Error %x. ", dev, result);
if (driver_byte(result) & DRIVER_SENSE)
print_sense("st", SCpnt);
else
printk("\n");
}
if ((sense[0] & 0x70) == 0x70 &&
scode == RECOVERED_ERROR
......
NOTE!
This is an ALPHA TEST VERSION (pre 3.0). The latest
released version of this driver is now part of
Linux kernel distribution. For other operating systems
use the snd-driv-2.5.tar.gz package.
This particular version contains lots of new features
BUT THERE ARE NO APPLICATIONS WHICH USE THEM. So there
is no need to install this version as long as you are
not developing the driver or applications which use it.
All new features are in the /dev/sequencer and /dev/midi
parts of the driver.
This version is little bit incomplete. Some features have
not been implemented for each soundcards yet. All features
of v2.4 should work OK.
CAUTION!
This version of driver works with applications written and
compiled for v2.*. The problem is that APPLICATIONS COMPILED
WITH soundcard.h OF THIS VERSION WILL NOT WORK WITH OLDER DRIVER.
Be careful when distributing applications compiled with this
version (just the apps using /dev/sequencer are incompatible).
*********************************************************
* IF YOU HAVE ANY PROBLEMS WITH THE SOUND DRIVER, *
......@@ -30,5 +5,3 @@ CAUTION!
* NEAREST LINUX FTP SITE AND CONTAINS ANSWER TO YOUR *
* PROBLEM. *
*********************************************************
Hannu
......@@ -973,7 +973,7 @@ static void read_buffers(struct buffer_head * bh[], int nrbuf)
}
if (bhnum)
ll_rw_block(READ, bhnum, bhr);
for (i = 0 ; i < nrbuf ; i++) {
for (i = nrbuf ; --i >= 0 ; ) {
if (bh[i]) {
wait_on_buffer(bh[i]);
}
......
......@@ -277,6 +277,8 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
return -ENOENT;
if (IS_RDONLY(inode))
return -EROFS;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
......@@ -299,6 +301,10 @@ asmlinkage int sys_chmod(const char * filename, mode_t mode)
iput(inode);
return -EROFS;
}
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
iput(inode);
return -EPERM;
}
if (mode == (mode_t) -1)
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
......@@ -322,6 +328,8 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
return -ENOENT;
if (IS_RDONLY(inode))
return -EROFS;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
......@@ -362,6 +370,10 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
iput(inode);
return -EROFS;
}
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
iput(inode);
return -EPERM;
}
if (user == (uid_t) -1)
user = inode->i_uid;
if (group == (gid_t) -1)
......
#define THREE_LEVEL
/*
* linux/fs/proc/array.c
*
......
#define THREE_LEVEL
/*
* linux/fs/proc/mem.c
*
......
......@@ -21,12 +21,6 @@ extern char ignore_irq13;
extern char wp_works_ok; /* doesn't work on a 386 */
extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */
#define start_bh_atomic() \
__asm__ __volatile__("incl _intr_count")
#define end_bh_atomic() \
__asm__ __volatile__("decl _intr_count")
/*
* Bus types (default is ISA, but people can check others with these..)
* MCA_bus hardcoded to 0 for now.
......
......@@ -78,12 +78,14 @@ struct hd_geometry {
#define HDIO_GET_MULTCOUNT 0x304 /* get current IDE blockmode setting */
#define HDIO_GET_IDENTITY 0x307 /* get IDE identification info */
#define HDIO_GET_KEEPSETTINGS 0x308 /* get keep-settings-on-reset flag */
#define HDIO_GET_CHIPSET 0x309 /* get current interface type setting */
#define HDIO_DRIVE_CMD 0x31f /* execute a special drive command */
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x32n/0x33n */
#define HDIO_SET_MULTCOUNT 0x321 /* set IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x322 /* permit other irqs during I/O */
#define HDIO_SET_KEEPSETTINGS 0x323 /* keep ioctl settings on reset */
#define HDIO_SET_CHIPSET 0x324 /* optimise driver for interface type */
/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
struct hd_driveid {
......
......@@ -45,6 +45,18 @@ extern inline void enable_bh(int nr)
set_bit(nr, &bh_mask);
}
extern inline void start_bh_atomic(void)
{
intr_count++;
}
extern inline void end_bh_atomic(void)
{
if (intr_count == 1 && (bh_active & bh_mask))
do_bottom_half();
intr_count--;
}
/*
* Autoprobing for irqs:
*
......
......@@ -388,7 +388,7 @@ struct pci_vendor_type {
{PCI_VENDOR_ID_CONTAQ, "Contaq"}, \
{PCI_VENDOR_ID_NS, "NS"}, \
{PCI_VENDOR_ID_VIA, "VIA Technologies"}, \
{PCI_VENDOR_ID_SI, "Silicon Integrated"}, \
{PCI_VENDOR_ID_SI, "Silicon Integrated Systems"}, \
{PCI_VENDOR_ID_LEADTEK, "Leadtek Research"}, \
{PCI_VENDOR_ID_IMS, "IMS"}, \
{PCI_VENDOR_ID_ZEINET, "ZeiNet"}, \
......
#define THREE_LEVEL
/*
* linux/ipc/shm.c
* Copyright (C) 1992, 1993 Krishna Balasubramanian
......
......@@ -745,7 +745,7 @@ register_symtab(struct symbol_table *intab)
link && (link != &kernel_module);
link = link->next) {
if (link->ref->module == mp)
if (link->ref && (link->ref->module == mp))
link->ref = newref++;
}
......
......@@ -13,7 +13,7 @@
#include <linux/types.h>
#include <linux/ioport.h>
#define IOTABLE_SIZE 32
#define IOTABLE_SIZE 64
typedef struct resource_entry_t {
u_long from, num;
......
#define THREE_LEVEL
/*
* linux/mm/filemmap.c
*
......
#define THREE_LEVEL
/*
* linux/mm/memory.c
*
......
#define THREE_LEVEL
/*
* linux/mm/mprotect.c
*
......
#define THREE_LEVEL
/*
* linux/mm/swap.c
*
......
#define THREE_LEVEL
/*
* linux/mm/vmalloc.c
*
......
......@@ -815,8 +815,8 @@ static int inet_release(struct socket *sock, struct socket *peer)
sk->inuse = 1;
/* This will destroy it. */
release_sock(sk);
sock->data = NULL;
release_sock(sk);
sk->socket = NULL;
return(0);
}
......@@ -939,8 +939,12 @@ static int inet_connect(struct socket *sock, struct sockaddr * uaddr,
return 0; /* Rock and roll */
}
if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK))
return -EALREADY; /* Connecting is currently in progress */
if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK)) {
if (sk->err != 0)
return -sk->err; /* Connection must have failed */
else
return -EALREADY; /* Connecting is currently in progress */
}
if (sock->state != SS_CONNECTING)
{
......
......@@ -337,7 +337,9 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
* Make sure we haven't missed an interrupt.
*/
printk("dev_queue_xmit: worked around a missed interrupt\n");
start_bh_atomic();
dev->hard_start_xmit(NULL, dev);
end_bh_atomic();
return;
}
......@@ -409,12 +411,15 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
}
}
}
start_bh_atomic();
if (dev->hard_start_xmit(skb, dev) == 0) {
end_bh_atomic();
/*
* Packet is now solely the responsibility of the driver
*/
return;
}
end_bh_atomic();
/*
* Transmission failed, put skb back into a list. Once on the list it's safe and
......
......@@ -1489,7 +1489,8 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* (4. We ought to check for IP multicast addresses and undefined types.. does this matter ?)
*/
if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)
if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 ||
skb->len<ntohs(iph->tot_len) || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)
{
ip_statistics.IpInHdrErrors++;
kfree_skb(skb, FREE_WRITE);
......@@ -2090,8 +2091,6 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
unsigned char ucval;
ucval=get_fs_byte((unsigned char *)optval);
if(ucval<1||ucval>255)
return -EINVAL;
sk->ip_mc_ttl=(int)ucval;
return 0;
}
......
......@@ -934,6 +934,8 @@ static int tcp_select(struct sock *sk, int sel_type, select_table *wait)
break;
case SEL_OUT:
if (sk->err)
return 1;
if (sk->shutdown & SEND_SHUTDOWN)
return 0;
if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)
......@@ -948,7 +950,7 @@ static int tcp_select(struct sock *sk, int sel_type, select_table *wait)
return 1;
case SEL_EX:
if (sk->err || sk->urg_data)
if (sk->urg_data)
return 1;
break;
}
......
......@@ -481,7 +481,7 @@ static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
old_fs = get_fs();
set_fs(get_ds());
i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
i = open_namei(fname, 2, S_IFSOCK, &inode, NULL);
set_fs(old_fs);
if (i < 0)
{
......
......@@ -11,12 +11,15 @@ TOPINCL := $(TOPDIR)/include/linux
.SUFFIXES: .ver
.c.ver:
$(CC) $(CFLAGS) -E -D__GENKSYMS__ $< | genksyms -w $(TOPINCL)/modules
@if [ ! -x /sbin/genksyms ]; then echo "Please read: README.modules"; fi
$(CC) $(CFLAGS) -E -DCONFIG_MODVERSIONS -D__GENKSYMS__ $< | /sbin/genksyms -w $(TOPINCL)/modules
@ln -sf $(TOPINCL)/modules/$@ .
$(SYMTAB_OBJS):
$(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c)
$(SYMTAB_OBJS:.o=.ver): $(TOPINCL)/autoconf.h
$(TOPINCL)/modversions.h: $(SYMTAB_OBJS:.o=.ver)
@echo updating $(TOPINCL)/modversions.h
@(cd $(TOPINCL)/modules; for f in *.ver;\
......
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