Commit f2e73398 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.100pre3

parent 57afa237
......@@ -258,6 +258,184 @@ int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
return -1;
}
static int irq_trigger(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
int trigger;
/*
* Determine IRQ trigger mode (edge or level sensitive):
*/
switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
{
case 0: /* conforms, ie. bus-type dependent */
{
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin, edge */
{
trigger = 0;
break;
}
case MP_BUS_PCI: /* PCI pin, level */
{
trigger = 1;
break;
}
default:
{
printk("broken BIOS!!\n");
trigger = 1;
break;
}
}
break;
}
case 1: /* edge */
{
trigger = 0;
break;
}
case 2: /* reserved */
{
printk("broken BIOS!!\n");
trigger = 1;
break;
}
case 3: /* level */
{
trigger = 1;
break;
}
default: /* invalid */
{
printk("broken BIOS!!\n");
trigger = 0;
break;
}
}
return trigger;
}
__initfunc(static int irq_polarity(int idx))
{
int bus = mp_irqs[idx].mpc_srcbus;
int polarity;
/*
* Determine IRQ line polarity (high active or low active):
*/
switch (mp_irqs[idx].mpc_irqflag & 3)
{
case 0: /* conforms, ie. bus-type dependent polarity */
{
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin */
{
polarity = 0;
break;
}
case MP_BUS_PCI: /* PCI pin */
{
polarity = 1;
break;
}
default:
{
printk("broken BIOS!!\n");
polarity = 1;
break;
}
}
break;
}
case 1: /* high active */
{
polarity = 0;
break;
}
case 2: /* reserved */
{
printk("broken BIOS!!\n");
polarity = 1;
break;
}
case 3: /* low active */
{
polarity = 1;
break;
}
default: /* invalid */
{
printk("broken BIOS!!\n");
polarity = 1;
break;
}
}
return polarity;
}
__initfunc(static int pin_2_irq (int idx, int pin))
{
int irq;
int bus = mp_irqs[idx].mpc_srcbus;
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin */
{
irq = mp_irqs[idx].mpc_srcbusirq;
break;
}
case MP_BUS_PCI: /* PCI pin */
{
/*
* PCI IRQs are 'directly mapped'
*/
irq = pin;
break;
}
default:
{
printk("unknown bus type %d.\n",bus);
irq = 0;
break;
}
}
/*
* PCI IRQ command line redirection. Yes, limits are hardcoded.
*/
if ((pin>=16) && (pin<=23)) {
if (pirq_entries[pin-16] != -1) {
if (!pirq_entries[pin-16]) {
printk("disabling PIRQ%d\n", pin-16);
} else {
irq = pirq_entries[pin-16];
printk("using PIRQ%d -> IRQ %d\n",
pin-16, irq);
}
}
}
return irq;
}
int IO_APIC_irq_trigger (int irq)
{
int idx, i;
for (i=0; i<nr_ioapic_registers; i++) {
idx = find_irq_entry(i,mp_INT);
if (irq == pin_2_irq(idx,i))
return irq_trigger(idx);
}
/*
* nonexistant IRQs are edge default
*/
return 0;
}
__initfunc(void setup_IO_APIC_irqs (void))
{
struct IO_APIC_route_entry entry;
......@@ -286,139 +464,17 @@ __initfunc(void setup_IO_APIC_irqs (void))
printk(", %d", i);
continue;
}
bus = mp_irqs[idx].mpc_srcbus;
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin */
{
irq = mp_irqs[idx].mpc_srcbusirq;
break;
}
case MP_BUS_PCI: /* PCI pin */
{
/*
* PCI IRQs are 'directly mapped'
*/
irq = i;
break;
}
default:
{
printk("unknown bus type %d.\n",bus);
irq = 0;
break;
}
}
entry.trigger = irq_trigger(idx);
entry.polarity = irq_polarity(idx);
/*
* PCI IRQ redirection. Yes, limits are hardcoded.
*/
if ((i>=16) && (i<=23)) {
if (pirq_entries[i-16] != -1) {
if (!pirq_entries[i-16]) {
printk("disabling PIRQ%d\n", i-16);
} else {
irq = pirq_entries[i-16];
printk("using PIRQ%d -> IRQ %d\n",
i-16, irq);
}
}
}
irq = pin_2_irq(idx,i);
if (!IO_APIC_IRQ(irq))
continue;
entry.vector = IO_APIC_VECTOR(irq);
/*
* Determine IRQ line polarity (high active or low active):
*/
switch (mp_irqs[idx].mpc_irqflag & 3)
{
case 0: /* conforms, ie. bus-type dependent polarity */
{
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin */
{
entry.polarity = 0;
break;
}
case MP_BUS_PCI: /* PCI pin */
{
entry.polarity = 1;
break;
}
default:
{
printk("broken BIOS!!\n");
break;
}
}
break;
}
case 1: /* high active */
{
entry.polarity = 0;
break;
}
case 2: /* reserved */
{
printk("broken BIOS!!\n");
break;
}
case 3: /* low active */
{
entry.polarity = 1;
break;
}
}
/*
* Determine IRQ trigger mode (edge or level sensitive):
*/
switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
{
case 0: /* conforms, ie. bus-type dependent */
{
switch (mp_bus_id_to_type[bus])
{
case MP_BUS_ISA: /* ISA pin, edge */
{
entry.trigger = 0;
break;
}
case MP_BUS_PCI: /* PCI pin, level */
{
entry.trigger = 1;
break;
}
default:
{
printk("broken BIOS!!\n");
break;
}
}
break;
}
case 1: /* edge */
{
entry.trigger = 0;
break;
}
case 2: /* reserved */
{
printk("broken BIOS!!\n");
break;
}
case 3: /* level */
{
entry.trigger = 1;
break;
}
}
/*
* There are broken mptables which register ISA+high-active+level IRQs,
* these are illegal and are converted here to ISA+high-active+edge
......@@ -426,6 +482,8 @@ __initfunc(void setup_IO_APIC_irqs (void))
* type, it represents PCI IRQs 'embedded into an ISA bus', they have
* to be accepted. Yes, ugh.
*/
bus = mp_irqs[idx].mpc_srcbus;
if ( (mp_bus_id_to_type[bus] == MP_BUS_ISA) &&
(entry.polarity == 0) /* active-high */ &&
(entry.trigger == 1) /* level */ )
......
......@@ -70,9 +70,8 @@ spinlock_t irq_controller_lock;
/*
* Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
* boards the timer interrupt and sometimes the keyboard interrupt is
* not connected to any IO-APIC pin, it's fed to the CPU ExtInt IRQ line
* directly.
* boards the timer interrupt is not connected to any IO-APIC pin, it's
* fed to the CPU IRQ line directly.
*
* Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
* this 'mixed mode' IRQ handling costs us one more branch in do_IRQ,
......@@ -82,11 +81,8 @@ spinlock_t irq_controller_lock;
/*
* Default to all normal IRQ's _not_ using the IO APIC.
*
* To get IO-APIC interrupts you should either:
* - turn some of them into IO-APIC interrupts at runtime
* with some magic system call interface.
* - explicitly use irq 16-19 depending on which PCI irq
* line your PCI controller uses.
* To get IO-APIC interrupts we turn some of them into IO-APIC
* interrupts during boot.
*/
unsigned int io_apic_irqs = 0;
......@@ -109,15 +105,34 @@ static struct hw_interrupt_type i8259A_irq_type = {
#ifdef __SMP__
static void do_ioapic_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
static void enable_ioapic_irq (unsigned int irq);
static void disable_ioapic_irq (unsigned int irq);
static struct hw_interrupt_type ioapic_irq_type = {
do_ioapic_IRQ,
enable_ioapic_irq,
disable_ioapic_irq
/*
* Level and edge triggered IO-APIC interrupts need different handling,
* so we use two separate irq descriptors:
*/
static void do_edge_ioapic_IRQ (unsigned int irq, int cpu,
struct pt_regs * regs);
static void enable_edge_ioapic_irq (unsigned int irq);
static void disable_edge_ioapic_irq (unsigned int irq);
static struct hw_interrupt_type ioapic_edge_irq_type = {
do_edge_ioapic_IRQ,
enable_edge_ioapic_irq,
disable_edge_ioapic_irq
};
static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
struct pt_regs * regs);
static void enable_level_ioapic_irq (unsigned int irq);
static void disable_level_ioapic_irq (unsigned int irq);
static struct hw_interrupt_type ioapic_level_irq_type = {
do_level_ioapic_IRQ,
enable_level_ioapic_irq,
disable_level_ioapic_irq
};
#endif
/*
......@@ -147,7 +162,7 @@ typedef struct {
irq_desc_t irq_desc[NR_IRQS] = {
[0 ... 15] = { 0, 0, 0, &i8259A_irq_type, }, /* standard ISA IRQs */
#ifdef __SMP__
[16 ... 23] = { 0, 0, 0, &ioapic_irq_type, }, /* 'high' PCI IRQs */
[16 ... 23] = { 0, 0, 0, &ioapic_edge_irq_type, }, /* 'high' PCI IRQs */
#endif
};
......@@ -342,10 +357,14 @@ int get_irq_list(char *buf)
kstat.irqs[cpu_logical_map(j)][i]);
#endif
if (IO_APIC_IRQ(i))
p += sprintf(p, " IO-APIC ");
else
p += sprintf(p, " XT-PIC ");
if (IO_APIC_IRQ(i)) {
p += sprintf(p, " IO-APIC");
if (irq_desc[i].handler == &ioapic_level_irq_type)
p += sprintf(p, "-level ");
else
p += sprintf(p, "-edge ");
} else
p += sprintf(p, " XT-PIC ");
p += sprintf(p, " %s", action->name);
for (action=action->next; action; action = action->next) {
......@@ -732,47 +751,43 @@ static void do_8259A_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
* better to do it this way as thus we dont have to be aware of
* 'pending' interrupts in the IRQ path, except at this point.
*/
static void enable_ioapic_irq(unsigned int irq)
static inline void self_IPI (unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
#if 0
enable_IO_APIC_irq(irq);
#endif
if (desc->events && !desc->ipi) {
ack_APIC_irq();
desc->ipi = 1;
send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq));
}
}
/*
* We do not actually disable IO-APIC irqs in hardware ...
*/
static void disable_ioapic_irq(unsigned int irq)
static void enable_edge_ioapic_irq(unsigned int irq)
{
#if 0
disable_IO_APIC_irq(irq);
#endif
self_IPI(irq);
}
static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
static void disable_edge_ioapic_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
}
spin_lock(&irq_controller_lock);
static void enable_level_ioapic_irq(unsigned int irq)
{
enable_IO_APIC_irq(irq);
self_IPI(irq);
}
desc->ipi = 0;
static void disable_level_ioapic_irq(unsigned int irq)
{
disable_IO_APIC_irq(irq);
}
/*
* If the irq is disabled for whatever reason, just
* set a flag and return
*/
if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
desc->events = 1;
ack_APIC_irq();
spin_unlock(&irq_controller_lock);
return;
}
/*
* Has to be called with the irq controller locked
*/
static void handle_ioapic_event (unsigned int irq, int cpu,
struct pt_regs * regs)
{
irq_desc_t *desc = irq_desc + irq;
desc->status = IRQ_INPROGRESS;
desc->events = 0;
......@@ -799,7 +814,63 @@ static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
spin_unlock(&irq_controller_lock);
no_handler:
}
static void do_edge_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
{
irq_desc_t *desc = irq_desc + irq;
/*
* Edge triggered IRQs can be acked immediately
*/
ack_APIC_irq();
spin_lock(&irq_controller_lock);
desc->ipi = 0;
/*
* If the irq is disabled for whatever reason, just
* set a flag and return
*/
if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
desc->events = 1;
spin_unlock(&irq_controller_lock);
return;
}
handle_ioapic_event(irq,cpu,regs);
hardirq_exit(cpu);
release_irqlock(cpu);
}
static void do_level_ioapic_IRQ (unsigned int irq, int cpu,
struct pt_regs * regs)
{
irq_desc_t *desc = irq_desc + irq;
spin_lock(&irq_controller_lock);
/*
* in the level triggered case we first disable the IRQ
* in the IO-APIC, then we 'early ACK' the IRQ, then we
* handle it and enable the IRQ when finished.
*/
disable_IO_APIC_irq(irq);
ack_APIC_irq();
desc->ipi = 0;
/*
* If the irq is disabled for whatever reason, just
* set a flag and return
*/
if (desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
desc->events = 1;
spin_unlock(&irq_controller_lock);
return;
}
handle_ioapic_event(irq,cpu,regs);
hardirq_exit(cpu);
release_irqlock(cpu);
}
......@@ -922,7 +993,12 @@ int setup_x86_irq(unsigned int irq, struct irqaction * new)
spin_lock(&irq_controller_lock);
#ifdef __SMP__
if (IO_APIC_IRQ(irq)) {
irq_desc[irq].handler = &ioapic_irq_type;
if (IO_APIC_VECTOR(irq) > 0xfe)
/*
* break visibly for now, FIXME
*/
panic("ayiee, tell mingo");
/*
* First disable it in the 8259A:
*/
......@@ -1076,18 +1152,21 @@ void init_IO_APIC_traps(void)
* also, we've got to be careful not to trash gate
* 0x80, because int 0x80 is hm, kindof importantish ;)
*/
for (i = 0; i < NR_IRQS ; i++)
if (IO_APIC_VECTOR(i) <= 0xfe) /* HACK */ {
if (IO_APIC_IRQ(i)) {
irq_desc[i].handler = &ioapic_irq_type;
/*
* First disable it in the 8259A:
*/
cached_irq_mask |= 1 << i;
if (i < 16)
set_8259A_irq_mask(i);
}
for (i = 0; i < NR_IRQS ; i++) {
if ((IO_APIC_VECTOR(i) <= 0xfe) /* HACK */ &&
(IO_APIC_IRQ(i))) {
if (IO_APIC_irq_trigger(i))
irq_desc[i].handler = &ioapic_level_irq_type;
else
irq_desc[i].handler = &ioapic_edge_irq_type;
/*
* disable it in the 8259A:
*/
cached_irq_mask |= 1 << i;
if (i < 16)
set_8259A_irq_mask(i);
}
}
}
#endif
......
......@@ -17,6 +17,7 @@ void ack_APIC_irq (void);
void setup_IO_APIC (void);
void init_IO_APIC_traps(void);
int IO_APIC_get_PCI_irq_vector (int bus, int slot, int fn);
int IO_APIC_irq_trigger (int irq);
void make_8259A_irq (unsigned int irq);
void send_IPI (int dest, int vector);
void init_pic_mode (void);
......
......@@ -201,10 +201,14 @@
* now set ionly for CD-R and CD-RW drives. I had
* removed this support because it produced errors.
* It produced errors _only_ for non-writers. duh.
* 4.13 May 05, 1998 -- Suppress useless "in progress of becoming ready"
* messages, since this is not an error.
* -- Change error messages to be const
* -- Remove a "\t" which looks ugly in the syslogs
*
*************************************************************************/
#define IDECD_VERSION "4.12"
#define IDECD_VERSION "4.13"
#include <linux/module.h>
#include <linux/types.h>
......@@ -264,11 +268,13 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
return;
}
if (reqbuf->error_code == 0x70 && reqbuf->sense_key == 0x02
&& reqbuf->asc == 0x3a && reqbuf->ascq == 0x00)
&& ((reqbuf->asc == 0x3a && reqbuf->ascq == 0x00) ||
(reqbuf->asc == 0x04 && reqbuf->ascq == 0x01)))
{
/*
* No disc in drive ("Medium not present"),
* so keep the noise level down to a dull roar.
* Suppress the following errors:
* "Medium not present", and "in progress of becoming ready",
* to keep the noise level down to a dull roar.
*/
return;
}
......@@ -276,7 +282,7 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
#if VERBOSE_IDE_CD_ERRORS
{
int i;
char *s;
const char *s;
char buf[80];
printk ("ATAPI device %s:\n", drive->name);
......@@ -346,7 +352,7 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
lo = mid+1;
}
printk (" The failed \"%s\" packet command was: \n\t\"", s);
printk (" The failed \"%s\" packet command was: \n \"", s);
for (i=0; i<sizeof (failed_command->c); i++)
printk ("%02x ", failed_command->c[i]);
printk ("\"\n");
......@@ -1020,7 +1026,7 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
#define IDECD_SEEK_TIMER (2 * WAIT_MIN_SLEEP) /* 40 ms */
#define IDECD_SEEK_TIMEOUT (20 * IDECD_SEEK_TIMER) /* 0.8 sec */
#define IDECD_SEEK_TIMEOUT WAIT_CMD /* 10 sec */
static void cdrom_seek_intr (ide_drive_t *drive)
{
......
......@@ -415,7 +415,7 @@ struct cdrom_info {
/* From Table 124 of the ATAPI 1.2 spec.
Unchanged in Table 140 of the ATAPI 2.6 draft standard. */
char *sense_key_texts[16] = {
const char *sense_key_texts[16] = {
"No sense data",
"Recovered error",
"Not ready",
......@@ -438,7 +438,7 @@ char *sense_key_texts[16] = {
/* From Table 37 of the ATAPI 2.6 draft standard. */
struct {
unsigned short packet_command;
char *text;
const char *text;
} packet_command_texts[] = {
{ TEST_UNIT_READY, "Test Unit Ready" },
{ REQUEST_SENSE, "Request Sense" },
......@@ -473,7 +473,7 @@ struct {
struct {
unsigned short asc_ascq;
char *text;
const char *text;
} sense_data_texts[] = {
{ 0x0000, "No additional sense information" },
......
......@@ -70,7 +70,7 @@ static int irq_write_proc(struct file *file, const char *buffer,
if (oldirq == newirq)
goto out;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&pp->lock, flags);
if (pp->flags & PARPORT_FLAG_COMA)
goto out_ok;
......
......@@ -76,6 +76,9 @@ endif
ifeq ($(CONFIG_GUS),y)
L_OBJS += gus.o
ifeq ($(CONFIG_GUSMAX),y)
CONFIG_MSS = y
endif
else
ifeq ($(CONFIG_GUS),m)
M_OBJS += gus.o
......
......@@ -7,7 +7,6 @@
*
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/sysctl.h>
......
......@@ -54,7 +54,7 @@ static ssize_t pipe_read(struct file * filp, char * buf,
}
} else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
if (PIPE_EMPTY(*inode)) {
if (!PIPE_WRITERS(*inode))
if (!PIPE_WRITERS(*inode) || !count)
return 0;
}
if (signal_pending(current))
......
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