Commit 2b2c89a1 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.23

parent 8f0ec1f9
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 22
SUBLEVEL = 23
ARCH = i386
......
......@@ -49,6 +49,16 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
goto bad_area;
if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
goto bad_area;
if (error_code & 4) {
/*
* accessing the stack below %esp is always a bug.
* The "+ 32" is there due to some instructions (like
* pusha) doing pre-decrement on the stack and that
* doesn't show up until later..
*/
if (address + 32 < regs->esp)
goto bad_area;
}
vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
vma->vm_start = (address & PAGE_MASK);
/*
......
......@@ -46,6 +46,9 @@ NEW! - should work for for EZ-Drive disks as well (not verified)
NEW! - ide-cd.c now compiles separate from ide.c
NEW! - Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces
NEW! - for details, see comments at top of triton.c
NEW! - ide-cd.c now supports door locking and auto-loading.
NEW! Also preliminary support for multisession and direct
NEW! reads of audio data.
For work in progress, see the comments in ide.c, ide-cd.c, and triton.c.
......@@ -161,6 +164,31 @@ interface (/dev/hda) and an IDE cdrom drive on the secondary interface
mkdir /cd
mount /dev/cdrom /cd -t iso9660 -o ro
If, after doing all of the above, mount doesn't work and you see
errors from the driver (with dmesg) complaining about `status=0xff',
this means that the hardware is not responding to the driver's attempts
to read it. One of the following is probably the problem:
- Your hardware is broken.
- You are using the wrong address for the device, or you have the
drive jumpered wrong. Review the configuration instructions above.
- Your IDE controller requires some nonstandard initialization sequence
before it will work properly. If this is the case, there will often
be a separate MS-DOS driver just for the controller. IDE interfaces
on sound cards usually fall into this category. Such configurations
can often be made to work by first booting MS-DOS, loading the
appropriate drivers, and then warm-booting linux (without powering
off). This can be automated using loadlin in the MS-DOS autoexec.
If you always get timeout errors, interrupts from the drive are probably
not making it to the host. Check how you have the hardware jumpered
and make sure it matches what the driver expects (see the configuration
instructions above). If you have a PCI system, also check the BIOS
setup; i've had one report of a system which was shipped with IRQ 15
disabled by the BIOS.
The kernel is able to execute binaries directly off of the cdrom,
provided it is mounted with the default block size of 1024 (as above).
......
......@@ -3,20 +3,17 @@
* linux/kernel/hd.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
*
*
* Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
* in the early extended-partition checks and added DM partitions
*/
/*
*
* Support for DiskManager v6.0x added by Mark Lord (mlord@bnr.ca)
* with information provided by OnTrack. This now works for linux fdisk
* and LILO, as well as loadlin and bootln. Note that disks other than
* /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
*
* Added support for "missing/deleted" extended partitions - mlord@bnr.ca
*
* More flexible handling of extended partitions - aeb, 950831
*/
#include <linux/config.h>
......@@ -82,14 +79,15 @@ static void extended_partition(struct gendisk *hd, int dev)
{
struct buffer_head *bh;
struct partition *p;
unsigned long first_sector, this_sector;
unsigned long first_sector, this_sector, this_size;
int mask = (1 << hd->minor_shift) - 1;
int i;
first_sector = hd->part[MINOR(dev)].start_sect;
this_sector = first_sector;
while (1) {
if ((current_minor & mask) >= (4 + hd->max_p))
if ((current_minor & mask) >= hd->max_p)
return;
if (!(bh = bread(dev,0,1024)))
return;
......@@ -100,29 +98,56 @@ static void extended_partition(struct gendisk *hd, int dev)
bh->b_dirt = 0;
bh->b_uptodate = 0;
bh->b_req = 0;
if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
goto done;
p = (struct partition *) (0x1BE + bh->b_data);
this_size = hd->part[MINOR(dev)].nr_sects;
/*
* Process the first entry, which should be the real
* data partition.
* Usually, the first entry is the real data partition,
* the 2nd entry is the next extended partition, or empty,
* and the 3rd and 4th entries are unused.
* However, DRDOS sometimes has the extended partition as
* the first entry (when the data partition is empty),
* and OS/2 seems to use all four entries.
*/
if (p->sys_ind == EXTENDED_PARTITION)
goto done; /* shouldn't happen */
if (p->sys_ind && p->nr_sects)
add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
current_minor++;
p++;
/*
* First process the data partition(s)
*/
for (i=0; i<4; i++, p++) {
if (!p->nr_sects || p->sys_ind == EXTENDED_PARTITION)
continue;
if (p->start_sect + p->nr_sects > this_size)
continue;
add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
current_minor++;
if ((current_minor & mask) >= hd->max_p)
goto done;
}
/*
* Process the second entry, which should be a link
* to the next logical partition. Create a minor
* for this just long enough to get the next partition
* table. The minor will be reused for the real
* Next, process the (first) extended partition, if present.
* (So far, there seems to be no reason to make
* extended_partition() recursive and allow a tree
* of extended partitions.)
* It should be a link to the next logical partition.
* Create a minor for this just long enough to get the next
* partition table. The minor will be reused for the next
* data partition.
*/
if (p->sys_ind != EXTENDED_PARTITION ||
!(hd->part[current_minor].nr_sects = p->nr_sects))
goto done; /* no more logicals in this partition */
p -= 4;
for (i=0; i<4; i++, p++)
if(p->nr_sects && p->sys_ind == EXTENDED_PARTITION)
break;
if (i == 4)
goto done; /* nothing left to do */
hd->part[current_minor].nr_sects = p->nr_sects;
hd->part[current_minor].start_sect = first_sector + p->start_sect;
this_sector = first_sector + p->start_sect;
dev = ((hd->major) << 8) | current_minor;
......@@ -211,6 +236,9 @@ static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long f
printk(" <");
extended_partition(hd, (hd->major << 8) | minor);
printk(" >");
/* prevent someone doing mkfs or mkswap on
an extended partition */
hd->part[minor].nr_sects = 0;
}
}
/*
......
This diff is collapsed.
This diff is collapsed.
......@@ -17,11 +17,10 @@
/******************************************************************************
* IDE driver configuration options (play with these as desired):
*
* REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <asm/io.h>
#undef REALLY_FAST_IO /* define if ide ports are perfect */
#define REALLY_FAST_IO /* define if ide ports are perfect */
#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */
#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */
......@@ -81,14 +80,25 @@ typedef unsigned char byte; /* used everywhere */
#define HWIF(drive) ((ide_hwif_t *)drive->hwif)
#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))
#define IDE_DATA_REG (HWIF(drive)->io_base)
#define IDE_ERROR_REG (HWIF(drive)->io_base+1)
#define IDE_NSECTOR_REG (HWIF(drive)->io_base+2)
#define IDE_SECTOR_REG (HWIF(drive)->io_base+3)
#define IDE_LCYL_REG (HWIF(drive)->io_base+4)
#define IDE_HCYL_REG (HWIF(drive)->io_base+5)
#define IDE_SELECT_REG (HWIF(drive)->io_base+6)
#define IDE_STATUS_REG (HWIF(drive)->io_base+7)
#define IDE_DATA_OFFSET (0)
#define IDE_ERROR_OFFSET (1)
#define IDE_NSECTOR_OFFSET (2)
#define IDE_SECTOR_OFFSET (3)
#define IDE_LCYL_OFFSET (4)
#define IDE_HCYL_OFFSET (5)
#define IDE_SELECT_OFFSET (6)
#define IDE_STATUS_OFFSET (7)
#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET
#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
#define IDE_DATA_REG (HWIF(drive)->io_base+IDE_DATA_OFFSET)
#define IDE_ERROR_REG (HWIF(drive)->io_base+IDE_ERROR_OFFSET)
#define IDE_NSECTOR_REG (HWIF(drive)->io_base+IDE_NSECTOR_OFFSET)
#define IDE_SECTOR_REG (HWIF(drive)->io_base+IDE_SECTOR_OFFSET)
#define IDE_LCYL_REG (HWIF(drive)->io_base+IDE_LCYL_OFFSET)
#define IDE_HCYL_REG (HWIF(drive)->io_base+IDE_HCYL_OFFSET)
#define IDE_SELECT_REG (HWIF(drive)->io_base+IDE_SELECT_OFFSET)
#define IDE_STATUS_REG (HWIF(drive)->io_base+IDE_STATUS_OFFSET)
#define IDE_CONTROL_REG (HWIF(drive)->ctl_port)
#define IDE_FEATURE_REG IDE_ERROR_REG
#define IDE_COMMAND_REG IDE_STATUS_REG
......@@ -414,6 +424,17 @@ int ide_do_reset (ide_drive_t *);
*/
void *ide_alloc (unsigned long bytecount, unsigned long within_area);
/*
* This function issues a specific IDE drive command onto the
* tail of the request queue, and waits for it to be completed.
* If arg is NULL, it goes through all the motions,
* but without actually sending a command to the drive.
*
* The value of arg is passed to the internal handler as rq->buffer.
*/
int ide_do_drive_cmd(int rdev, char *args);
#ifdef CONFIG_BLK_DEV_IDECD
/*
* These are routines in ide-cd.c invoked from ide.c
......
......@@ -194,6 +194,29 @@ static int build_dmatable (ide_drive_t *drive)
return 1; /* let the PIO routines handle this weirdness */
}
static int config_drive_for_dma (ide_drive_t *drive)
{
const char **list;
struct hd_driveid *id = drive->id;
if (id && (id->capability & 1)) {
/* Enable DMA on any drive that supports mword2 DMA */
if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
/* Consult the list of known "good" drives */
list = good_dma_drives;
while (*list) {
if (!strcmp(*list++,id->model)) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
}
}
return 1; /* DMA not enabled */
}
/*
* triton_dmaproc() initiates/aborts DMA read/write operations on a drive.
*
......@@ -207,40 +230,31 @@ static int build_dmatable (ide_drive_t *drive)
*/
static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
const char **list;
unsigned long dma_base = HWIF(drive)->dma_base;
unsigned int reading = (1 << 3);
if (func == ide_dma_abort) {
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
return 0;
}
if (func == ide_dma_check) {
struct hd_driveid *id = drive->id;
if (id && (id->capability & 1)) {
/* Enable DMA on any drive that supports mword2 DMA */
if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
/* Consult the list of known "good" drives */
list = good_dma_drives;
while (*list) {
if (!strcmp(*list++,id->model)) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
}
}
return 1; /* DMA not enabled */
switch (func) {
case ide_dma_abort:
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
return 0;
case ide_dma_check:
return config_drive_for_dma (drive);
case ide_dma_write:
reading = 0;
case ide_dma_read:
break;
default:
printk("triton_dmaproc: unsupported func: %d\n", func);
return 1;
}
if (build_dmatable (drive))
return 1;
outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */
outb((!func) << 3, dma_base); /* specify r/w */
outb(reading, dma_base); /* specify r/w */
outb(0x26, dma_base+2); /* clear status bits */
ide_set_handler (drive, &dma_intr); /* issue cmd to drive */
OUT_BYTE(func ? WIN_WRITEDMA : WIN_READDMA, IDE_COMMAND_REG);
outb(inb(dma_base)|1, dma_base); /* begin DMA */
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
outb(inb(dma_base)|1, dma_base); /* begin DMA */
return 0;
}
......@@ -326,8 +340,8 @@ void ide_init_triton (byte bus, byte fn)
base = bmiba + 8;
} else
continue;
printk(" %s: BusMaster DMA at 0x%04x-0x%04x", hwif->name, base, base+5);
if (check_region(base, 6)) {
printk(" %s: BusMaster DMA at 0x%04x-0x%04x", hwif->name, base, base+7);
if (check_region(base, 8)) {
printk(" -- ERROR, PORTS ALREADY IN USE");
} else {
unsigned long *table;
......
......@@ -245,8 +245,6 @@ endif
ifdef CONFIG_ARCNET
L_OBJS += arcnet.o
else
M_OBJS += arcnet.o
endif
ifdef CONFIG_PI
......
......@@ -319,10 +319,14 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
for (port = lance_portlist; *port; port++) {
int ioaddr = *port;
if ( check_region(ioaddr, LANCE_TOTAL_SIZE) == 0
&& inb(ioaddr + 14) == 0x57
&& inb(ioaddr + 15) == 0x57) {
mem_start = lance_probe1(ioaddr, mem_start);
if ( check_region(ioaddr, LANCE_TOTAL_SIZE) == 0) {
/* Detect "normal" 0x57 0x57 and the NI6510EB 0x52 0x44
signatures w/ minimal I/O reads */
char offset15, offset14 = inb(ioaddr + 14);
if ((offset14 == 0x52 || offset14 == 0x57) &&
((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
mem_start = lance_probe1(ioaddr, mem_start);
}
}
......
......@@ -121,10 +121,11 @@ __IN(b,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned short
/* __IN(w,"w","0" (0)) */
__IN(w,)
__IN(w,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned int
__IN(l,"")
#undef RETURN_TYPE
__OUT(b,"b",char)
__OUT(w,"w",short)
......
#ifndef _LINUX_HDREG_H
#define _LINUX_HDREG_H
#include <linux/config.h>
/*
* This file contains some defines for the AT-hd-controller.
* Various sources.
......@@ -154,9 +152,12 @@ struct hd_driveid {
/* unsigned short reservedyy[96];*/ /* reserved (words 160-255) */
};
#ifdef __KERNEL__
/*
* These routines are used for kernel command line parameters from main.c:
*/
#include <linux/config.h>
#ifdef CONFIG_BLK_DEV_HD
void hd_setup(char *, int *);
#endif /* CONFIG_BLK_DEV_HD */
......@@ -164,4 +165,6 @@ void hd_setup(char *, int *);
void ide_setup(char *);
#endif /* CONFIG_BLK_DEV_IDE */
#endif /* __KERNEL__ */
#endif /* _LINUX_HDREG_H */
......@@ -25,7 +25,7 @@
struct igmphdr
{
unsigned char type;
unsigned char unused;
unsigned char code;
unsigned short csum;
unsigned long group;
};
......@@ -37,7 +37,7 @@ struct igmphdr
struct igmp_header
{
unsigned char type;
unsigned char unused;
unsigned char code;
unsigned short csum;
unsigned long group;
};
......
......@@ -110,6 +110,8 @@ struct mcd_Toc {
struct msf diskTime;
};
#if 0
#ifndef I_WAS_HERE
#error Please edit this file first.
#endif
#endif
......@@ -173,6 +173,8 @@
#define MCDX_E 1 /* unspec error */
#define MCDX_EOM 2 /* end of media */
#if 0
#ifndef I_WAS_HERE
#error Please edit this file first.
#endif
#endif
......@@ -1305,7 +1305,7 @@ int dev_ioctl(unsigned int cmd, void *arg)
void dev_init(void)
{
struct device *dev, *dev2;
struct device *dev, **dp;
/*
* Add the devices.
......@@ -1313,24 +1313,25 @@ void dev_init(void)
* from the chain disconnecting the device until the
* next reboot.
*/
dev2 = NULL;
for (dev = dev_base; dev != NULL; dev=dev->next)
dp = &dev_base;
while ((dev = *dp) != NULL)
{
int i;
for (i = 0; i < DEV_NUMBUFFS; i++) {
skb_queue_head_init(dev->buffs + i);
}
if (dev->init && dev->init(dev))
{
/*
* It failed to come up. Unhook it.
*/
if (dev2 == NULL)
dev_base = dev->next;
else
dev2->next = dev->next;
*dp = dev->next;
}
else
{
dev2 = dev;
dp = &dev->next;
}
}
proc_net_register(&(struct proc_dir_entry) {
......@@ -1339,6 +1340,5 @@ void dev_init(void)
0, &proc_net_inode_operations,
dev_get_info
});
}
......@@ -1819,7 +1819,7 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
iph->tot_len = ntohs(skb->len-(((unsigned char *)iph)-skb->data));
#ifdef CONFIG_IP_FIREWALL
if(ip_fw_chk(iph, dev, ip_fw_blk_chain, ip_fw_blk_policy, 0) != 1)
if(ip_fw_chk(iph, dev, ip_fw_blk_chain, ip_fw_blk_policy, 0) < 1)
/* just don't send this packet */
return;
#endif
......
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