Commit 80d461c8 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.17 IDE 69

 - Apply small host chip driver cosmetics by Andrej xxx Panin
   and Vojtech Pavlik.

 - Remove support for "disc recovery time". It could only supposedly
   help with really simplistic broken devices from the past,
   which didn't have moderately sophisticated controllers.
   And finally Vojtech voted for it as well... so I just trust him.

 - Apply icside host chip driver and other ARM related updates by Russell King,
   which finally settle the "portability" work a bit, well hopefully.
parent c7c39840
...@@ -259,7 +259,7 @@ static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry ...@@ -259,7 +259,7 @@ static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry
{ {
for ( ; chipset_table->xfer_speed ; chipset_table++) for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) { if (chipset_table->xfer_speed == speed) {
return ((byte) ((system_bus_speed <= 33) ? chipset_table->chipset_settings_33 : chipset_table->chipset_settings_34)); return ((byte) ((system_bus_speed <= 33333) ? chipset_table->chipset_settings_33 : chipset_table->chipset_settings_34));
} }
return 0x00; return 0x00;
} }
...@@ -268,7 +268,7 @@ static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_ ...@@ -268,7 +268,7 @@ static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_
{ {
for ( ; chipset_table->xfer_speed ; chipset_table++) for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) { if (chipset_table->xfer_speed == speed) {
return ((byte) ((system_bus_speed <= 33) ? chipset_table->ultra_settings_33 : chipset_table->ultra_settings_34)); return ((byte) ((system_bus_speed <= 33333) ? chipset_table->ultra_settings_33 : chipset_table->ultra_settings_34));
} }
return 0x00; return 0x00;
} }
......
...@@ -124,8 +124,8 @@ static void ali14xx_tune_drive(struct ata_device *drive, u8 pio) ...@@ -124,8 +124,8 @@ static void ali14xx_tune_drive(struct ata_device *drive, u8 pio)
/* calculate timing, according to PIO mode */ /* calculate timing, according to PIO mode */
time1 = t->cycle; time1 = t->cycle;
time2 = t->active; time2 = t->active;
param3 = param1 = (time2 * system_bus_speed + 999) / 1000; param3 = param1 = (time2 * system_bus_speed + 999999) / 1000000;
param4 = param2 = (time1 * system_bus_speed + 999) / 1000 - param1; param4 = param2 = (time1 * system_bus_speed + 999999) / 1000000 - param1;
if (pio < XFER_PIO_3) { if (pio < XFER_PIO_3) {
param3 += 8; param3 += 8;
param4 += 8; param4 += 8;
......
...@@ -261,18 +261,18 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio) ...@@ -261,18 +261,18 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio)
s_time = t->setup; s_time = t->setup;
a_time = t->active; a_time = t->active;
if ((s_clc = (s_time * system_bus_speed + 999) / 1000) >= 8) if ((s_clc = (s_time * system_bus_speed + 999999) / 1000000) >= 8)
s_clc = 0; s_clc = 0;
if ((a_clc = (a_time * system_bus_speed + 999) / 1000) >= 8) if ((a_clc = (a_time * system_bus_speed + 999999) / 1000000) >= 8)
a_clc = 0; a_clc = 0;
c_time = t->cycle; c_time = t->cycle;
#if 0 #if 0
if ((r_clc = ((c_time - s_time - a_time) * system_bus_speed + 999) / 1000) >= 16) if ((r_clc = ((c_time - s_time - a_time) * system_bus_speed + 999999) / 1000000) >= 16)
r_clc = 0; r_clc = 0;
#endif #endif
if (!(r_clc = (c_time * system_bus_speed + 999) / 1000 - a_clc - s_clc)) { if (!(r_clc = (c_time * system_bus_speed + 999999) / 1000000 - a_clc - s_clc)) {
r_clc = 1; r_clc = 1;
} else { } else {
if (r_clc >= 16) if (r_clc >= 16)
......
...@@ -87,7 +87,6 @@ static struct amd_ide_chip { ...@@ -87,7 +87,6 @@ static struct amd_ide_chip {
static struct amd_ide_chip *amd_config; static struct amd_ide_chip *amd_config;
static unsigned char amd_enabled; static unsigned char amd_enabled;
static unsigned int amd_80w; static unsigned int amd_80w;
static unsigned int amd_clock;
static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 }; static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 };
static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 }; static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 };
...@@ -131,7 +130,7 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -131,7 +130,7 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]); amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]);
amd_print("BM-DMA base: %#x", amd_base); amd_print("BM-DMA base: %#x", amd_base);
amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10); amd_print("PCI clock: %d.%dMHz", system_bus_speed / 1000, system_bus_speed / 100 % 10);
amd_print("-----------------------Primary IDE-------Secondary IDE------"); amd_print("-----------------------Primary IDE-------Secondary IDE------");
...@@ -147,7 +146,7 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -147,7 +146,7 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
amd_print("Cable Type: %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w"); amd_print("Cable Type: %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w");
if (!amd_clock) if (!system_bus_speed)
return p - buffer; return p - buffer;
amd_print("-------------------drive0----drive1----drive2----drive3-----"); amd_print("-------------------drive0----drive1----drive2----drive3-----");
...@@ -169,22 +168,22 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -169,22 +168,22 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
if (den[i] && uen[i] && udma[i] == 1) { if (den[i] && uen[i] && udma[i] == 1) {
speed[i] = amd_clock * 3; speed[i] = system_bus_speed * 3;
cycle[i] = 666666 / amd_clock; cycle[i] = 666666 / system_bus_speed;
continue; continue;
} }
speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2); speed[i] = 4 * system_bus_speed / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2; cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / system_bus_speed / 2;
} }
amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / amd_clock); amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / system_bus_speed);
amd_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / amd_clock); amd_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / system_bus_speed);
amd_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / amd_clock); amd_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / system_bus_speed);
amd_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / amd_clock); amd_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / system_bus_speed);
amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / amd_clock); amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / system_bus_speed);
amd_print_drive("Cycle Time: ", "%8dns", cycle[i]); amd_print_drive("Cycle Time: ", "%8dns", cycle[i]);
amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
...@@ -238,7 +237,7 @@ static int amd_set_drive(ide_drive_t *drive, unsigned char speed) ...@@ -238,7 +237,7 @@ static int amd_set_drive(ide_drive_t *drive, unsigned char speed)
printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
drive->dn >> 1, drive->dn & 1); drive->dn >> 1, drive->dn & 1);
T = 1000000000 / amd_clock; T = 1000000000 / system_bus_speed;
UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2);
ata_timing_compute(drive, speed, &t, T, UT); ata_timing_compute(drive, speed, &t, T, UT);
...@@ -248,7 +247,7 @@ static int amd_set_drive(ide_drive_t *drive, unsigned char speed) ...@@ -248,7 +247,7 @@ static int amd_set_drive(ide_drive_t *drive, unsigned char speed)
ata_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); ata_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
} }
if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; if (speed == XFER_UDMA_5 && system_bus_speed <= 33333) t.udma = 1;
amd_set_speed(drive->channel->pci_dev, drive->dn, &t); amd_set_speed(drive->channel->pci_dev, drive->dn, &t);
...@@ -357,24 +356,6 @@ static unsigned int __init amd74xx_init_chipset(struct pci_dev *dev) ...@@ -357,24 +356,6 @@ static unsigned int __init amd74xx_init_chipset(struct pci_dev *dev)
pci_write_config_byte(dev, AMD_IDE_CONFIG, pci_write_config_byte(dev, AMD_IDE_CONFIG,
(amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0)); (amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0));
/*
* Determine the system bus clock.
*/
amd_clock = system_bus_speed * 1000;
switch (amd_clock) {
case 33000: amd_clock = 33333; break;
case 37000: amd_clock = 37500; break;
case 41000: amd_clock = 41666; break;
}
if (amd_clock < 20000 || amd_clock > 50000) {
printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock);
printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n");
amd_clock = 33333;
}
/* /*
* Print the boot message. * Print the boot message.
*/ */
......
...@@ -603,7 +603,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle ...@@ -603,7 +603,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
u8 cycle_count; u8 cycle_count;
recovery_time = cycle_time - (setup_time + active_time); recovery_time = cycle_time - (setup_time + active_time);
clock_time = 1000 / system_bus_speed; clock_time = 1000000 / system_bus_speed;
cycle_count = (cycle_time + clock_time - 1) / clock_time; cycle_count = (cycle_time + clock_time - 1) / clock_time;
setup_count = (setup_time + clock_time - 1) / clock_time; setup_count = (setup_time + clock_time - 1) / clock_time;
......
...@@ -305,7 +305,7 @@ static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted) ...@@ -305,7 +305,7 @@ static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
*/ */
recovery_time = t->cycle - (t->setup + t->active); recovery_time = t->cycle - (t->setup + t->active);
clock_time = 1000 / system_bus_speed; clock_time = 1000000 / system_bus_speed;
cycle_count = (t->cycle + clock_time - 1) / clock_time; cycle_count = (t->cycle + clock_time - 1) / clock_time;
setup_count = (t->setup + clock_time - 1) / clock_time; setup_count = (t->setup + clock_time - 1) / clock_time;
active_count = (t->active + clock_time - 1) / clock_time; active_count = (t->active + clock_time - 1) / clock_time;
......
...@@ -121,7 +121,7 @@ static int calc_clk (int time, int bus_speed) ...@@ -121,7 +121,7 @@ static int calc_clk (int time, int bus_speed)
{ {
int clocks; int clocks;
clocks = (time*bus_speed+999)/1000 -1; clocks = (time*bus_speed+999999)/1000000 -1;
if (clocks < 0) if (clocks < 0)
clocks = 0; clocks = 0;
......
...@@ -219,8 +219,8 @@ static byte ht_pio2timings(ide_drive_t *drive, byte pio) ...@@ -219,8 +219,8 @@ static byte ht_pio2timings(ide_drive_t *drive, byte pio)
/* /*
* Cycle times should be Vesa bus cycles * Cycle times should be Vesa bus cycles
*/ */
active_cycles = (active_time * system_bus_speed + 999) / 1000; active_cycles = (active_time * system_bus_speed + 999999) / 1000000;
recovery_cycles = (recovery_time * system_bus_speed + 999) / 1000; recovery_cycles = (recovery_time * system_bus_speed + 999999) / 1000000;
/* /*
* Upper and lower limits * Upper and lower limits
*/ */
......
/* /*
* linux/drivers/ide/icside.c * linux/drivers/ide/icside.c
* *
* Copyright (c) 1996,1997 Russell King. * Copyright (c) 1996-2002 Russell King.
* *
* Changelog: * Changelog:
* 08-Jun-1996 RMK Created * 08-Jun-1996 RMK Created
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/ecard.h> #include <asm/ecard.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/page.h>
extern char *ide_xfer_verbose (byte xfer_rate); extern char *ide_xfer_verbose (byte xfer_rate);
...@@ -75,6 +76,12 @@ static struct cardinfo icside_cardinfo_v6_2 = { ...@@ -75,6 +76,12 @@ static struct cardinfo icside_cardinfo_v6_2 = {
ICS_ARCIN_V6_IDESTEPPING ICS_ARCIN_V6_IDESTEPPING
}; };
struct icside_state {
unsigned int channel;
unsigned int enabled;
unsigned int irq_port;
};
static const card_ids icside_cids[] = { static const card_ids icside_cids[] = {
{ MANU_ICS, PROD_ICS_IDE }, { MANU_ICS, PROD_ICS_IDE },
{ MANU_ICS2, PROD_ICS2_IDE }, { MANU_ICS2, PROD_ICS2_IDE },
...@@ -122,10 +129,21 @@ static const expansioncard_ops_t icside_ops_arcin_v5 = { ...@@ -122,10 +129,21 @@ static const expansioncard_ops_t icside_ops_arcin_v5 = {
*/ */
static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
{ {
unsigned int ide_base_port = (unsigned int)ec->irq_data; struct icside_state *state = ec->irq_data;
unsigned int base = state->irq_port;
state->enabled = 1;
outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); switch (state->channel) {
outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2); case 0:
outb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
inb(base + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
outb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
inb(base + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
} }
/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
...@@ -133,10 +151,12 @@ static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) ...@@ -133,10 +151,12 @@ static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
*/ */
static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
{ {
unsigned int ide_base_port = (unsigned int)ec->irq_data; struct icside_state *state = ec->irq_data;
inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); state->enabled = 0;
inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
} }
/* Prototype: icside_irqprobe(struct expansion_card *ec) /* Prototype: icside_irqprobe(struct expansion_card *ec)
...@@ -144,10 +164,10 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) ...@@ -144,10 +164,10 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
*/ */
static int icside_irqpending_arcin_v6(struct expansion_card *ec) static int icside_irqpending_arcin_v6(struct expansion_card *ec)
{ {
unsigned int ide_base_port = (unsigned int)ec->irq_data; struct icside_state *state = ec->irq_data;
return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 || return inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1; inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
} }
static const expansioncard_ops_t icside_ops_arcin_v6 = { static const expansioncard_ops_t icside_ops_arcin_v6 = {
...@@ -210,6 +230,39 @@ static iftype_t __init icside_identifyif (struct expansion_card *ec) ...@@ -210,6 +230,39 @@ static iftype_t __init icside_identifyif (struct expansion_card *ec)
return iftype; return iftype;
} }
/*
* Handle routing of interrupts. This is called before
* we write the command to the drive.
*/
static void icside_maskproc(struct ata_device *drive, int mask)
{
struct ata_channel *ch = drive->channel;
struct icside_state *state = ch->hw.priv;
unsigned long flags;
local_irq_save(flags);
state->channel = ch->unit;
if (state->enabled && !mask) {
switch (ch->unit) {
case 0:
outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
break;
case 1:
outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
break;
}
} else {
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
}
local_irq_restore(flags);
}
#ifdef CONFIG_BLK_DEV_IDEDMA_ICS #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
/* /*
* SG-DMA support. * SG-DMA support.
...@@ -223,32 +276,42 @@ static iftype_t __init icside_identifyif (struct expansion_card *ec) ...@@ -223,32 +276,42 @@ static iftype_t __init icside_identifyif (struct expansion_card *ec)
#define NR_ENTRIES 256 #define NR_ENTRIES 256
#define TABLE_SIZE (NR_ENTRIES * 8) #define TABLE_SIZE (NR_ENTRIES * 8)
static int ide_build_sglist(struct ata_channel *hwif, struct request *rq) static int ide_build_sglist(struct ata_channel *ch, struct request *rq)
{ {
request_queue_t *q = &hwif->drives[DEVICE_NR(rq->rq_dev) & 1].queue; struct scatterlist *sg = ch->sg_table;
struct scatterlist *sg = hwif->sg_table; int nents;
int nents = blk_rq_map_sg(q, rq, sg);
if (rq->flags & REQ_DRIVE_ACB) {
struct ata_taskfile *args = rq->special;
if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
ch->sg_dma_direction = PCI_DMA_TODEVICE;
else
ch->sg_dma_direction = PCI_DMA_FROMDEVICE;
memset(sg, 0, sizeof(*sg));
sg->page = virt_to_page(rq->buffer);
sg->offset = ((unsigned long)rq->buffer) & ~PAGE_MASK;
sg->length = rq->nr_sectors * SECTOR_SIZE;
nents = 1;
} else {
nents = blk_rq_map_sg(rq->q, rq, sg);
if (rq->q && nents > rq->nr_phys_segments) if (rq->q && nents > rq->nr_phys_segments)
printk("icside: received %d segments, build %d\n", printk("icside: received %d segments, build %d\n",
rq->nr_phys_segments, nents); rq->nr_phys_segments, nents);
if (rq_data_dir(rq) == READ) if (rq_data_dir(rq) == READ)
hwif->sg_dma_direction = PCI_DMA_FROMDEVICE; ch->sg_dma_direction = PCI_DMA_FROMDEVICE;
else else
hwif->sg_dma_direction = PCI_DMA_TODEVICE; ch->sg_dma_direction = PCI_DMA_TODEVICE;
}
return pci_map_sg(NULL, sg, nents, hwif->sg_dma_direction);
}
static int return pci_map_sg(NULL, sg, nents, ch->sg_dma_direction);
icside_udma_new_table(struct ata_channel *ch, struct request *rq)
{
return ch->sg_nents = ide_build_sglist(ch, rq);
} }
/* Teardown mappings after DMA has completed. */ /* Teardown mappings after DMA has completed. */
static void icside_destroy_dmatable(ide_drive_t *drive) static void icside_destroy_dmatable(struct ata_device *drive)
{ {
struct scatterlist *sg = drive->channel->sg_table; struct scatterlist *sg = drive->channel->sg_table;
int nents = drive->channel->sg_nents; int nents = drive->channel->sg_nents;
...@@ -282,10 +345,9 @@ static void icside_destroy_dmatable(ide_drive_t *drive) ...@@ -282,10 +345,9 @@ static void icside_destroy_dmatable(ide_drive_t *drive)
* MW2 70 25 25 120 C * MW2 70 25 25 120 C
*/ */
static int static int
icside_config_if(ide_drive_t *drive, int xfer_mode) icside_config_if(struct ata_device *drive, int xfer_mode)
{ {
int func = ide_dma_off; int on = 0, cycle_time = 0, use_dma_info = 0;
int cycle_time = 0, use_dma_info = 0;
switch (xfer_mode) { switch (xfer_mode) {
case XFER_MW_DMA_2: cycle_time = 250; use_dma_info = 1; break; case XFER_MW_DMA_2: cycle_time = 250; use_dma_info = 1; break;
...@@ -306,7 +368,7 @@ icside_config_if(ide_drive_t *drive, int xfer_mode) ...@@ -306,7 +368,7 @@ icside_config_if(ide_drive_t *drive, int xfer_mode)
drive->init_speed = xfer_mode; drive->init_speed = xfer_mode;
if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0) if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0)
func = ide_dma_on; on = 1;
else else
drive->drive_data = 480; drive->drive_data = 480;
...@@ -315,50 +377,45 @@ icside_config_if(ide_drive_t *drive, int xfer_mode) ...@@ -315,50 +377,45 @@ icside_config_if(ide_drive_t *drive, int xfer_mode)
drive->current_speed = xfer_mode; drive->current_speed = xfer_mode;
return func; return on;
} }
static int static int icside_set_speed(struct ata_device *drive, byte speed)
icside_set_speed(ide_drive_t *drive, byte speed)
{ {
return icside_config_if(drive, speed); return icside_config_if(drive, speed);
} }
/* static void icside_dma_enable(struct ata_device *drive, int on, int verbose)
* dma_intr() is the handler for disk read/write DMA interrupts
*/
static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *rq)
{ {
int i; if (!on) {
byte stat, dma_stat; if (verbose)
printk("%s: DMA disabled\n", drive->name);
dma_stat = drive->channel->udma(ide_dma_end, drive, rq); #ifdef CONFIG_BLK_DEV_IDE_TCQ
stat = GET_STAT(); /* get drive status */ udma_tcq_enable(drive, 0);
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { #endif
if (!dma_stat) {
for (i = rq->nr_sectors; i > 0;) {
i -= rq->current_nr_sectors;
ide_end_request(drive, 1);
}
return ide_stopped;
}
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
} }
return ide_error(drive, "dma_intr", stat);
}
/*
* We don't need any bouncing. Yes, this looks the
* wrong way around, but it is correct.
*/
blk_queue_bounce_limit(&drive->queue, BLK_BOUNCE_ANY);
drive->using_dma = on;
#ifdef CONFIG_CLK_DEV_IDE_TCQ_DEFAULT
if (on)
udma_tcq_enable(drive, 1);
#endif
}
static int static int icside_dma_check(struct ata_device *drive)
icside_dma_check(struct ata_device *drive, struct request *rq)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel; struct ata_channel *ch = drive->channel;
int autodma = hwif->autodma;
int xfer_mode = XFER_PIO_2; int xfer_mode = XFER_PIO_2;
int func = ide_dma_off_quietly; int on;
if (!id || !(id->capability & 1) || !autodma) if (!id || !(id->capability & 1) || !ch->autodma)
goto out; goto out;
/* /*
...@@ -367,188 +424,284 @@ icside_dma_check(struct ata_device *drive, struct request *rq) ...@@ -367,188 +424,284 @@ icside_dma_check(struct ata_device *drive, struct request *rq)
if (id->field_valid & 2) { if (id->field_valid & 2) {
if (id->dma_mword & 4) { if (id->dma_mword & 4) {
xfer_mode = XFER_MW_DMA_2; xfer_mode = XFER_MW_DMA_2;
func = ide_dma_on;
} else if (id->dma_mword & 2) { } else if (id->dma_mword & 2) {
xfer_mode = XFER_MW_DMA_1; xfer_mode = XFER_MW_DMA_1;
func = ide_dma_on;
} else if (id->dma_mword & 1) { } else if (id->dma_mword & 1) {
xfer_mode = XFER_MW_DMA_0; xfer_mode = XFER_MW_DMA_0;
func = ide_dma_on;
} }
goto out;
} }
out: out:
func = icside_config_if(drive, xfer_mode); on = icside_config_if(drive, xfer_mode);
icside_dma_enable(drive, on, 0);
return hwif->udma(func, drive, rq); return 0;
} }
static int static int icside_dma_stop(struct ata_device *drive)
icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{ {
struct ata_channel *hwif = drive->channel; struct ata_channel *ch = drive->channel;
int count, reading = 0;
switch (func) { drive->waiting_for_dma = 0;
case ide_dma_off: disable_dma(ch->hw.dma);
printk("%s: DMA disabled\n", drive->name); icside_destroy_dmatable(drive);
/*FALLTHROUGH*/
return get_dma_residue(ch->hw.dma) != 0;
}
static int icside_dma_start(struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
case ide_dma_off_quietly:
case ide_dma_on:
/* /*
* We don't need any bouncing. Yes, this looks the * We can not enable DMA on both channels.
* wrong way around, but it is correct.
*/ */
blk_queue_bounce_limit(&drive->queue, BLK_BOUNCE_ANY); BUG_ON(dma_channel_active(ch->hw.dma));
drive->using_dma = (func == ide_dma_on);
enable_dma(ch->hw.dma);
return 0; return 0;
}
/*
* dma_intr() is the handler for disk read/write DMA interrupts
*/
static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *rq)
{
int dma_stat;
byte stat;
dma_stat = icside_dma_stop(drive);
stat = GET_STAT(); /* get drive status */
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
__ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped;
}
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
}
return ide_error(drive, rq, "dma_intr", stat);
}
case ide_dma_check: static int
return icside_dma_check(drive, rq); icside_dma_common(struct ata_device *drive, struct request *rq,
unsigned int dma_mode)
{
struct ata_channel *ch = drive->channel;
unsigned int count;
case ide_dma_read: /*
reading = 1; * We can not enable DMA on both channels.
case ide_dma_write: */
count = icside_udma_new_table(hwif, rq); BUG_ON(dma_channel_active(ch->hw.dma));
count = ch->sg_nents = ide_build_sglist(ch, rq);
if (!count) if (!count)
return 1; return 1;
disable_dma(hwif->hw.dma);
/* Route the DMA signals to /*
* to the correct interface. * Route the DMA signals to to this channel.
*/ */
outb(hwif->select_data, hwif->config_data); outb(ch->select_data, ch->config_data);
/* Select the correct timing /*
* for this drive * Select the correct timing for this drive.
*/ */
set_dma_speed(hwif->hw.dma, drive->drive_data); set_dma_speed(ch->hw.dma, drive->drive_data);
set_dma_sg(hwif->hw.dma, drive->channel->sg_table, count); /*
set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ * Tell the DMA engine about the SG table and
: DMA_MODE_WRITE); * data direction.
*/
set_dma_sg(ch->hw.dma, ch->sg_table, count);
set_dma_mode(ch->hw.dma, dma_mode);
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
return 0;
}
static int icside_dma_read(struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
unsigned int cmd;
if (icside_dma_common(drive, rq, DMA_MODE_READ))
return 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL); ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
IDE_COMMAND_REG);
case ide_dma_begin: if ((rq->flags & REQ_DRIVE_ACB) && drive->addressing == 1) {
enable_dma(hwif->hw.dma); struct ata_taskfile *args = rq->special;
cmd = args->taskfile.command;
} else if (drive->addressing) {
cmd = WIN_READDMA_EXT;
} else {
cmd = WIN_READDMA;
}
OUT_BYTE(cmd, IDE_COMMAND_REG);
enable_dma(ch->hw.dma);
return 0; return 0;
}
case ide_dma_end: static int icside_dma_write(struct ata_device *drive, struct request *rq)
drive->waiting_for_dma = 0; {
disable_dma(hwif->hw.dma); struct ata_channel *ch = drive->channel;
icside_destroy_dmatable(drive); unsigned int cmd;
return get_dma_residue(hwif->hw.dma) != 0;
case ide_dma_test_irq: if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
return inb((unsigned long)hwif->hw.priv) & 1; return 1;
case ide_dma_timeout: if (drive->type != ATA_DISK)
default: return 0;
printk("icside_dmaproc: unsupported function: %d\n", func);
ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
if ((rq->flags & REQ_DRIVE_ACB) && drive->addressing == 1) {
struct ata_taskfile *args = rq->special;
cmd = args->taskfile.command;
} else if (drive->addressing) {
cmd = WIN_WRITEDMA_EXT;
} else {
cmd = WIN_WRITEDMA;
} }
return 1; OUT_BYTE(cmd, IDE_COMMAND_REG);
enable_dma(ch->hw.dma);
return 0;
} }
static int static int icside_irq_status(struct ata_device *drive)
icside_setup_dma(struct ata_channel *hwif, int autodma) {
struct ata_channel *ch = drive->channel;
struct icside_state *state = ch->hw.priv;
return inb(state->irq_port +
(ch->unit ?
ICS_ARCIN_V6_INTRSTAT_2 :
ICS_ARCIN_V6_INTRSTAT_1)) & 1;
}
static void icside_dma_timeout(struct ata_device *drive)
{
printk(KERN_ERR "ATA: %s: UDMA timeout occured:", drive->name);
ide_dump_status(drive, NULL, "UDMA timeout", GET_STAT());
}
static void icside_irq_lost(struct ata_device *drive)
{
printk(KERN_ERR "ATA: %s: IRQ lost\n", drive->name);
}
static int icside_setup_dma(struct ata_channel *ch)
{ {
printk(" %s: SG-DMA", hwif->name); int autodma = 0;
#ifdef CONFIG_IDEDMA_ICS_AUTO
autodma = 1;
#endif
printk(" %s: SG-DMA", ch->name);
hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES, ch->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES,
GFP_KERNEL); GFP_KERNEL);
if (!hwif->sg_table) if (!ch->sg_table)
goto failed; goto failed;
hwif->dmatable_cpu = NULL; ch->dmatable_cpu = NULL;
hwif->dmatable_dma = 0; ch->dmatable_dma = 0;
hwif->speedproc = icside_set_speed; ch->speedproc = icside_set_speed;
hwif->dmaproc = icside_dmaproc; ch->XXX_udma = icside_dma_check;
hwif->autodma = autodma; ch->udma_enable = icside_dma_enable;
ch->udma_start = icside_dma_start;
printk(" capable%s\n", autodma ? ch->udma_stop = icside_dma_stop;
", auto-enable" : ""); ch->udma_read = icside_dma_read;
ch->udma_write = icside_dma_write;
ch->udma_irq_status = icside_irq_status;
ch->udma_timeout = icside_dma_timeout;
ch->udma_irq_lost = icside_irq_lost;
ch->autodma = autodma;
printk(" capable%s\n", autodma ? ", auto-enable" : "");
return 1; return 1;
failed: failed:
printk(" -- ERROR, unable to allocate DMA table\n"); printk(" disabled, unable to allocate DMA table\n");
return 0; return 0;
} }
void ide_release_dma(struct ata_channel *hwif) void ide_release_dma(struct ata_channel *ch)
{ {
if (hwif->sg_table) { if (ch->sg_table) {
kfree(hwif->sg_table); kfree(ch->sg_table);
hwif->sg_table = NULL; ch->sg_table = NULL;
} }
} }
#endif #endif
static struct ata_channel * static struct ata_channel *icside_find_hwif(unsigned long dataport)
icside_find_hwif(unsigned long dataport)
{ {
struct ata_channel *hwif; struct ata_channel *ch;
int index; int index;
for (index = 0; index < MAX_HWIFS; ++index) { for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index]; ch = &ide_hwifs[index];
if (hwif->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport) if (ch->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport)
goto found; goto found;
} }
for (index = 0; index < MAX_HWIFS; ++index) { for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index]; ch = &ide_hwifs[index];
if (!hwif->io_ports[IDE_DATA_OFFSET]) if (!ch->io_ports[IDE_DATA_OFFSET])
goto found; goto found;
} }
return NULL; return NULL;
found: found:
return hwif; return ch;
} }
static struct ata_channel * static struct ata_channel *
icside_setup(unsigned long base, struct cardinfo *info, int irq) icside_setup(unsigned long base, struct cardinfo *info, int irq)
{ {
unsigned long port = base + info->dataoffset; unsigned long port = base + info->dataoffset;
struct ata_channel *hwif; struct ata_channel *ch;
hwif = icside_find_hwif(base); ch = icside_find_hwif(base);
if (hwif) { if (ch) {
int i; int i;
memset(&hwif->hw, 0, sizeof(hw_regs_t)); memset(&ch->hw, 0, sizeof(hw_regs_t));
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hwif->hw.io_ports[i] = (ide_ioreg_t)port; ch->hw.io_ports[i] = (ide_ioreg_t)port;
hwif->io_ports[i] = (ide_ioreg_t)port; ch->io_ports[i] = (ide_ioreg_t)port;
port += 1 << info->stepping; port += 1 << info->stepping;
} }
hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; ch->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
hwif->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; ch->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
hwif->hw.irq = irq; ch->hw.irq = irq;
hwif->irq = irq; ch->irq = irq;
hwif->hw.dma = NO_DMA; ch->hw.dma = NO_DMA;
hwif->noprobe = 0; ch->noprobe = 0;
hwif->chipset = ide_acorn; ch->chipset = ide_acorn;
} }
return hwif; return ch;
} }
static int __init icside_register_v5(struct expansion_card *ec, int autodma) static int __init icside_register_v5(struct expansion_card *ec)
{ {
unsigned long slot_port; unsigned long slot_port;
struct ata_channel *hwif; struct ata_channel *ch;
slot_port = ecard_address(ec, ECARD_MEMC, 0); slot_port = ecard_address(ec, ECARD_MEMC, 0);
...@@ -562,17 +715,17 @@ static int __init icside_register_v5(struct expansion_card *ec, int autodma) ...@@ -562,17 +715,17 @@ static int __init icside_register_v5(struct expansion_card *ec, int autodma)
*/ */
inb(slot_port + ICS_ARCIN_V5_INTROFFSET); inb(slot_port + ICS_ARCIN_V5_INTROFFSET);
hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq); ch = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq);
return hwif ? 0 : -1; return ch ? 0 : -1;
} }
static int __init icside_register_v6(struct expansion_card *ec, int autodma) static int __init icside_register_v6(struct expansion_card *ec)
{ {
unsigned long slot_port, port; unsigned long slot_port, port;
struct ata_channel *hwif; struct icside_state *state;
struct ata_channel *mate; struct ata_channel *ch0, *ch1;
int sel = 0; unsigned int sel = 0;
slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST); slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
port = ecard_address(ec, ECARD_EASI, ECARD_FAST); port = ecard_address(ec, ECARD_EASI, ECARD_FAST);
...@@ -584,55 +737,57 @@ static int __init icside_register_v6(struct expansion_card *ec, int autodma) ...@@ -584,55 +737,57 @@ static int __init icside_register_v6(struct expansion_card *ec, int autodma)
outb(sel, slot_port); outb(sel, slot_port);
ec->irq_data = (void *)port;
ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
/* /*
* Be on the safe side - disable interrupts * Be on the safe side - disable interrupts
*/ */
inb(port + ICS_ARCIN_V6_INTROFFSET_1); inb(port + ICS_ARCIN_V6_INTROFFSET_1);
inb(port + ICS_ARCIN_V6_INTROFFSET_2); inb(port + ICS_ARCIN_V6_INTROFFSET_2);
hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq); /*
mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq); * Find and register the interfaces.
*/
ch0 = icside_setup(port, &icside_cardinfo_v6_1, ec->irq);
ch1 = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);
if (!ch0 || !ch1)
return -ENODEV;
state = kmalloc(sizeof(struct icside_state), GFP_KERNEL);
if (!state)
return -ENOMEM;
state->channel = 0;
state->enabled = 0;
state->irq_port = port;
ec->irq_data = state;
ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
ch0->maskproc = icside_maskproc;
ch0->unit = 0;
ch0->hw.priv = state;
ch0->config_data = slot_port;
ch0->select_data = sel;
ch0->hw.dma = ec->dma;
ch1->maskproc = icside_maskproc;
ch1->unit = 1;
ch1->hw.priv = state;
ch1->config_data = slot_port;
ch1->select_data = sel | 1;
ch1->hw.dma = ec->dma;
#ifdef CONFIG_BLK_DEV_IDEDMA_ICS #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
if (ec->dma != NO_DMA) { if (ec->dma != NO_DMA && !request_dma(ec->dma, ch0->name)) {
if (request_dma(ec->dma, hwif->name)) icside_setup_dma(ch0);
goto no_dma; icside_setup_dma(ch1);
if (hwif) {
hwif->config_data = slot_port;
hwif->select_data = sel;
hwif->hw.dma = ec->dma;
hwif->hw.priv = (void *)
(port + ICS_ARCIN_V6_INTRSTAT_1);
hwif->unit = 0;
icside_setup_dma(hwif, autodma);
}
if (mate) {
mate->config_data = slot_port;
mate->select_data = sel | 1;
mate->hw.dma = ec->dma;
mate->hw.priv = (void *)
(port + ICS_ARCIN_V6_INTRSTAT_2);
mate->unit = 1;
icside_setup_dma(mate, autodma);
}
} }
no_dma:
#endif #endif
return hwif || mate ? 0 : -1; return 0;
} }
int __init icside_init(void) int __init icside_init(void)
{ {
int autodma = 0;
#ifdef CONFIG_IDEDMA_ICS_AUTO
autodma = 1;
#endif
ecard_startfind (); ecard_startfind ();
do { do {
...@@ -647,11 +802,11 @@ int __init icside_init(void) ...@@ -647,11 +802,11 @@ int __init icside_init(void)
switch (icside_identifyif(ec)) { switch (icside_identifyif(ec)) {
case ics_if_arcin_v5: case ics_if_arcin_v5:
result = icside_register_v5(ec, autodma); result = icside_register_v5(ec);
break; break;
case ics_if_arcin_v6: case ics_if_arcin_v6:
result = icside_register_v6(ec, autodma); result = icside_register_v6(ec);
break; break;
default: default:
......
...@@ -139,34 +139,6 @@ int noautodma = 0; ...@@ -139,34 +139,6 @@ int noautodma = 0;
*/ */
struct ata_channel ide_hwifs[MAX_HWIFS]; /* master data repository */ struct ata_channel ide_hwifs[MAX_HWIFS]; /* master data repository */
#if (DISK_RECOVERY_TIME > 0)
/*
* For really screwed hardware (hey, at least it *can* be used with Linux)
* we can enforce a minimum delay time between successive operations.
*/
static unsigned long read_timer (void)
{
unsigned long t, flags;
int i;
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
t = jiffies * 11932;
outb_p(0, 0x43);
i = inb_p(0x40);
i |= inb(0x40) << 8;
__restore_flags(flags); /* local CPU only */
return (t - i);
}
#endif
static inline void set_recovery_timer(struct ata_channel *channel)
{
#if (DISK_RECOVERY_TIME > 0)
channel->last_time = read_timer();
#endif
}
static void init_hwif_data(struct ata_channel *ch, unsigned int index) static void init_hwif_data(struct ata_channel *ch, unsigned int index)
{ {
static const byte ide_major[] = { static const byte ide_major[] = {
...@@ -241,8 +213,6 @@ static void __init init_ide_data (void) ...@@ -241,8 +213,6 @@ static void __init init_ide_data (void)
/* Add default hw interfaces */ /* Add default hw interfaces */
ide_init_default_hwifs(); ide_init_default_hwifs();
idebus_parameter = 0;
} }
/* /*
...@@ -667,6 +637,50 @@ void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 stat, u8 ...@@ -667,6 +637,50 @@ void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 stat, u8
end_that_request_last(rq); end_that_request_last(rq);
} }
#if FANCY_STATUS_DUMPS
struct ata_bit_messages {
u8 mask;
u8 match;
const char *msg;
};
static struct ata_bit_messages ata_status_msgs[] = {
{ BUSY_STAT, BUSY_STAT, "Busy" },
{ READY_STAT, READY_STAT, "DriveReady" },
{ WRERR_STAT, WRERR_STAT, "DeviceFault" },
{ SEEK_STAT, SEEK_STAT, "SeekComplete" },
{ DRQ_STAT, DRQ_STAT, "DataRequest" },
{ ECC_STAT, ECC_STAT, "CorrectedError" },
{ INDEX_STAT, INDEX_STAT, "Index" },
{ ERR_STAT, ERR_STAT, "Error" }
};
static struct ata_bit_messages ata_error_msgs[] = {
{ ICRC_ERR|ABRT_ERR, ABRT_ERR, "DriveStatusError" },
{ ICRC_ERR|ABRT_ERR, ICRC_ERR, "BadSector" },
{ ICRC_ERR|ABRT_ERR, ICRC_ERR|ABRT_ERR, "BadCRC" },
{ ECC_ERR, ECC_ERR, "UncorrectableError" },
{ ID_ERR, ID_ERR, "SectorIdNotFound" },
{ TRK0_ERR, TRK0_ERR, "TrackZeroNotFound" },
{ MARK_ERR, MARK_ERR, "AddrMarkNotFound" }
};
static void ata_dump_bits(struct ata_bit_messages *msgs, int nr, byte bits)
{
int i;
printk(" { ");
for (i = 0; i < nr; i++, msgs++)
if ((bits & msgs->mask) == msgs->match)
printk("%s ", msgs->msg);
printk("} ");
}
#else
#define ata_dump_bits(msgs,nr,bits) do { } while (0)
#endif
/* /*
* Error reporting, in human readable form (luxurious, but a memory hog). * Error reporting, in human readable form (luxurious, but a memory hog).
*/ */
...@@ -674,49 +688,22 @@ u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *ms ...@@ -674,49 +688,22 @@ u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *ms
{ {
unsigned long flags; unsigned long flags;
byte err = 0; byte err = 0;
int i;
__save_flags (flags); /* local CPU only */ __save_flags (flags); /* local CPU only */
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
#if !(FANCY_STATUS_DUMPS)
printk("%s: %s: status=0x%02x\n", drive->name, msg, stat); printk("%s: %s: status=0x%02x", drive->name, msg, stat);
#else ata_dump_bits(ata_status_msgs, ARRAY_SIZE(ata_status_msgs), stat);
printk(" { "); printk("\n");
{
char *msg = "";
if (stat & BUSY_STAT)
msg = "Busy";
else {
if (stat & READY_STAT)
msg = "DriveReady";
if (stat & WRERR_STAT)
msg = "DeviceFault";
if (stat & SEEK_STAT)
msg = "SeekComplete";
if (stat & DRQ_STAT)
msg = "DataRequest";
if (stat & ECC_STAT)
msg = "CorrectedError";
if (stat & INDEX_STAT)
msg = "Index";
if (stat & ERR_STAT)
msg = "Error";
}
}
printk("%s }\n", msg);
#endif
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = GET_ERR(); err = GET_ERR();
printk("%s: %s: error=0x%02x", drive->name, msg, err); printk("%s: %s: error=0x%02x", drive->name, msg, err);
#if FANCY_STATUS_DUMPS #if FANCY_STATUS_DUMPS
if (drive->type == ATA_DISK) { if (drive->type == ATA_DISK) {
printk(" { "); ata_dump_bits(ata_error_msgs, ARRAY_SIZE(ata_error_msgs), err);
if (err & ABRT_ERR) printk("DriveStatusError ");
if (err & ICRC_ERR) printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector ");
if (err & ECC_ERR) printk("UncorrectableError ");
if (err & ID_ERR) printk("SectorIdNotFound ");
if (err & TRK0_ERR) printk("TrackZeroNotFound ");
if (err & MARK_ERR) printk("AddrMarkNotFound ");
printk("}");
if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) { if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
if ((drive->id->command_set_2 & 0x0400) && if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) && (drive->id->cfs_enable_2 & 0x0400) &&
...@@ -988,11 +975,6 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r ...@@ -988,11 +975,6 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
*/ */
if (block == 0 && drive->remap_0_to_1 == 1) if (block == 0 && drive->remap_0_to_1 == 1)
block = 1; /* redirect MBR access to EZ-Drive partn table */ block = 1; /* redirect MBR access to EZ-Drive partn table */
#if (DISK_RECOVERY_TIME > 0)
while ((read_timer() - ch->last_time) < DISK_RECOVERY_TIME);
#endif
{ {
ide_startstop_t res; ide_startstop_t res;
...@@ -1464,7 +1446,6 @@ void ide_timer_expiry(unsigned long data) ...@@ -1464,7 +1446,6 @@ void ide_timer_expiry(unsigned long data)
} else } else
startstop = ide_error(drive, drive->rq, "irq timeout", GET_STAT()); startstop = ide_error(drive, drive->rq, "irq timeout", GET_STAT());
} }
set_recovery_timer(ch);
enable_irq(ch->irq); enable_irq(ch->irq);
spin_lock_irq(ch->lock); spin_lock_irq(ch->lock);
...@@ -1614,7 +1595,6 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs) ...@@ -1614,7 +1595,6 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
* same irq as is currently being serviced here, and Linux * same irq as is currently being serviced here, and Linux
* won't allow another of the same (on any CPU) until we return. * won't allow another of the same (on any CPU) until we return.
*/ */
set_recovery_timer(drive->channel);
if (startstop == ide_stopped) { if (startstop == ide_stopped) {
if (!ch->handler) { /* paranoia */ if (!ch->handler) { /* paranoia */
clear_bit(IDE_BUSY, ch->active); clear_bit(IDE_BUSY, ch->active);
...@@ -2787,10 +2767,7 @@ int __init ide_setup (char *s) ...@@ -2787,10 +2767,7 @@ int __init ide_setup (char *s)
if (!strncmp(s, "idebus", 6)) { if (!strncmp(s, "idebus", 6)) {
if (match_parm(&s[6], NULL, vals, 1) != 1) if (match_parm(&s[6], NULL, vals, 1) != 1)
goto bad_option; goto bad_option;
if (vals[0] >= 20 && vals[0] <= 66) {
idebus_parameter = vals[0]; idebus_parameter = vals[0];
} else
printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
goto done; goto done;
} }
...@@ -3219,27 +3196,40 @@ static int __init ata_module_init(void) ...@@ -3219,27 +3196,40 @@ static int __init ata_module_init(void)
ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL); ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL);
/* Initialize system bus speed. /*
* * Because most of the ATA adapters represent the timings in unit of bus
* This can be changed by a particular chipse initialization module. * clocks, and there is no known reliable way to detect the bus clock
* Otherwise we assume 33MHz as a safe value for PCI bus based systems. * frequency, we assume 50 MHz for non-PCI (VLB, EISA) and 33 MHz for PCI based
* 50MHz will be assumed for abolitions like VESA, since higher values * systems. Since assuming only hurts performance and not stability, this is
* result in more conservative timing setups. * OK. The user can change this on the command line by using the "idebus=XX"
* * parameter. While the system_bus_speed variable is in kHz units, we accept
* The kernel parameter idebus=XX overrides the default settings. * both MHz and kHz entry on the command line for backward compatibility.
*/ */
system_bus_speed = 50; system_bus_speed = 50000;
if (idebus_parameter)
if (pci_present())
system_bus_speed = 33333;
if (idebus_parameter >= 20 && idebus_parameter <= 80) {
system_bus_speed = idebus_parameter * 1000;
switch (system_bus_speed) {
case 33000: system_bus_speed = 33333; break;
case 37000: system_bus_speed = 37500; break;
case 41000: system_bus_speed = 41666; break;
case 66000: system_bus_speed = 66666; break;
}
}
if (idebus_parameter >= 20000 && idebus_parameter <= 80000)
system_bus_speed = idebus_parameter; system_bus_speed = idebus_parameter;
#ifdef CONFIG_PCI
else if (pci_present())
system_bus_speed = 33;
#endif
printk(KERN_INFO "ATA: system bus speed %dMHz\n", system_bus_speed); printk(KERN_INFO "ATA: %s bus speed %d.%dMHz\n",
pci_present() ? "PCI" : "System", system_bus_speed / 1000, system_bus_speed / 100 % 10);
init_ide_data (); init_ide_data();
initializing = 1; initializing = 1;
......
...@@ -175,7 +175,7 @@ static int cmpt_clk(int time, int bus_speed) ...@@ -175,7 +175,7 @@ static int cmpt_clk(int time, int bus_speed)
* Use idebus=xx to select right frequency. * Use idebus=xx to select right frequency.
*/ */
{ {
return ((time*bus_speed+999)/1000); return ((time*bus_speed+999999)/1000000);
} }
static void write_reg(byte value, int reg) static void write_reg(byte value, int reg)
......
...@@ -258,7 +258,7 @@ void ide_release_dma(struct ata_channel *ch) ...@@ -258,7 +258,7 @@ void ide_release_dma(struct ata_channel *ch)
* recovery" in the ATAPI drivers. This was just plain wrong before, in esp. * recovery" in the ATAPI drivers. This was just plain wrong before, in esp.
* not portable, and just got uncovered now. * not portable, and just got uncovered now.
*/ */
static void udma_pci_enable(struct ata_device *drive, int on, int verbose) void udma_pci_enable(struct ata_device *drive, int on, int verbose)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
int set_high = 1; int set_high = 1;
...@@ -396,7 +396,7 @@ void udma_destroy_table(struct ata_channel *ch) ...@@ -396,7 +396,7 @@ void udma_destroy_table(struct ata_channel *ch)
* about addressing modes. * about addressing modes.
*/ */
static int udma_pci_start(struct ata_device *drive, struct request *rq) int udma_pci_start(struct ata_device *drive, struct request *rq)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
...@@ -410,7 +410,7 @@ static int udma_pci_start(struct ata_device *drive, struct request *rq) ...@@ -410,7 +410,7 @@ static int udma_pci_start(struct ata_device *drive, struct request *rq)
return 0; return 0;
} }
static int udma_pci_stop(struct ata_device *drive) int udma_pci_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
...@@ -425,12 +425,12 @@ static int udma_pci_stop(struct ata_device *drive) ...@@ -425,12 +425,12 @@ static int udma_pci_stop(struct ata_device *drive)
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */ return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
} }
static int udma_pci_read(struct ata_device *drive, struct request *rq) int udma_pci_read(struct ata_device *drive, struct request *rq)
{ {
return ata_do_udma(1, drive, rq); return ata_do_udma(1, drive, rq);
} }
static int udma_pci_write(struct ata_device *drive, struct request *rq) int udma_pci_write(struct ata_device *drive, struct request *rq)
{ {
return ata_do_udma(0, drive, rq); return ata_do_udma(0, drive, rq);
} }
...@@ -438,7 +438,7 @@ static int udma_pci_write(struct ata_device *drive, struct request *rq) ...@@ -438,7 +438,7 @@ static int udma_pci_write(struct ata_device *drive, struct request *rq)
/* /*
* FIXME: This should be attached to a channel as we can see now! * FIXME: This should be attached to a channel as we can see now!
*/ */
static int udma_pci_irq_status(struct ata_device *drive) int udma_pci_irq_status(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
u8 dma_stat; u8 dma_stat;
...@@ -449,12 +449,12 @@ static int udma_pci_irq_status(struct ata_device *drive) ...@@ -449,12 +449,12 @@ static int udma_pci_irq_status(struct ata_device *drive)
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
} }
static void udma_pci_timeout(struct ata_device *drive) void udma_pci_timeout(struct ata_device *drive)
{ {
printk(KERN_ERR "ATA: UDMA timeout occured %s!\n", drive->name); printk(KERN_ERR "ATA: UDMA timeout occured %s!\n", drive->name);
} }
static void udma_pci_irq_lost(struct ata_device *drive) void udma_pci_irq_lost(struct ata_device *drive)
{ {
} }
...@@ -553,3 +553,11 @@ int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request * ...@@ -553,3 +553,11 @@ int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *
EXPORT_SYMBOL(ata_do_udma); EXPORT_SYMBOL(ata_do_udma);
EXPORT_SYMBOL(ide_dma_intr); EXPORT_SYMBOL(ide_dma_intr);
EXPORT_SYMBOL(udma_pci_enable);
EXPORT_SYMBOL(udma_pci_start);
EXPORT_SYMBOL(udma_pci_stop);
EXPORT_SYMBOL(udma_pci_read);
EXPORT_SYMBOL(udma_pci_write);
EXPORT_SYMBOL(udma_pci_irq_status);
EXPORT_SYMBOL(udma_pci_timeout);
EXPORT_SYMBOL(udma_pci_irq_lost);
...@@ -166,10 +166,12 @@ static void decode_registers (byte registers, byte value) ...@@ -166,10 +166,12 @@ static void decode_registers (byte registers, byte value)
#endif /* PDC202XX_DECODE_REGISTER_INFO */ #endif /* PDC202XX_DECODE_REGISTER_INFO */
int check_in_drive_lists(struct ata_device *drive) { int check_in_drive_lists(struct ata_device *drive)
const char *pdc_quirk_drives[] = { {
static const char *pdc_quirk_drives[] = {
"QUANTUM FIREBALLlct08 08", "QUANTUM FIREBALLlct08 08",
"QUANTUM FIREBALLP KA6.4", "QUANTUM FIREBALLP KA6.4",
"QUANTUM FIREBALLP KA9.1",
"QUANTUM FIREBALLP LM20.4", "QUANTUM FIREBALLP LM20.4",
"QUANTUM FIREBALLP KX20.5", "QUANTUM FIREBALLP KX20.5",
"QUANTUM FIREBALLP KX27.3", "QUANTUM FIREBALLP KX27.3",
......
...@@ -105,7 +105,6 @@ static struct piix_ide_chip { ...@@ -105,7 +105,6 @@ static struct piix_ide_chip {
static struct piix_ide_chip *piix_config; static struct piix_ide_chip *piix_config;
static unsigned char piix_enabled; static unsigned char piix_enabled;
static unsigned int piix_80w; static unsigned int piix_80w;
static unsigned int piix_clock;
static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
...@@ -147,7 +146,7 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -147,7 +146,7 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
: piix_dma[piix_config->flags & PIIX_UDMA]); : piix_dma[piix_config->flags & PIIX_UDMA]);
piix_print("BM-DMA base: %#x", piix_base); piix_print("BM-DMA base: %#x", piix_base);
piix_print("PCI clock: %d.%dMHz", piix_clock / 1000, piix_clock / 100 % 10); piix_print("PCI clock: %d.%dMHz", system_bus_speed / 1000, system_bus_speed / 100 % 10);
piix_print("-----------------------Primary IDE-------Secondary IDE------"); piix_print("-----------------------Primary IDE-------Secondary IDE------");
...@@ -160,7 +159,7 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -160,7 +159,7 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
piix_print("Cable Type: %10s%20s", (piix_80w & 1) ? "80w" : "40w", (piix_80w & 2) ? "80w" : "40w"); piix_print("Cable Type: %10s%20s", (piix_80w & 1) ? "80w" : "40w", (piix_80w & 2) ? "80w" : "40w");
if (!piix_clock) if (!system_bus_speed)
return p - buffer; return p - buffer;
piix_print("-------------------drive0----drive1----drive2----drive3-----"); piix_print("-------------------drive0----drive1----drive2----drive3-----");
...@@ -192,8 +191,8 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -192,8 +191,8 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
} }
dmaen[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); dmaen[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
cycle[i] = 1000000 / piix_clock * (active[i] + recover[i]); cycle[i] = 1000000 / system_bus_speed * (active[i] + recover[i]);
speed[i] = 2 * piix_clock / (active[i] + recover[i]); speed[i] = 2 * system_bus_speed / (active[i] + recover[i]);
if (!(piix_config->flags & PIIX_UDMA)) if (!(piix_config->flags & PIIX_UDMA))
continue; continue;
...@@ -213,17 +212,17 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -213,17 +212,17 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
udma[i] = (4 - ((e >> (i << 2)) & 3)) * umul; udma[i] = (4 - ((e >> (i << 2)) & 3)) * umul;
} else udma[i] = (8 - ((e >> (i << 2)) & 7)) * 2; } else udma[i] = (8 - ((e >> (i << 2)) & 7)) * 2;
speed[i] = 8 * piix_clock / udma[i]; speed[i] = 8 * system_bus_speed / udma[i];
cycle[i] = 250000 * udma[i] / piix_clock; cycle[i] = 250000 * udma[i] / system_bus_speed;
} }
piix_print_drive("Transfer Mode: ", "%10s", dmaen[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); piix_print_drive("Transfer Mode: ", "%10s", dmaen[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
piix_print_drive("Address Setup: ", "%8dns", (1000000 / piix_clock) * 3); piix_print_drive("Address Setup: ", "%8dns", (1000000 / system_bus_speed) * 3);
piix_print_drive("Cmd Active: ", "%8dns", (1000000 / piix_clock) * 12); piix_print_drive("Cmd Active: ", "%8dns", (1000000 / system_bus_speed) * 12);
piix_print_drive("Cmd Recovery: ", "%8dns", (1000000 / piix_clock) * 18); piix_print_drive("Cmd Recovery: ", "%8dns", (1000000 / system_bus_speed) * 18);
piix_print_drive("Data Active: ", "%8dns", (1000000 / piix_clock) * active[i]); piix_print_drive("Data Active: ", "%8dns", (1000000 / system_bus_speed) * active[i]);
piix_print_drive("Data Recovery: ", "%8dns", (1000000 / piix_clock) * recover[i]); piix_print_drive("Data Recovery: ", "%8dns", (1000000 / system_bus_speed) * recover[i]);
piix_print_drive("Cycle Time: ", "%8dns", cycle[i]); piix_print_drive("Cycle Time: ", "%8dns", cycle[i]);
piix_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); piix_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
...@@ -339,7 +338,7 @@ static int piix_set_drive(struct ata_device *drive, unsigned char speed) ...@@ -339,7 +338,7 @@ static int piix_set_drive(struct ata_device *drive, unsigned char speed)
if (speed > XFER_UDMA_4 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100) if (speed > XFER_UDMA_4 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100)
umul = 4; umul = 4;
T = 1000000000 / piix_clock; T = 1000000000 / system_bus_speed;
UT = T / umul; UT = T / umul;
ata_timing_compute(drive, speed, &t, T, UT); ata_timing_compute(drive, speed, &t, T, UT);
...@@ -493,24 +492,6 @@ static unsigned int __init piix_init_chipset(struct pci_dev *dev) ...@@ -493,24 +492,6 @@ static unsigned int __init piix_init_chipset(struct pci_dev *dev)
pci_write_config_word(dev, PIIX_IDETIM0 + (i << 1), w); pci_write_config_word(dev, PIIX_IDETIM0 + (i << 1), w);
} }
/*
* Determine the system bus clock.
*/
piix_clock = system_bus_speed * 1000;
switch (piix_clock) {
case 33000: piix_clock = 33333; break;
case 37000: piix_clock = 37500; break;
case 41000: piix_clock = 41666; break;
}
if (piix_clock < 20000 || piix_clock > 50000) {
printk(KERN_WARNING "PIIX: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", piix_clock);
printk(KERN_WARNING "PIIX: Use ide0=ata66 if you want to assume 80-wire cable\n");
piix_clock = 33333;
}
/* /*
* Print the boot message. * Print the boot message.
*/ */
......
...@@ -133,12 +133,12 @@ static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int ...@@ -133,12 +133,12 @@ static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int
{ {
byte active_cycle,recovery_cycle; byte active_cycle,recovery_cycle;
if (system_bus_speed <= 33) { if (system_bus_speed <= 33333) {
active_cycle = 9 - IDE_IN(active_time * system_bus_speed / 1000 + 1, 2, 9); active_cycle = 9 - IDE_IN(active_time * system_bus_speed / 1000000 + 1, 2, 9);
recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_speed / 1000 + 1, 0, 15); recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_speed / 1000000 + 1, 0, 15);
} else { } else {
active_cycle = 8 - IDE_IN(active_time * system_bus_speed / 1000 + 1, 1, 8); active_cycle = 8 - IDE_IN(active_time * system_bus_speed / 1000000 + 1, 1, 8);
recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_speed / 1000 + 1, 3, 18); recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_speed / 1000000 + 1, 3, 18);
} }
return((recovery_cycle<<4) | 0x08 | active_cycle); return((recovery_cycle<<4) | 0x08 | active_cycle);
...@@ -152,8 +152,8 @@ static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int ...@@ -152,8 +152,8 @@ static byte qd6500_compute_timing(struct ata_channel *hwif, int active_time, int
static byte qd6580_compute_timing (int active_time, int recovery_time) static byte qd6580_compute_timing (int active_time, int recovery_time)
{ {
byte active_cycle = 17-IDE_IN(active_time * system_bus_speed / 1000 + 1, 2, 17); byte active_cycle = 17-IDE_IN(active_time * system_bus_speed / 1000000 + 1, 2, 17);
byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_speed / 1000 + 1, 2, 15); byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_speed / 1000000 + 1, 2, 15);
return((recovery_cycle<<4) | active_cycle); return((recovery_cycle<<4) | active_cycle);
} }
......
...@@ -242,9 +242,9 @@ static struct pci_dev *isa_dev; ...@@ -242,9 +242,9 @@ static struct pci_dev *isa_dev;
static int svwks_tune_chipset(struct ata_device *drive, byte speed) static int svwks_tune_chipset(struct ata_device *drive, byte speed)
{ {
byte udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; static u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
byte dma_modes[] = { 0x77, 0x21, 0x20 }; static u8 dma_modes[] = { 0x77, 0x21, 0x20 };
byte pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; static u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
struct ata_channel *hwif = drive->channel; struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
...@@ -253,7 +253,7 @@ static int svwks_tune_chipset(struct ata_device *drive, byte speed) ...@@ -253,7 +253,7 @@ static int svwks_tune_chipset(struct ata_device *drive, byte speed)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
unsigned long dma_base = hwif->dma_base; unsigned long dma_base = hwif->dma_base;
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
int err; int err;
byte drive_pci = 0x00; byte drive_pci = 0x00;
......
...@@ -5,8 +5,12 @@ ...@@ -5,8 +5,12 @@
* *
* Maintainer unknown. * Maintainer unknown.
* *
* Drive tuning added from Rebel.com's kernel sources * Changelog:
* -- Russell King (15/11/98) linux@arm.linux.org.uk *
* 15/11/1998 RMK Drive tuning added from Rebel.com's kernel
* sources
* 30/03/2002 RMK Add fixes specified in W83C553F errata.
* (with special thanks to Todd Inglett)
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -27,6 +31,17 @@ ...@@ -27,6 +31,17 @@
extern char *ide_xfer_verbose (byte xfer_rate); extern char *ide_xfer_verbose (byte xfer_rate);
/*
* SL82C105 PCI config register 0x40 bits.
*/
#define CTRL_IDE_IRQB (1 << 30)
#define CTRL_IDE_IRQA (1 << 28)
#define CTRL_LEGIRQ (1 << 11)
#define CTRL_P1F16 (1 << 5)
#define CTRL_P1EN (1 << 4)
#define CTRL_P0F16 (1 << 1)
#define CTRL_P0EN (1 << 0)
/* /*
* Convert a PIO mode and cycle time to the required on/off * Convert a PIO mode and cycle time to the required on/off
* times for the interface. This has protection against run-away * times for the interface. This has protection against run-away
...@@ -111,6 +126,7 @@ static int config_for_dma(ide_drive_t *drive) ...@@ -111,6 +126,7 @@ static int config_for_dma(ide_drive_t *drive)
return 0; return 0;
} }
/* /*
* Check to see if the drive and * Check to see if the drive and
* chipset is capable of DMA mode * chipset is capable of DMA mode
...@@ -146,6 +162,7 @@ static int sl82c105_check_drive(ide_drive_t *drive) ...@@ -146,6 +162,7 @@ static int sl82c105_check_drive(ide_drive_t *drive)
break; break;
} }
} while (0); } while (0);
if (on) if (on)
config_for_dma(drive); config_for_dma(drive);
else else
...@@ -153,18 +170,105 @@ static int sl82c105_check_drive(ide_drive_t *drive) ...@@ -153,18 +170,105 @@ static int sl82c105_check_drive(ide_drive_t *drive)
udma_enable(drive, on, 0); udma_enable(drive, on, 0);
return 0; return 0;
} }
/* /*
* Our own dmaproc, only to intercept ide_dma_check * Our very own dmaproc. We need to intercept various calls
* to fix up the SL82C105 specific behaviour.
*/ */
static int sl82c105_dmaproc(struct ata_device *drive) static int sl82c105_dmaproc(struct ata_device *drive)
{ {
return sl82c105_check_drive(drive); return sl82c105_check_drive(drive);
} }
/*
* The SL82C105 holds off all IDE interrupts while in DMA mode until
* all DMA activity is completed. Sometimes this causes problems (eg,
* when the drive wants to report an error condition).
*
* 0x7e is a "chip testing" register. Bit 2 resets the DMA controller
* state machine. We need to kick this to work around various bugs.
*/
static inline void sl82c105_reset_host(struct pci_dev *dev)
{
u16 val;
pci_read_config_word(dev, 0x7e, &val);
pci_write_config_word(dev, 0x7e, val | (1 << 2));
pci_write_config_word(dev, 0x7e, val & ~(1 << 2));
}
static void sl82c105_dma_enable(struct ata_device *drive, int on, int verbose)
{
if (!on || config_for_dma(drive)) {
config_for_pio(drive, 4, 0);
on = 0;
}
udma_pci_enable(drive, on, verbose);
}
/*
* ATAPI devices can cause the SL82C105 DMA state machine to go gaga.
* Winbond recommend that the DMA state machine is reset prior to
* setting the bus master DMA enable bit.
*
* The generic IDE core will have disabled the BMEN bit before this
* function is called.
*/
static int sl82c105_dma_read(struct ata_device *drive, struct request *rq)
{
sl82c105_reset_host(drive->channel->pci_dev);
return udma_pci_read(drive, rq);
}
static int sl82c105_dma_write(struct ata_device *drive, struct request *rq)
{
sl82c105_reset_host(drive->channel->pci_dev);
return udma_pci_write(drive, rq);
}
static void sl82c105_timeout(struct ata_device *drive)
{
sl82c105_reset_host(drive->channel->pci_dev);
}
/*
* If we get an IRQ timeout, it might be that the DMA state machine
* got confused. Fix from Todd Inglett. Details from Winbond.
*
* This function is called when the IDE timer expires, the drive
* indicates that it is READY, and we were waiting for DMA to complete.
*/
static void sl82c105_lostirq(ide_drive_t *drive)
{
struct ata_channel *ch = drive->channel;
struct pci_dev *dev = ch->pci_dev;
u32 val, mask = ch->unit ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
unsigned long dma_base = ch->dma_base;
printk("sl82c105: lost IRQ: resetting host\n");
/*
* Check the raw interrupt from the drive.
*/
pci_read_config_dword(dev, 0x40, &val);
if (val & mask)
printk("sl82c105: drive was requesting IRQ, but host lost it\n");
/*
* Was DMA enabled? If so, disable it - we're resetting the
* host. The IDE layer will be handling the drive for us.
*/
val = inb(dma_base);
if (val & 1) {
outb(val & ~1, dma_base);
printk("sl82c105: DMA was enabled\n");
}
sl82c105_reset_host(dev);
}
/* /*
* We only deal with PIO mode here - DMA mode 'using_dma' is not * We only deal with PIO mode here - DMA mode 'using_dma' is not
* initialised at the point that this function is called. * initialised at the point that this function is called.
...@@ -185,21 +289,25 @@ static void tune_sl82c105(ide_drive_t *drive, byte pio) ...@@ -185,21 +289,25 @@ static void tune_sl82c105(ide_drive_t *drive, byte pio)
* Return the revision of the Winbond bridge * Return the revision of the Winbond bridge
* which this function is part of. * which this function is part of.
*/ */
static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) static __init unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
{ {
struct pci_dev *bridge; struct pci_dev *bridge;
unsigned char rev; unsigned char rev;
bridge = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, NULL);
/* /*
* If we are part of a Winbond 553 * The bridge should be part of the same device, but function 0.
*/ */
if (!bridge || bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) bridge = pci_find_slot(dev->bus->number,
PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
if (!bridge)
return -1; return -1;
if (bridge->bus != dev->bus || /*
PCI_SLOT(bridge->devfn) != PCI_SLOT(dev->devfn)) * Make sure it is a Winbond 553 and is an ISA bridge.
*/
if (bridge->vendor != PCI_VENDOR_ID_WINBOND ||
bridge->device != PCI_DEVICE_ID_WINBOND_83C553 ||
bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA)
return -1; return -1;
/* /*
...@@ -215,49 +323,55 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) ...@@ -215,49 +323,55 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
*/ */
static unsigned int __init sl82c105_init_chipset(struct pci_dev *dev) static unsigned int __init sl82c105_init_chipset(struct pci_dev *dev)
{ {
unsigned char ctrl_stat; u32 val;
/* pci_read_config_dword(dev, 0x40, &val);
* Enable the ports val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1EN | CTRL_P1F16;
*/ pci_write_config_dword(dev, 0x40, val);
pci_read_config_byte(dev, 0x40, &ctrl_stat);
pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33);
return dev->irq; return dev->irq;
} }
static void __init sl82c105_init_dma(struct ata_channel *hwif, unsigned long dma_base) static void __init sl82c105_init_dma(struct ata_channel *ch, unsigned long dma_base)
{ {
unsigned int rev; unsigned int bridge_rev;
byte dma_state; byte dma_state;
dma_state = inb(dma_base + 2); dma_state = inb(dma_base + 2);
rev = sl82c105_bridge_revision(hwif->pci_dev); bridge_rev = sl82c105_bridge_revision(ch->pci_dev);
if (rev <= 5) { if (bridge_rev <= 5) {
hwif->autodma = 0; ch->autodma = 0;
hwif->drives[0].autotune = 1; ch->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; ch->drives[1].autotune = 1;
printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
hwif->name, rev); ch->name, bridge_rev);
dma_state &= ~0x60; dma_state &= ~0x60;
} else { } else {
dma_state |= 0x60; dma_state |= 0x60;
hwif->autodma = 1; ch->autodma = 1;
} }
outb(dma_state, dma_base + 2); outb(dma_state, dma_base + 2);
hwif->XXX_udma = NULL; ata_init_dma(ch, dma_base);
ata_init_dma(hwif, dma_base);
if (hwif->XXX_udma) if (bridge_rev <= 5)
hwif->XXX_udma = sl82c105_dmaproc; ch->XXX_udma = NULL;
else {
ch->XXX_udma = sl82c105_dmaproc;
ch->udma_enable = sl82c105_dma_enable;
ch->udma_read = sl82c105_dma_read;
ch->udma_write = sl82c105_dma_write;
ch->udma_timeout = sl82c105_timeout;
ch->udma_irq_lost = sl82c105_lostirq;
}
} }
/* /*
* Initialise the chip * Initialise the chip
*/ */
static void __init sl82c105_init_channel(struct ata_channel *hwif) static void __init sl82c105_init_channel(struct ata_channel *ch)
{ {
hwif->tuneproc = tune_sl82c105; ch->tuneproc = tune_sl82c105;
} }
......
...@@ -105,7 +105,7 @@ static struct via_isa_bridge { ...@@ -105,7 +105,7 @@ static struct via_isa_bridge {
unsigned char rev_min; unsigned char rev_min;
unsigned char rev_max; unsigned char rev_max;
unsigned short flags; unsigned short flags;
} via_isa_bridges[] = { } via_isa_bridges [] __initdata = {
#ifdef FUTURE_BRIDGES #ifdef FUTURE_BRIDGES
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 },
...@@ -132,7 +132,6 @@ static struct via_isa_bridge { ...@@ -132,7 +132,6 @@ static struct via_isa_bridge {
static struct via_isa_bridge *via_config; static struct via_isa_bridge *via_config;
static unsigned char via_enabled; static unsigned char via_enabled;
static unsigned int via_80w; static unsigned int via_80w;
static unsigned int via_clock;
static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
/* /*
...@@ -175,7 +174,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -175,7 +174,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
via_print("Highest DMA rate: %s", via_dma[via_config->flags & VIA_UDMA]); via_print("Highest DMA rate: %s", via_dma[via_config->flags & VIA_UDMA]);
via_print("BM-DMA base: %#x", via_base); via_print("BM-DMA base: %#x", via_base);
via_print("PCI clock: %d.%dMHz", via_clock / 1000, via_clock / 100 % 10); via_print("PCI clock: %d.%dMHz", system_bus_speed / 1000, system_bus_speed / 100 % 10);
pci_read_config_byte(dev, VIA_MISC_1, &t); pci_read_config_byte(dev, VIA_MISC_1, &t);
via_print("Master Read Cycle IRDY: %dws", (t & 64) >> 6); via_print("Master Read Cycle IRDY: %dws", (t & 64) >> 6);
...@@ -223,8 +222,8 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -223,8 +222,8 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
uen[i] = ((u >> ((3 - i) << 3)) & 0x20); uen[i] = ((u >> ((3 - i) << 3)) & 0x20);
den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
speed[i] = 2 * via_clock / (active[i] + recover[i]); speed[i] = 2 * system_bus_speed / (active[i] + recover[i]);
cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock; cycle[i] = 1000000 * (active[i] + recover[i]) / system_bus_speed;
if (!uen[i] || !den[i]) if (!uen[i] || !den[i])
continue; continue;
...@@ -232,34 +231,34 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) ...@@ -232,34 +231,34 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
switch (via_config->flags & VIA_UDMA) { switch (via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: case VIA_UDMA_33:
speed[i] = 2 * via_clock / udma[i]; speed[i] = 2 * system_bus_speed / udma[i];
cycle[i] = 1000000 * udma[i] / via_clock; cycle[i] = 1000000 * udma[i] / system_bus_speed;
break; break;
case VIA_UDMA_66: case VIA_UDMA_66:
speed[i] = 4 * via_clock / (udma[i] * umul[i]); speed[i] = 4 * system_bus_speed / (udma[i] * umul[i]);
cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock; cycle[i] = 500000 * (udma[i] * umul[i]) / system_bus_speed;
break; break;
case VIA_UDMA_100: case VIA_UDMA_100:
speed[i] = 6 * via_clock / udma[i]; speed[i] = 6 * system_bus_speed / udma[i];
cycle[i] = 333333 * udma[i] / via_clock; cycle[i] = 333333 * udma[i] / system_bus_speed;
break; break;
case VIA_UDMA_133: case VIA_UDMA_133:
speed[i] = 8 * via_clock / udma[i]; speed[i] = 8 * system_bus_speed / udma[i];
cycle[i] = 250000 * udma[i] / via_clock; cycle[i] = 250000 * udma[i] / system_bus_speed;
break; break;
} }
} }
via_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); via_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
via_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / via_clock); via_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / system_bus_speed);
via_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / via_clock); via_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / system_bus_speed);
via_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / via_clock); via_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / system_bus_speed);
via_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / via_clock); via_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / system_bus_speed);
via_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / via_clock); via_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / system_bus_speed);
via_print_drive("Cycle Time: ", "%8dns", cycle[i]); via_print_drive("Cycle Time: ", "%8dns", cycle[i]);
via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
...@@ -314,7 +313,7 @@ static int via_set_drive(struct ata_device *drive, unsigned char speed) ...@@ -314,7 +313,7 @@ static int via_set_drive(struct ata_device *drive, unsigned char speed)
printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
drive->dn >> 1, drive->dn & 1); drive->dn >> 1, drive->dn & 1);
T = 1000000000 / via_clock; T = 1000000000 / system_bus_speed;
switch (via_config->flags & VIA_UDMA) { switch (via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: UT = T; break; case VIA_UDMA_33: UT = T; break;
...@@ -470,24 +469,6 @@ static unsigned int __init via82cxxx_init_chipset(struct pci_dev *dev) ...@@ -470,24 +469,6 @@ static unsigned int __init via82cxxx_init_chipset(struct pci_dev *dev)
pci_write_config_byte(dev, VIA_FIFO_CONFIG, t); pci_write_config_byte(dev, VIA_FIFO_CONFIG, t);
/*
* Determine system bus clock.
*/
via_clock = system_bus_speed * 1000;
switch (via_clock) {
case 33000: via_clock = 33333; break;
case 37000: via_clock = 37500; break;
case 41000: via_clock = 41666; break;
}
if (via_clock < 20000 || via_clock > 50000) {
printk(KERN_WARNING "VP_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", via_clock);
printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want to assume 80-wire cable.\n");
via_clock = 33333;
}
/* /*
* Print the boot message. * Print the boot message.
*/ */
......
...@@ -40,9 +40,6 @@ ...@@ -40,9 +40,6 @@
/* Right now this is only needed by a promise controlled. /* Right now this is only needed by a promise controlled.
*/ */
#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 */ #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
# define OK_TO_RESET_CONTROLLER 0 /* 0 for use with AH2372A/B interface */ # define OK_TO_RESET_CONTROLLER 0 /* 0 for use with AH2372A/B interface */
#endif #endif
...@@ -202,7 +199,8 @@ typedef enum { ...@@ -202,7 +199,8 @@ typedef enum {
ide_cmd646, ide_cmd646,
ide_cy82c693, ide_cy82c693,
ide_pmac, ide_pmac,
ide_etrax100 ide_etrax100,
ide_acorn
} hwif_chipset_t; } hwif_chipset_t;
...@@ -547,10 +545,6 @@ struct ata_channel { ...@@ -547,10 +545,6 @@ struct ata_channel {
unsigned slow : 1; /* flag: slow data port */ unsigned slow : 1; /* flag: slow data port */
unsigned io_32bit : 1; /* 0=16-bit, 1=32-bit */ unsigned io_32bit : 1; /* 0=16-bit, 1=32-bit */
unsigned char bus_state; /* power state of the IDE bus */ unsigned char bus_state; /* power state of the IDE bus */
#if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */
#endif
}; };
/* /*
...@@ -861,6 +855,15 @@ static inline void udma_irq_lost(struct ata_device *drive) ...@@ -861,6 +855,15 @@ static inline void udma_irq_lost(struct ata_device *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
void udma_pci_enable(struct ata_device *drive, int on, int verbose);
int udma_pci_start(struct ata_device *drive, struct request *rq);
int udma_pci_stop(struct ata_device *drive);
int udma_pci_read(struct ata_device *drive, struct request *rq);
int udma_pci_write(struct ata_device *drive, struct request *rq);
int udma_pci_irq_status(struct ata_device *drive);
void udma_pci_timeout(struct ata_device *drive);
void udma_pci_irq_lost(struct ata_device *);
extern int udma_new_table(struct ata_channel *, struct request *); extern int udma_new_table(struct ata_channel *, struct request *);
extern void udma_destroy_table(struct ata_channel *); extern void udma_destroy_table(struct ata_channel *);
extern void udma_print(struct ata_device *); extern void udma_print(struct ata_device *);
......
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