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
*/ */
......
This diff is collapsed.
...@@ -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)
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); if (pci_present())
system_bus_speed = 33333;
init_ide_data (); 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;
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();
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