Commit eccec1ce authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.21 IDE 88

 - Bunch of cleanups by Bartlomiej (accounts for over a half of the patch):

    cmd64x.c:
	- kill SPLIT_BYTE() macro
	- kill wrappers for cmd64x_config_drive_for_dma()
	- misc cleanups

    cy82c693.c:
	- kill obsolete comments
	- clean cy82c693_tune_drive() and calc_clk()
	- misc cleanups

    hpt34x.c:
	- kill obsolete comment
	- kill SPLIT_BYTE()
	- kill hpt34x_clear_chipset()
	- simplify hpt34x_tune_drive()

    hpt366.c:
	- kill hpt_min_rev()
	- kill redundant hpt368_tune_chipset() and hpt374_tune_chipset()
	- fix badlists checking in config_chipset_for_dma()
	- misc cleanups

    pdc202xx.c:
	- clean registers decoding
	- clean pdc202xx_tune_chipset()
	- kill pdc202xx_udma_irq_status(), use generic udma_pci_irq_status()
	- rationalize pdc202xx_reset()
	- kill UDMA_SPEED_FLAG() and PDC_CLOCK() macros,
	  do it right by defining constants PDC_UDMA and PDC_CLK
	- kill init_high_16() inline, no need to hide internals
	- clean pdc202xx_init_chipset()
	- split ata66_pdc202xx() and pdc202xx_init_chipset()
	- clean config_chipset_for_dma()
	- misc cleanups

 - Fix plug in of CF cards. The previously used sub device driver attach method
   lookup was entirely hosed.

 - Enforce indentation style on ide-cs.c. Enable debugging there. (Makes the
   patch quite big...)
parent ded80dca
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Note, this driver is not used at all on other systems because * Note, this driver is not used at all on other systems because
* there the "BIOS" has done all of the following already. * there the "BIOS" has done all of the following already.
* Due to massive hardware bugs, UltraDMA is only supported * Due to massive hardware bugs, UDMA is not supported on the 646U.
* on the 646U2 and not on the 646U.
* *
* Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be>
* Copyright (C) 1998 David S. Miller <davem@redhat.com> * Copyright (C) 1998 David S. Miller <davem@redhat.com>
...@@ -28,10 +27,6 @@ ...@@ -28,10 +27,6 @@
#include "ata-timing.h" #include "ata-timing.h"
#include "pcihost.h" #include "pcihost.h"
#ifndef SPLIT_BYTE
#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
#endif
#define CMD_DEBUG 0 #define CMD_DEBUG 0
#if CMD_DEBUG #if CMD_DEBUG
...@@ -186,6 +181,7 @@ static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted) ...@@ -186,6 +181,7 @@ static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
* I copied all this complicated stuff from cmd640.c and made a few minor changes. * I copied all this complicated stuff from cmd640.c and made a few minor changes.
* For now I am just going to pray that it is correct. * For now I am just going to pray that it is correct.
*/ */
/* FIXME: try to use generic ata-timings library --bkz */
recovery_time = t->cycle - (t->setup + t->active); recovery_time = t->cycle - (t->setup + t->active);
clock_time = 1000000 / system_bus_speed; clock_time = 1000000 / system_bus_speed;
...@@ -256,9 +252,7 @@ static int cmd64x_ratemask(struct ata_device *drive) ...@@ -256,9 +252,7 @@ static int cmd64x_ratemask(struct ata_device *drive)
case 0x07: case 0x07:
case 0x05: case 0x05:
map |= XFER_UDMA; map |= XFER_UDMA;
case 0x03: default: /* 0x03, 0x01 */
case 0x01:
default:
break; break;
} }
} }
...@@ -272,13 +266,12 @@ static int cmd64x_ratemask(struct ata_device *drive) ...@@ -272,13 +266,12 @@ static int cmd64x_ratemask(struct ata_device *drive)
return map; return map;
} }
static byte cmd680_taskfile_timing(struct ata_channel *hwif) static u8 cmd680_taskfile_timing(struct ata_channel *ch)
{ {
struct pci_dev *dev = hwif->pci_dev; u8 addr_mask = (ch->unit) ? 0xB2 : 0xA2;
byte addr_mask = (hwif->unit) ? 0xB2 : 0xA2; u16 timing;
unsigned short timing;
pci_read_config_word(dev, addr_mask, &timing); pci_read_config_word(ch->pci_dev, addr_mask, &timing);
switch (timing) { switch (timing) {
case 0x10c1: return 4; case 0x10c1: return 4;
...@@ -290,12 +283,12 @@ static byte cmd680_taskfile_timing(struct ata_channel *hwif) ...@@ -290,12 +283,12 @@ static byte cmd680_taskfile_timing(struct ata_channel *hwif)
} }
} }
static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted) static void cmd680_tuneproc(struct ata_device *drive, u8 mode_wanted)
{ {
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;
byte drive_pci; u8 drive_pci;
unsigned short speedt; u16 speedt;
switch (drive->dn) { switch (drive->dn) {
case 0: drive_pci = 0xA4; break; case 0: drive_pci = 0xA4; break;
...@@ -320,25 +313,23 @@ static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted) ...@@ -320,25 +313,23 @@ static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
pci_write_config_word(dev, drive_pci, speedt); pci_write_config_word(dev, drive_pci, speedt);
} }
static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed) static void config_cmd64x_chipset_for_pio(struct ata_device *drive, u8 set_speed)
{ {
byte speed = 0x00; u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
byte set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
cmd64x_tuneproc(drive, set_pio); cmd64x_tuneproc(drive, set_pio);
speed = XFER_PIO_0 + set_pio;
if (set_speed) if (set_speed)
(void) ide_config_drive_speed(drive, speed); (void) ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
} }
static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed) static void config_cmd680_chipset_for_pio(struct ata_device *drive, u8 set_speed)
{ {
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;
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 addr_mask = (hwif->unit) ? 0x84 : 0x80; u8 addr_mask = (hwif->unit) ? 0x84 : 0x80;
u8 speed = 0x00; u8 speed;
u8 mode_pci = 0x00; u8 mode_pci;
u8 channel_timings = cmd680_taskfile_timing(hwif); u8 channel_timings = cmd680_taskfile_timing(hwif);
u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
...@@ -375,8 +366,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) ...@@ -375,8 +366,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 pciU = (hwif->unit) ? UDIDETCR1 : UDIDETCR0; u8 pciU = (hwif->unit) ? UDIDETCR1 : UDIDETCR0;
u8 pciD = (hwif->unit) ? BMIDESR1 : BMIDESR0; u8 pciD = (hwif->unit) ? BMIDESR1 : BMIDESR0;
u8 regU = 0; u8 regU, regD;
u8 regD = 0;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0)) if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return 1; return 1;
...@@ -390,6 +380,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) ...@@ -390,6 +380,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
(void) pci_read_config_byte(dev, pciD, &regD); (void) pci_read_config_byte(dev, pciD, &regD);
(void) pci_read_config_byte(dev, pciU, &regU); (void) pci_read_config_byte(dev, pciU, &regU);
/* FIXME: get unit checking out of here --bkz */
switch(speed) { switch(speed) {
case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break;
case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break;
...@@ -406,12 +397,13 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) ...@@ -406,12 +397,13 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
#else #else
switch(speed) { switch(speed) {
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; case XFER_PIO_4:
case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; case XFER_PIO_3:
case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; case XFER_PIO_2:
case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; case XFER_PIO_1:
case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; case XFER_PIO_0:
cmd64x_tuneproc(drive, speed - XFER_PIO_0);
break;
default: default:
return 1; return 1;
} }
...@@ -436,12 +428,9 @@ static int cmd680_tune_chipset(struct ata_device *drive, byte speed) ...@@ -436,12 +428,9 @@ static int cmd680_tune_chipset(struct ata_device *drive, byte speed)
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
u8 addr_mask = (hwif->unit) ? 0x84 : 0x80; u8 addr_mask = (hwif->unit) ? 0x84 : 0x80;
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 dma_pci = 0; u8 dma_pci, udma_pci;
u8 udma_pci = 0; u8 mode_pci, scsc;
u8 mode_pci = 0; u16 ultra, multi;
u8 scsc = 0;
u16 ultra = 0;
u16 multi = 0;
pci_read_config_byte(dev, addr_mask, &mode_pci); pci_read_config_byte(dev, addr_mask, &mode_pci);
pci_read_config_byte(dev, 0x8A, &scsc); pci_read_config_byte(dev, 0x8A, &scsc);
...@@ -515,11 +504,13 @@ speed_break : ...@@ -515,11 +504,13 @@ speed_break :
multi = 0x2208; multi = 0x2208;
break; break;
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd680_tuneproc(drive, 4); break; case XFER_PIO_4:
case XFER_PIO_3: cmd680_tuneproc(drive, 3); break; case XFER_PIO_3:
case XFER_PIO_2: cmd680_tuneproc(drive, 2); break; case XFER_PIO_2:
case XFER_PIO_1: cmd680_tuneproc(drive, 1); break; case XFER_PIO_1:
case XFER_PIO_0: cmd680_tuneproc(drive, 0); break; case XFER_PIO_0:
cmd680_tuneproc(drive, speed - XFER_PIO_0);
break;
default: default:
return 1; return 1;
} }
...@@ -570,7 +561,7 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma) ...@@ -570,7 +561,7 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
return !drive->channel->speedproc(drive, mode); return !drive->channel->speedproc(drive, mode);
} }
static int cmd64x_config_drive_for_dma(struct ata_device *drive) static int cmd6xx_udma_setup(struct ata_device *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel; struct ata_channel *hwif = drive->channel;
...@@ -627,11 +618,6 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive) ...@@ -627,11 +618,6 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive)
return 0; return 0;
} }
static int cmd680_udma_setup(struct ata_device *drive)
{
return cmd64x_config_drive_for_dma(drive);
}
static int cmd64x_udma_stop(struct ata_device *drive) static int cmd64x_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -680,11 +666,10 @@ static int cmd64x_udma_irq_status(struct ata_device *drive) ...@@ -680,11 +666,10 @@ static int cmd64x_udma_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 int cmd64x_udma_setup(struct ata_device *drive) /*
{ * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
return cmd64x_config_drive_for_dma(drive); * event order for DMA transfers.
} */
static int cmd646_1_udma_stop(struct ata_device *drive) static int cmd646_1_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -699,14 +684,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive) ...@@ -699,14 +684,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive)
return (dma_stat & 7) != 4; /* verify good DMA status */ return (dma_stat & 7) != 4; /* verify good DMA status */
} }
/*
* ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
* event order for DMA transfers.
*/
static int cmd646_1_udma_setup(struct ata_device *drive)
{
return cmd64x_config_drive_for_dma(drive);
}
#endif #endif
static int cmd680_busproc(struct ata_device * drive, int state) static int cmd680_busproc(struct ata_device * drive, int state)
...@@ -808,10 +785,7 @@ static unsigned int cmd64x_pci_init(struct pci_dev *dev) ...@@ -808,10 +785,7 @@ static unsigned int cmd64x_pci_init(struct pci_dev *dev)
} }
printk("\n"); printk("\n");
break; break;
case PCI_DEVICE_ID_CMD_648: default: /* 648, 649 */
case PCI_DEVICE_ID_CMD_649:
break;
default:
break; break;
} }
...@@ -863,8 +837,8 @@ static unsigned int __init cmd64x_init_chipset(struct pci_dev *dev) ...@@ -863,8 +837,8 @@ static unsigned int __init cmd64x_init_chipset(struct pci_dev *dev)
static unsigned int cmd680_ata66(struct ata_channel *hwif) static unsigned int cmd680_ata66(struct ata_channel *hwif)
{ {
byte ata66 = 0; u8 ata66;
byte addr_mask = (hwif->unit) ? 0xB0 : 0xA0; u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66); pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66);
return (ata66 & 0x01) ? 1 : 0; return (ata66 & 0x01) ? 1 : 0;
...@@ -872,8 +846,8 @@ static unsigned int cmd680_ata66(struct ata_channel *hwif) ...@@ -872,8 +846,8 @@ static unsigned int cmd680_ata66(struct ata_channel *hwif)
static unsigned int cmd64x_ata66(struct ata_channel *hwif) static unsigned int cmd64x_ata66(struct ata_channel *hwif)
{ {
byte ata66 = 0; u8 ata66;
byte mask = (hwif->unit) ? 0x02 : 0x01; u8 mask = (hwif->unit) ? 0x02 : 0x01;
pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66); pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
return (ata66 & mask) ? 1 : 0; return (ata66 & mask) ? 1 : 0;
...@@ -881,8 +855,7 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif) ...@@ -881,8 +855,7 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif)
static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif) static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
{ {
struct pci_dev *dev = hwif->pci_dev; if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680)
if (dev->device == PCI_DEVICE_ID_CMD_680)
return cmd680_ata66(hwif); return cmd680_ata66(hwif);
return cmd64x_ata66(hwif); return cmd64x_ata66(hwif);
} }
...@@ -890,7 +863,7 @@ static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif) ...@@ -890,7 +863,7 @@ static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
static void __init cmd64x_init_channel(struct ata_channel *hwif) static void __init cmd64x_init_channel(struct ata_channel *hwif)
{ {
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
unsigned int class_rev; u32 class_rev;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff; class_rev &= 0xff;
...@@ -903,7 +876,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -903,7 +876,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
hwif->busproc = cmd680_busproc; hwif->busproc = cmd680_busproc;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) if (hwif->dma_base)
hwif->udma_setup = cmd680_udma_setup; hwif->udma_setup = cmd6xx_udma_setup;
#endif #endif
hwif->resetproc = cmd680_reset; hwif->resetproc = cmd680_reset;
hwif->speedproc = cmd680_tune_chipset; hwif->speedproc = cmd680_tune_chipset;
...@@ -914,7 +887,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -914,7 +887,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
case PCI_DEVICE_ID_CMD_643: case PCI_DEVICE_ID_CMD_643:
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->udma_setup = cmd64x_udma_setup; hwif->udma_setup = cmd6xx_udma_setup;
hwif->udma_stop = cmd64x_udma_stop; hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status; hwif->udma_irq_status = cmd64x_udma_irq_status;
} }
...@@ -926,11 +899,10 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -926,11 +899,10 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
hwif->chipset = ide_cmd646; hwif->chipset = ide_cmd646;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->udma_setup = cmd6xx_udma_setup;
if (class_rev == 0x01) { if (class_rev == 0x01) {
hwif->udma_setup = cmd646_1_udma_setup;
hwif->udma_stop = cmd646_1_udma_stop; hwif->udma_stop = cmd646_1_udma_stop;
} else { } else {
hwif->udma_setup = cmd64x_udma_setup;
hwif->udma_stop = cmd64x_udma_stop; hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status; hwif->udma_irq_status = cmd64x_udma_irq_status;
} }
...@@ -1007,9 +979,8 @@ int __init init_cmd64x(void) ...@@ -1007,9 +979,8 @@ int __init init_cmd64x(void)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(chipsets); ++i) { for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
ata_register_chipset(&chipsets[i]); ata_register_chipset(&chipsets[i]);
}
return 0; return 0;
} }
...@@ -21,12 +21,9 @@ ...@@ -21,12 +21,9 @@
* hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
* - this is my first linux driver, so there's probably a lot of room * - this is my first linux driver, so there's probably a lot of room
* for optimizations and bug fixing, so feel free to do it. * for optimizations and bug fixing, so feel free to do it.
* - use idebus=xx parameter to set PCI bus speed - needed to calc
* timings for PIO modes (default will be 40)
* - if using PIO mode it's a good idea to set the PIO mode and
* 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
* - I had some problems with my IBM DHEA with PIO modes < 2 * - I had some problems with my IBM DHEA with PIO modes < 2
* (lost interrupts) ????? * (lost interrupts) ?????
* FIXME: probably because we set wrong timings for 8bit --bkz
* - first tests with DMA look okay, they seem to work, but there is a * - first tests with DMA look okay, they seem to work, but there is a
* problem with sound - the BusMaster IDE TimeOut should fixed this * problem with sound - the BusMaster IDE TimeOut should fixed this
* *
...@@ -83,6 +80,9 @@ ...@@ -83,6 +80,9 @@
/* here are the offset definitions for the registers */ /* here are the offset definitions for the registers */
#define CY82_IDE_CMDREG 0x04 #define CY82_IDE_CMDREG 0x04
#define CY82_IDE_ADDRSETUP 0x48 #define CY82_IDE_ADDRSETUP 0x48
#define CYPRESS_TIMINGS 0x4C
#define CY82_IDE_MASTER_IOR 0x4C #define CY82_IDE_MASTER_IOR 0x4C
#define CY82_IDE_MASTER_IOW 0x4D #define CY82_IDE_MASTER_IOW 0x4D
#define CY82_IDE_SLAVE_IOR 0x4E #define CY82_IDE_SLAVE_IOR 0x4E
...@@ -105,19 +105,20 @@ ...@@ -105,19 +105,20 @@
#define CY82C963_MIN_BUS_SPEED 25 #define CY82C963_MIN_BUS_SPEED 25
#define CY82C963_MAX_BUS_SPEED 33 #define CY82C963_MAX_BUS_SPEED 33
/* the struct for the PIO mode timings */ /* the struct for the PIO mode timings (in clocks) */
typedef struct pio_clocks_s { typedef struct pio_clocks_s {
byte address_time; /* Address setup (clocks) */ u8 address_time; /* Address setup */
byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ /* 0xF0=Active/data, 0x0F=Recovery */
byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ u8 time_16r; /* 16bit IOR */
byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ u8 time_16w; /* 16bit IOW */
u8 time_8; /* 8bit */
} pio_clocks_t; } pio_clocks_t;
/* /*
* calc clocks using bus_speed * calc clocks using bus_speed
* returns (rounded up) time in bus clocks for time in ns * returns (rounded up) time in bus clocks for time in ns
*/ */
static int calc_clk (int time, int bus_speed) static u8 calc_clk(int time, int bus_speed)
{ {
int clocks; int clocks;
...@@ -129,7 +130,7 @@ static int calc_clk (int time, int bus_speed) ...@@ -129,7 +130,7 @@ static int calc_clk (int time, int bus_speed)
if (clocks > 0x0F) if (clocks > 0x0F)
clocks = 0x0F; clocks = 0x0F;
return clocks; return (u8)clocks;
} }
/* /*
...@@ -140,7 +141,8 @@ static int calc_clk (int time, int bus_speed) ...@@ -140,7 +141,8 @@ static int calc_clk (int time, int bus_speed)
* for mode 3 and 4 drives 8 and 16-bit timings are the same * for mode 3 and 4 drives 8 and 16-bit timings are the same
* *
*/ */
static void compute_clocks (byte pio, pio_clocks_t *p_pclk) /* FIXME: use generic ata-timings library --bkz */
static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
{ {
struct ata_timing *t; struct ata_timing *t;
int clk1, clk2; int clk1, clk2;
...@@ -149,34 +151,33 @@ static void compute_clocks (byte pio, pio_clocks_t *p_pclk) ...@@ -149,34 +151,33 @@ static void compute_clocks (byte pio, pio_clocks_t *p_pclk)
/* we don't check against CY82C693's min and max speed, /* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter * so you can play with the idebus=xx parameter
* FIXME: warn about going out of specification --bkz
*/ */
if (pio > CY82C693_MAX_PIO) if (pio > CY82C693_MAX_PIO)
pio = CY82C693_MAX_PIO; pio = CY82C693_MAX_PIO;
/* let's calc the address setup time clocks */ /* address setup */
p_pclk->address_time = (byte)calc_clk(t->setup, system_bus_speed); p_pclk->address_time = calc_clk(t->setup, system_bus_speed);
/* let's calc the active and recovery time clocks */ /* active */
clk1 = calc_clk(t->active, system_bus_speed); clk1 = calc_clk(t->active, system_bus_speed);
/* calc recovery timing */ /* FIXME: check why not t->cycle - t->active ? --bkz */
clk2 = t->cycle - t->active - t->setup; /* recovery */
clk2 = calc_clk(t->cycle - t->active - t->setup, system_bus_speed);
clk2 = calc_clk(clk2, system_bus_speed);
clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ clk1 = (clk1 << 4) | clk2; /* combine active and recovery clocks */
/* note: we use the same values for 16bit IOR and IOW /* note: we use the same values for 16bit IOR and IOW
* those are all the same, since I don't have other * those are all the same, since I don't have other
* timings than those from ata-timing.h * timings than those from ata-timing.h
*/ */
p_pclk->time_16w = p_pclk->time_16r = clk1;
p_pclk->time_16r = (byte)clk1; /* FIXME: ugh... --bkz */
p_pclk->time_16w = (byte)clk1;
/* what are good values for 8bit ?? */ /* what are good values for 8bit ?? */
p_pclk->time_8 = (byte)clk1; p_pclk->time_8 = clk1;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
...@@ -276,7 +277,9 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) ...@@ -276,7 +277,9 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio)
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
pio_clocks_t pclk; pio_clocks_t pclk;
unsigned int addrCtrl; unsigned int addrCtrl;
u8 ior, iow, bit8;
/* FIXME: probaly broken --bkz */
/* select primary or secondary channel */ /* select primary or secondary channel */
if (hwif->index > 0) { /* drive is on the secondary channel */ if (hwif->index > 0) { /* drive is on the secondary channel */
dev = pci_find_slot(dev->bus->number, dev->devfn+1); dev = pci_find_slot(dev->bus->number, dev->devfn+1);
...@@ -286,40 +289,41 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) ...@@ -286,40 +289,41 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio)
} }
} }
if (drive->select.b.unit == 0) {
ior = CY82_IDE_MASTER_IOR;
iow = CY82_IDE_MASTER_IOW;
bit8 = CY82_IDE_MASTER_8BIT;
} else {
ior = CY82_IDE_SLAVE_IOR;
iow = CY82_IDE_SLAVE_IOW;
bit8 = CY82_IDE_SLAVE_8BIT;
}
#if CY82C693_DEBUG_LOGS #if CY82C693_DEBUG_LOGS
/* for debug let's show the register values */ /* for debug let's show the register values */
if (drive->select.b.unit == 0) { /*
/* * get address setup control register
* get master drive registers * mine master or slave data
* address setup control register */
* is 32 bit !!! pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= 0x0F;
/* now let's get the remaining registers */
pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r);
pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w);
pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8);
} else {
/*
* set slave drive registers
* address setup control register
* is 32 bit !!!
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
if (drive->select.b.unit == 0)
addrCtrl &= 0x0F;
else {
addrCtrl &= 0xF0; addrCtrl &= 0xF0;
addrCtrl >>= 4; addrCtrl >>= 4;
/* now let's get the remaining registers */
pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r);
pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w);
pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8);
} }
printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); /* now let's get the remaining registers */
pci_read_config_byte(dev, ior, &pclk.time_16r);
pci_read_config_byte(dev, iow, &pclk.time_16w);
pci_read_config_byte(dev, bit8, &pclk.time_8);
printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X,"
" ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
drive->name, hwif->unit, drive->select.b.unit,
addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
#endif /* CY82C693_DEBUG_LOGS */ #endif /* CY82C693_DEBUG_LOGS */
/* first let's calc the pio modes */ /* first let's calc the pio modes */
...@@ -331,65 +335,37 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) ...@@ -331,65 +335,37 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio)
compute_clocks(pio, &pclk); /* let's calc the values for this PIO mode */ compute_clocks(pio, &pclk); /* let's calc the values for this PIO mode */
/* now let's write the clocks registers */ /*
* set address setup control register
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
if (drive->select.b.unit == 0) { if (drive->select.b.unit == 0) {
/* addrCtrl &= (~0x0F);
* set master drive
* address setup control register
* is 32 bit !!!
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF);
addrCtrl |= (unsigned int)pclk.address_time; addrCtrl |= (unsigned int)pclk.address_time;
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
addrCtrl &= 0xF;
} else { } else {
/*
* set slave drive
* address setup control register
* is 32 bit !!!
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF0); addrCtrl &= (~0xF0);
addrCtrl |= ((unsigned int)pclk.address_time<<4); addrCtrl |= ((unsigned int)pclk.address_time<<4);
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
addrCtrl >>= 4;
addrCtrl &= 0xF;
} }
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
pci_write_config_byte(dev, ior, pclk.time_16r);
pci_write_config_byte(dev, iow, pclk.time_16w);
pci_write_config_byte(dev, bit8, pclk.time_8);
#if CY82C693_DEBUG_INFO #if CY82C693_DEBUG_INFO
printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X,"
#endif /* CY82C693_DEBUG_INFO */ " ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name,
hwif->unit, drive->select.b.unit, addrCtrl,
pclk.time_16r, pclk.time_16w, pclk.time_8);
#endif
} }
/*
* this function is called during init and is used to setup the cy82c693 chip
*/
/*
* FIXME! "pci_init_cy82c693" really should replace
* the "init_cy82c693_chip", it is the correct location to tinker/setup
* the device prior to INIT.
*/
static unsigned int __init pci_init_cy82c693(struct pci_dev *dev) static unsigned int __init pci_init_cy82c693(struct pci_dev *dev)
{ {
#ifdef CY82C693_SETDMA_CLOCK #ifdef CY82C693_SETDMA_CLOCK
byte data; u8 data;
#endif /* CY82C693_SETDMA_CLOCK */ #endif
/* write info about this verion of the driver */ /* write info about this verion of the driver */
printk (KERN_INFO CY82_VERSION "\n"); printk (KERN_INFO CY82_VERSION "\n");
...@@ -402,7 +378,7 @@ static unsigned int __init pci_init_cy82c693(struct pci_dev *dev) ...@@ -402,7 +378,7 @@ static unsigned int __init pci_init_cy82c693(struct pci_dev *dev)
#if CY82C693_DEBUG_INFO #if CY82C693_DEBUG_INFO
printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", dev->name, data); printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", dev->name, data);
#endif /* CY82C693_DEBUG_INFO */ #endif
/* /*
* for some reason sometimes the DMA controller * for some reason sometimes the DMA controller
......
...@@ -5,19 +5,7 @@ ...@@ -5,19 +5,7 @@
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
* *
* * ide-pci.c reference:
* 00:12.0 Unknown mass storage controller:
* Triones Technologies, Inc.
* Unknown device 0003 (rev 01)
*
* hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
* hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
* hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010)
* hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030)
* hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070)
* hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0)
*
* ide-pci.c reference
* *
* Since there are two cards that report almost identically, * Since there are two cards that report almost identically,
* the only discernable difference is the values reported in pcicmd. * the only discernable difference is the values reported in pcicmd.
...@@ -45,53 +33,34 @@ ...@@ -45,53 +33,34 @@
#include "ata-timing.h" #include "ata-timing.h"
#include "pcihost.h" #include "pcihost.h"
#ifndef SPLIT_BYTE
# define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
#endif
#define HPT343_DEBUG_DRIVE_INFO 0 #define HPT343_DEBUG_DRIVE_INFO 0
static void hpt34x_clear_chipset(struct ata_device *drive) static int hpt34x_tune_chipset(struct ata_device *drive, u8 speed)
{
unsigned int reg1 = 0, tmp1 = 0;
unsigned int reg2 = 0, tmp2 = 0;
pci_read_config_dword(drive->channel->pci_dev, 0x44, &reg1);
pci_read_config_dword(drive->channel->pci_dev, 0x48, &reg2);
tmp1 = ((0x00 << (3 * drive->dn)) | (reg1 & ~(7 << (3 * drive->dn))));
tmp2 = (reg2 & ~(0x11 << drive->dn));
pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1);
pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2);
}
static int hpt34x_tune_chipset(struct ata_device *drive, byte speed)
{ {
byte hi_speed, lo_speed; struct pci_dev *dev = drive->channel->pci_dev;
unsigned int reg1 = 0, tmp1 = 0; u8 udma = 0, pio = 0;
unsigned int reg2 = 0, tmp2 = 0; u32 reg1, reg2, tmp1, tmp2;
SPLIT_BYTE(speed, hi_speed, lo_speed); if (speed >= XFER_UDMA_0)
udma = 0x01;
if (hi_speed & 7) { else if (speed >= XFER_SW_DMA_0)
hi_speed = (hi_speed & 4) ? 0x01 : 0x10; udma = 0x10;
} else { else
lo_speed <<= 5; pio = speed & 7;
lo_speed >>= 5;
}
pci_read_config_dword(drive->channel->pci_dev, 0x44, &reg1); pci_read_config_dword(dev, 0x44, &reg1);
pci_read_config_dword(drive->channel->pci_dev, 0x48, &reg2); pci_read_config_dword(dev, 0x48, &reg2);
tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); tmp1 = (pio << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)));
tmp2 = ((hi_speed << drive->dn) | reg2); tmp2 = (udma << drive->dn) | (reg2 & ~(0x11 << drive->dn));
pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1); pci_write_config_dword(dev, 0x44, tmp1);
pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2); pci_write_config_dword(dev, 0x48, tmp2);
#if HPT343_DEBUG_DRIVE_INFO #if HPT343_DEBUG_DRIVE_INFO
printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
" (0x%02x 0x%02x) 0x%04x\n", " (0x%02x 0x%02x) 0x%04x\n",
drive->name, speed, drive->name, speed,
drive->dn, reg1, tmp1, reg2, tmp2, drive->dn, reg1, tmp1, reg2, tmp2,
hi_speed, lo_speed, err); udma, pio, err);
#endif #endif
drive->current_speed = speed; drive->current_speed = speed;
...@@ -103,7 +72,7 @@ static void config_chipset_for_pio(struct ata_device *drive) ...@@ -103,7 +72,7 @@ static void config_chipset_for_pio(struct ata_device *drive)
unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
unsigned short xfer_pio = drive->id->eide_pio_modes; unsigned short xfer_pio = drive->id->eide_pio_modes;
byte timing, speed, pio; u8 timing, speed, pio;
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
...@@ -135,19 +104,9 @@ static void config_chipset_for_pio(struct ata_device *drive) ...@@ -135,19 +104,9 @@ static void config_chipset_for_pio(struct ata_device *drive)
(void) hpt34x_tune_chipset(drive, speed); (void) hpt34x_tune_chipset(drive, speed);
} }
static void hpt34x_tune_drive(struct ata_device *drive, byte pio) static void hpt34x_tune_drive(struct ata_device *drive, u8 pio)
{ {
byte speed; (void) hpt34x_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
switch(pio) {
case 4: speed = XFER_PIO_4;break;
case 3: speed = XFER_PIO_3;break;
case 2: speed = XFER_PIO_2;break;
case 1: speed = XFER_PIO_1;break;
default: speed = XFER_PIO_0;break;
}
hpt34x_clear_chipset(drive);
(void) hpt34x_tune_chipset(drive, speed);
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
...@@ -168,7 +127,6 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma) ...@@ -168,7 +127,6 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
if (mode < XFER_SW_DMA_0) if (mode < XFER_SW_DMA_0)
return 0; return 0;
hpt34x_clear_chipset(drive);
return !hpt34x_tune_chipset(drive, mode); return !hpt34x_tune_chipset(drive, mode);
} }
......
...@@ -476,8 +476,6 @@ static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { ...@@ -476,8 +476,6 @@ static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
#define F_LOW_PCI_50 0x2d #define F_LOW_PCI_50 0x2d
#define F_LOW_PCI_66 0x42 #define F_LOW_PCI_66 0x42
static unsigned int hpt_min_rev(struct pci_dev *dev, int rev);
static int check_in_drive_lists(struct ata_device *drive, const char **list) static int check_in_drive_lists(struct ata_device *drive, const char **list)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
...@@ -515,29 +513,24 @@ static unsigned int hpt_revision(struct pci_dev *dev) ...@@ -515,29 +513,24 @@ static unsigned int hpt_revision(struct pci_dev *dev)
return class_rev; return class_rev;
} }
static unsigned int hpt_min_rev(struct pci_dev *dev, int rev)
{
return (hpt_revision(dev) >= rev) ? 1 : 0;
}
static int hpt3xx_ratemask(struct ata_device *drive) static int hpt3xx_ratemask(struct ata_device *drive)
{ {
struct pci_dev *dev = drive->channel->pci_dev; u32 rev = hpt_revision(drive->channel->pci_dev);
int map = XFER_UDMA; int map = XFER_UDMA;
if (hpt_min_rev(dev, 8)) { /* HPT374 */ if (rev >= 8) { /* HPT374 */
if (HPT374_ALLOW_ATA133_6) if (HPT374_ALLOW_ATA133_6)
map |= XFER_UDMA_133; map |= XFER_UDMA_133;
map |= (XFER_UDMA_100 | XFER_UDMA_66); map |= (XFER_UDMA_100 | XFER_UDMA_66);
} else if (hpt_min_rev(dev, 5)) { /* HPT372 */ } else if (rev >= 5) { /* HPT372 */
if (HPT372_ALLOW_ATA133_6) if (HPT372_ALLOW_ATA133_6)
map |= XFER_UDMA_133; map |= XFER_UDMA_133;
map |= (XFER_UDMA_100 | XFER_UDMA_66); map |= (XFER_UDMA_100 | XFER_UDMA_66);
} else if (hpt_min_rev(dev, 4)) { /* HPT370A */ } else if (rev >= 4) { /* HPT370A */
if (HPT370_ALLOW_ATA100_5) if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100; map |= XFER_UDMA_100;
map |= XFER_UDMA_66; map |= XFER_UDMA_66;
} else if (hpt_min_rev(dev, 3)) { /* HPT370 */ } else if (rev >= 3) { /* HPT370 */
if (HPT370_ALLOW_ATA100_5) if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100; map |= XFER_UDMA_100;
map |= XFER_UDMA_66; map |= XFER_UDMA_66;
...@@ -600,11 +593,6 @@ static void hpt366_tune_chipset(struct ata_device *drive, u8 speed) ...@@ -600,11 +593,6 @@ static void hpt366_tune_chipset(struct ata_device *drive, u8 speed)
pci_write_config_dword(dev, regtime, reg2); pci_write_config_dword(dev, regtime, reg2);
} }
static void hpt368_tune_chipset(struct ata_device *drive, u8 speed)
{
hpt366_tune_chipset(drive, speed);
}
static void hpt370_tune_chipset(struct ata_device *drive, u8 speed) static void hpt370_tune_chipset(struct ata_device *drive, u8 speed)
{ {
u8 regfast = (drive->channel->unit) ? 0x55 : 0x51; u8 regfast = (drive->channel->unit) ? 0x55 : 0x51;
...@@ -674,31 +662,24 @@ static void hpt372_tune_chipset(struct ata_device *drive, u8 speed) ...@@ -674,31 +662,24 @@ static void hpt372_tune_chipset(struct ata_device *drive, u8 speed)
pci_write_config_dword(dev, drive_pci, list_conf); pci_write_config_dword(dev, drive_pci, list_conf);
} }
static void hpt374_tune_chipset(struct ata_device *drive, u8 speed)
{
hpt372_tune_chipset(drive, speed);
}
static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed) static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed)
{ {
struct pci_dev *dev = drive->channel->pci_dev; u32 rev;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0)) if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return -1; return -1;
if (hpt_min_rev(dev, 7)) { rev = hpt_revision(drive->channel->pci_dev);
hpt374_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 5)) { if (rev >= 5) {
hpt372_tune_chipset(drive, speed); hpt372_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 3)) { } else if (rev >= 3) {
hpt370_tune_chipset(drive, speed); hpt370_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 2)) {
hpt368_tune_chipset(drive, speed);
} else { } else {
hpt366_tune_chipset(drive, speed); hpt366_tune_chipset(drive, speed);
} }
drive->current_speed = speed; drive->current_speed = speed;
return ((int) ide_config_drive_speed(drive, speed)); return ide_config_drive_speed(drive, speed);
} }
static void config_chipset_for_pio(struct ata_device *drive) static void config_chipset_for_pio(struct ata_device *drive)
...@@ -755,13 +736,15 @@ static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio) ...@@ -755,13 +736,15 @@ static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive) static int config_chipset_for_dma(struct ata_device *drive)
{ {
struct pci_dev *dev = drive->channel->pci_dev;
int map; int map;
u32 rev;
u8 mode; u8 mode;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
rev = hpt_revision(drive->channel->pci_dev);
/* FIXME: check SWDMA modes --bkz */ /* FIXME: check SWDMA modes --bkz */
map = hpt3xx_ratemask(drive) | XFER_MWDMA; map = hpt3xx_ratemask(drive) | XFER_MWDMA;
mode = ata_timing_mode(drive, map); mode = ata_timing_mode(drive, map);
...@@ -770,7 +753,7 @@ static int config_chipset_for_dma(struct ata_device *drive) ...@@ -770,7 +753,7 @@ static int config_chipset_for_dma(struct ata_device *drive)
bad_ata100_5 is for HPT370/370A, bad_ata100_5 is for HPT370/370A,
bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368 bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368
*/ */
if (mode == XFER_UDMA_5 && hpt_min_rev(dev, 5)) { if (mode == XFER_UDMA_5 && rev < 5) {
if (check_in_drive_lists(drive, bad_ata100_5)) { if (check_in_drive_lists(drive, bad_ata100_5)) {
/* FIXME: make XFER_UDMA_66/100/133 /* FIXME: make XFER_UDMA_66/100/133
independent of XFER_UDMA --bkz */ independent of XFER_UDMA --bkz */
...@@ -779,7 +762,7 @@ static int config_chipset_for_dma(struct ata_device *drive) ...@@ -779,7 +762,7 @@ static int config_chipset_for_dma(struct ata_device *drive)
mode = ata_timing_mode(drive, map); mode = ata_timing_mode(drive, map);
} }
} }
if (mode == XFER_UDMA_4 && hpt_min_rev(dev, 3)) { if (mode == XFER_UDMA_4 && rev < 3) {
if (check_in_drive_lists(drive, bad_ata66_4)) { if (check_in_drive_lists(drive, bad_ata66_4)) {
if (drive->id->dma_ultra & 0x0008) { if (drive->id->dma_ultra & 0x0008) {
mode = XFER_UDMA_3; mode = XFER_UDMA_3;
...@@ -790,14 +773,14 @@ static int config_chipset_for_dma(struct ata_device *drive) ...@@ -790,14 +773,14 @@ static int config_chipset_for_dma(struct ata_device *drive)
} }
} }
} }
if (mode == XFER_UDMA_3 && hpt_min_rev(dev, 3)) { if (mode == XFER_UDMA_3 && rev < 3) {
if (check_in_drive_lists(drive, bad_ata66_3)) { if (check_in_drive_lists(drive, bad_ata66_3)) {
map &= ~XFER_UDMA_66; map &= ~XFER_UDMA_66;
map |= XFER_UDMA; map |= XFER_UDMA;
mode = ata_timing_mode(drive, map); mode = ata_timing_mode(drive, map);
} }
} }
if (check_in_drive_lists(drive, bad_ata33) && hpt_min_rev(dev, 3)) if (check_in_drive_lists(drive, bad_ata33) && rev < 3)
mode = ata_timing_mode(drive, XFER_MWDMA); mode = ata_timing_mode(drive, XFER_MWDMA);
return !hpt3xx_tune_chipset(drive, mode); return !hpt3xx_tune_chipset(drive, mode);
...@@ -823,7 +806,8 @@ static void hpt3xx_maskproc(struct ata_device *drive) ...@@ -823,7 +806,8 @@ static void hpt3xx_maskproc(struct ata_device *drive)
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
if (drive->quirk_list) { if (drive->quirk_list) {
if (hpt_min_rev(dev, 3)) { u32 rev = hpt_revision(dev);
if (rev >= 3) {
u8 reg5a; u8 reg5a;
pci_read_config_byte(dev, 0x5a, &reg5a); pci_read_config_byte(dev, 0x5a, &reg5a);
if ((reg5a & 0x10) >> 4) if ((reg5a & 0x10) >> 4)
...@@ -892,15 +876,16 @@ static int hpt3xx_udma_setup(struct ata_device *drive) ...@@ -892,15 +876,16 @@ static int hpt3xx_udma_setup(struct ata_device *drive)
static void hpt366_udma_irq_lost(struct ata_device *drive) static void hpt366_udma_irq_lost(struct ata_device *drive)
{ {
struct pci_dev *dev = drive->channel->pci_dev;
u8 reg50h, reg52h, reg5ah; u8 reg50h, reg52h, reg5ah;
pci_read_config_byte(drive->channel->pci_dev, 0x50, &reg50h); pci_read_config_byte(dev, 0x50, &reg50h);
pci_read_config_byte(drive->channel->pci_dev, 0x52, &reg52h); pci_read_config_byte(dev, 0x52, &reg52h);
pci_read_config_byte(drive->channel->pci_dev, 0x5a, &reg5ah); pci_read_config_byte(dev, 0x5a, &reg5ah);
printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
drive->name, __FUNCTION__, reg50h, reg52h, reg5ah); drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
if (reg5ah & 0x10) if (reg5ah & 0x10)
pci_write_config_byte(drive->channel->pci_dev, 0x5a, reg5ah & ~0x10); pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
} }
static void do_udma_start(struct ata_device *drive) static void do_udma_start(struct ata_device *drive)
...@@ -1127,7 +1112,7 @@ static void __init hpt37x_init(struct pci_dev *dev) ...@@ -1127,7 +1112,7 @@ static void __init hpt37x_init(struct pci_dev *dev)
{ {
int adjust, i; int adjust, i;
u16 freq; u16 freq;
u32 pll; u32 pll, rev = hpt_revision(dev);
u8 reg5bh; u8 reg5bh;
/* /*
...@@ -1144,9 +1129,9 @@ static void __init hpt37x_init(struct pci_dev *dev) ...@@ -1144,9 +1129,9 @@ static void __init hpt37x_init(struct pci_dev *dev)
freq &= 0x1FF; freq &= 0x1FF;
if (freq < 0x9c) { if (freq < 0x9c) {
pll = F_LOW_PCI_33; pll = F_LOW_PCI_33;
if (hpt_min_rev(dev, 7)) { if (rev >= 7) {
dev->sysdata = (void *) thirty_three_base_hpt374; dev->sysdata = (void *) thirty_three_base_hpt374;
} else if (hpt_min_rev(dev, 5)) { } else if (rev >= 5) {
dev->sysdata = (void *) thirty_three_base_hpt372; dev->sysdata = (void *) thirty_three_base_hpt372;
} else { } else {
dev->sysdata = (void *) thirty_three_base_hpt370; dev->sysdata = (void *) thirty_three_base_hpt370;
...@@ -1156,10 +1141,10 @@ static void __init hpt37x_init(struct pci_dev *dev) ...@@ -1156,10 +1141,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
pll = F_LOW_PCI_40; pll = F_LOW_PCI_40;
} else if (freq < 0xc8) { } else if (freq < 0xc8) {
pll = F_LOW_PCI_50; pll = F_LOW_PCI_50;
if (hpt_min_rev(dev, 7)) { if (rev >= 7) {
// dev->sysdata = (void *) fifty_base_hpt374; // dev->sysdata = (void *) fifty_base_hpt374;
BUG(); BUG();
} else if (hpt_min_rev(dev, 5)) { } else if (rev >= 5) {
dev->sysdata = (void *) fifty_base_hpt372; dev->sysdata = (void *) fifty_base_hpt372;
} else { } else {
dev->sysdata = (void *) fifty_base_hpt370; dev->sysdata = (void *) fifty_base_hpt370;
...@@ -1167,10 +1152,10 @@ static void __init hpt37x_init(struct pci_dev *dev) ...@@ -1167,10 +1152,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
printk("HPT37X: using 50MHz PCI clock\n"); printk("HPT37X: using 50MHz PCI clock\n");
} else { } else {
pll = F_LOW_PCI_66; pll = F_LOW_PCI_66;
if (hpt_min_rev(dev, 7)) { if (rev >= 7) {
// dev->sysdata = (void *) sixty_six_base_hpt374; // dev->sysdata = (void *) sixty_six_base_hpt374;
BUG(); BUG();
} else if (hpt_min_rev(dev, 5)) { } else if (rev >= 5) {
dev->sysdata = (void *) sixty_six_base_hpt372; dev->sysdata = (void *) sixty_six_base_hpt372;
} else { } else {
dev->sysdata = (void *) sixty_six_base_hpt370; dev->sysdata = (void *) sixty_six_base_hpt370;
...@@ -1213,10 +1198,10 @@ static void __init hpt37x_init(struct pci_dev *dev) ...@@ -1213,10 +1198,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
pci_write_config_dword(dev, 0x5c, pci_write_config_dword(dev, 0x5c,
pll & ~0x100); pll & ~0x100);
pci_write_config_byte(dev, 0x5b, 0x21); pci_write_config_byte(dev, 0x5b, 0x21);
if (hpt_min_rev(dev, 7)) { if (rev >= 7) {
// dev->sysdata = (void *) fifty_base_hpt374; // dev->sysdata = (void *) fifty_base_hpt374;
BUG(); BUG();
} else if (hpt_min_rev(dev, 5)) { } else if (rev >= 5) {
dev->sysdata = (void *) fifty_base_hpt372; dev->sysdata = (void *) fifty_base_hpt372;
} else { } else {
dev->sysdata = (void *) fifty_base_hpt370; dev->sysdata = (void *) fifty_base_hpt370;
...@@ -1269,6 +1254,7 @@ static void __init hpt366_init(struct pci_dev *dev) ...@@ -1269,6 +1254,7 @@ static void __init hpt366_init(struct pci_dev *dev)
static unsigned int __init hpt366_init_chipset(struct pci_dev *dev) static unsigned int __init hpt366_init_chipset(struct pci_dev *dev)
{ {
u32 rev = hpt_revision(dev);
u8 test; u8 test;
if (dev->resource[PCI_ROM_RESOURCE].start) if (dev->resource[PCI_ROM_RESOURCE].start)
...@@ -1290,7 +1276,7 @@ static unsigned int __init hpt366_init_chipset(struct pci_dev *dev) ...@@ -1290,7 +1276,7 @@ static unsigned int __init hpt366_init_chipset(struct pci_dev *dev)
if (test != 0x08) if (test != 0x08)
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
if (hpt_min_rev(dev, 3)) if (rev >= 3)
hpt37x_init(dev); hpt37x_init(dev);
else else
hpt366_init(dev); hpt366_init(dev);
...@@ -1315,6 +1301,7 @@ static unsigned int __init hpt366_ata66_check(struct ata_channel *ch) ...@@ -1315,6 +1301,7 @@ static unsigned int __init hpt366_ata66_check(struct ata_channel *ch)
static void __init hpt366_init_channel(struct ata_channel *ch) static void __init hpt366_init_channel(struct ata_channel *ch)
{ {
struct pci_dev *dev = ch->pci_dev; struct pci_dev *dev = ch->pci_dev;
u32 rev = hpt_revision(dev);
ch->tuneproc = hpt3xx_tune_drive; ch->tuneproc = hpt3xx_tune_drive;
ch->speedproc = hpt3xx_tune_chipset; ch->speedproc = hpt3xx_tune_chipset;
...@@ -1330,7 +1317,7 @@ static void __init hpt366_init_channel(struct ata_channel *ch) ...@@ -1330,7 +1317,7 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (ch->dma_base) { if (ch->dma_base) {
if (hpt_min_rev(dev, 3)) { if (rev >= 3) {
u8 reg5ah; u8 reg5ah;
pci_read_config_byte(dev, 0x5a, &reg5ah); pci_read_config_byte(dev, 0x5a, &reg5ah);
if (reg5ah & 0x10) /* interrupt force enable */ if (reg5ah & 0x10) /* interrupt force enable */
...@@ -1343,45 +1330,33 @@ static void __init hpt366_init_channel(struct ata_channel *ch) ...@@ -1343,45 +1330,33 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
ch->resetproc = hpt3xx_reset; ch->resetproc = hpt3xx_reset;
ch->busproc = hpt370_busproc; ch->busproc = hpt370_busproc;
if (hpt_min_rev(dev, 7)) { if (rev >= 5) {
ch->udma_stop = hpt374_udma_stop; ch->udma_stop = hpt374_udma_stop;
ch->udma_setup = hpt3xx_udma_setup; } else { /* rev >= 3 */
} else if (hpt_min_rev(dev, 5)) {
ch->udma_stop = hpt374_udma_stop;
ch->udma_setup = hpt3xx_udma_setup;
} else if (hpt_min_rev(dev, 3)) {
ch->udma_start = hpt370_udma_start; ch->udma_start = hpt370_udma_start;
ch->udma_stop = hpt370_udma_stop; ch->udma_stop = hpt370_udma_stop;
ch->udma_timeout = hpt370_udma_timeout; ch->udma_timeout = hpt370_udma_timeout;
ch->udma_irq_lost = hpt370_udma_irq_lost; ch->udma_irq_lost = hpt370_udma_irq_lost;
ch->udma_setup = hpt3xx_udma_setup;
} }
} else if (hpt_min_rev(dev, 2)) {
ch->udma_irq_lost = hpt366_udma_irq_lost;
// ch->resetproc = hpt3xx_reset;
// ch->busproc = hpt3xx_tristate;
ch->udma_setup = hpt3xx_udma_setup;
} else { } else {
ch->udma_irq_lost = hpt366_udma_irq_lost; ch->udma_irq_lost = hpt366_udma_irq_lost;
// ch->resetproc = hpt3xx_reset; // ch->resetproc = hpt3xx_reset;
// ch->busproc = hpt3xx_tristate; // ch->busproc = hpt3xx_tristate;
ch->udma_setup = hpt3xx_udma_setup;
} }
ch->udma_setup = hpt3xx_udma_setup;
if (!noautodma) if (!noautodma)
ch->autodma = 1; ch->autodma = 1;
else else
ch->autodma = 0; ch->autodma = 0;
ch->highmem = 1; ch->highmem = 1;
} else { } else
#endif
{
ch->autodma = 0; ch->autodma = 0;
ch->drives[0].autotune = 1; ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1; ch->drives[1].autotune = 1;
} }
#else
ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1;
ch->autodma = 0;
#endif
} }
static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase) static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase)
...@@ -1390,10 +1365,9 @@ static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase ...@@ -1390,10 +1365,9 @@ static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase
u8 dma_old = inb(dmabase + 2); u8 dma_old = inb(dmabase + 2);
u8 dma_new = dma_old; u8 dma_new = dma_old;
u8 primary = ch->unit ? 0x4b : 0x43; u8 primary = ch->unit ? 0x4b : 0x43;
u8 secondary = primary + 4;
pci_read_config_byte(ch->pci_dev, primary, &masterdma); pci_read_config_byte(ch->pci_dev, primary, &masterdma);
pci_read_config_byte(ch->pci_dev, secondary, &slavedma); pci_read_config_byte(ch->pci_dev, primary + 4, &slavedma);
if (masterdma & 0x30) if (masterdma & 0x30)
dma_new |= 0x20; dma_new |= 0x20;
...@@ -1447,9 +1421,8 @@ int __init init_hpt366(void) ...@@ -1447,9 +1421,8 @@ int __init init_hpt366(void)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(chipsets); ++i) { for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
ata_register_chipset(&chipsets[i]); ata_register_chipset(&chipsets[i]);
}
return 0; return 0;
} }
/*====================================================================== /**** vi:set ts=8 sts=8 sw=8:************************************************
*
A driver for PCMCIA IDE/ATA disk cards A driver for PCMCIA IDE/ATA disk cards
ide_cs.c 1.26 1999/11/16 02:10:49 ide_cs.c 1.26 1999/11/16 02:10:49
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
and other provisions required by the GPL. If you do not delete and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this the provisions above, a recipient may use your version of this
file under either the MPL or the GPL. file under either the MPL or the GPL.
*
======================================================================*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -54,12 +54,12 @@ ...@@ -54,12 +54,12 @@
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#define PCMCIA_DEBUG 100
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG; static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i"); MODULE_PARM(pc_debug, "i");
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version = static const char *version = "ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
#else #else
#define DEBUG(n, args...) #define DEBUG(n, args...)
#endif #endif
...@@ -81,23 +81,23 @@ MODULE_LICENSE("GPL"); ...@@ -81,23 +81,23 @@ MODULE_LICENSE("GPL");
/*====================================================================*/ /*====================================================================*/
static const char ide_major[] = { static const char ide_major[] = {
IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
#ifdef IDE4_MAJOR #ifdef IDE4_MAJOR
IDE4_MAJOR, IDE5_MAJOR IDE4_MAJOR, IDE5_MAJOR
#endif #endif
}; };
typedef struct ide_info_t { typedef struct ide_info_t {
dev_link_t link; dev_link_t link;
int ndev; int ndev;
dev_node_t node; dev_node_t node;
int hd; int hd;
} ide_info_t; } ide_info_t;
static void ide_config(dev_link_t *link); static void ide_config(dev_link_t * link);
static void ide_release(u_long arg); static void ide_release(u_long arg);
static int ide_event(event_t event, int priority, static int ide_event(event_t event, int priority,
event_callback_args_t *args); event_callback_args_t * args);
static dev_info_t dev_info = "ide-cs"; static dev_info_t dev_info = "ide-cs";
...@@ -110,8 +110,11 @@ static dev_link_t *dev_list = NULL; ...@@ -110,8 +110,11 @@ static dev_link_t *dev_list = NULL;
static void cs_error(client_handle_t handle, int func, int ret) static void cs_error(client_handle_t handle, int func, int ret)
{ {
error_info_t err = { func, ret }; error_info_t err = { func, ret };
CardServices(ReportError, handle, &err);
DEBUG(0, "cs_error\n");
CardServices(ReportError, handle, &err);
} }
/*====================================================================== /*======================================================================
...@@ -124,56 +127,58 @@ static void cs_error(client_handle_t handle, int func, int ret) ...@@ -124,56 +127,58 @@ static void cs_error(client_handle_t handle, int func, int ret)
static dev_link_t *ide_attach(void) static dev_link_t *ide_attach(void)
{ {
ide_info_t *info; ide_info_t *info;
dev_link_t *link; dev_link_t *link;
client_reg_t client_reg; client_reg_t client_reg;
int i, ret; int i, ret;
DEBUG(0, "ide_attach()\n"); DEBUG(0, "ide_attach\n");
/* Create new ide device */ /* Create new ide device */
info = kmalloc(sizeof(*info), GFP_KERNEL); info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) return NULL; if (!info)
memset(info, 0, sizeof(*info)); return NULL;
link = &info->link; link->priv = info; memset(info, 0, sizeof(*info));
link = &info->link;
link->release.function = &ide_release; link->priv = info;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->release.function = &ide_release;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->release.data = (u_long) link;
link->io.IOAddrLines = 3; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; link->io.IOAddrLines = 3;
if (irq_list[0] == -1) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo2 = irq_mask; link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
else if (irq_list[0] == -1)
for (i = 0; i < 4; i++) link->irq.IRQInfo2 = irq_mask;
link->irq.IRQInfo2 |= 1 << irq_list[i]; else
link->conf.Attributes = CONF_ENABLE_IRQ; for (i = 0; i < 4; i++)
link->conf.Vcc = 50; link->irq.IRQInfo2 |= 1 << irq_list[i];
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
/* Register with Card Services */ link->conf.IntType = INT_MEMORY_AND_IO;
link->next = dev_list;
dev_list = link; /* Register with Card Services */
client_reg.dev_info = &dev_info; link->next = dev_list;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; dev_list = link;
client_reg.EventMask = client_reg.dev_info = &dev_info;
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | client_reg.EventMask =
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
client_reg.event_handler = &ide_event; CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
client_reg.Version = 0x0210; CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.event_callback_args.client_data = link; client_reg.event_handler = &ide_event;
ret = CardServices(RegisterClient, &link->handle, &client_reg); client_reg.Version = 0x0210;
if (ret != CS_SUCCESS) { client_reg.event_callback_args.client_data = link;
cs_error(link->handle, RegisterClient, ret); ret = CardServices(RegisterClient, &link->handle, &client_reg);
ide_detach(link); if (ret != CS_SUCCESS) {
return NULL; cs_error(link->handle, RegisterClient, ret);
} ide_detach(link);
return NULL;
return link; }
} /* ide_attach */
return link;
} /* ide_attach */
/*====================================================================== /*======================================================================
...@@ -184,34 +189,35 @@ static dev_link_t *ide_attach(void) ...@@ -184,34 +189,35 @@ static dev_link_t *ide_attach(void)
======================================================================*/ ======================================================================*/
static void ide_detach(dev_link_t *link) static void ide_detach(dev_link_t * link)
{ {
dev_link_t **linkp; dev_link_t **linkp;
int ret; int ret;
DEBUG(0, "ide_detach(0x%p)\n", link); DEBUG(0, "ide_detach(0x%p)\n", link);
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
if (*linkp == NULL)
return;
del_timer(&link->release); /* Locate device structure */
if (link->state & DEV_CONFIG) for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
ide_release((u_long)link); if (*linkp == link)
break;
if (link->handle) { if (*linkp == NULL)
ret = CardServices(DeregisterClient, link->handle); return;
if (ret != CS_SUCCESS)
cs_error(link->handle, DeregisterClient, ret); del_timer(&link->release);
} if (link->state & DEV_CONFIG)
ide_release((u_long) link);
/* Unlink, free device structure */
*linkp = link->next; if (link->handle) {
kfree(link->priv); ret = CardServices(DeregisterClient, link->handle);
if (ret != CS_SUCCESS)
} /* ide_detach */ cs_error(link->handle, DeregisterClient, ret);
}
/* Unlink, free device structure */
*linkp = link->next;
kfree(link->priv);
} /* ide_detach */
/*====================================================================== /*======================================================================
...@@ -227,199 +233,224 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed ...@@ -227,199 +233,224 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
#define CFG_CHECK(fn, args...) \ #define CFG_CHECK(fn, args...) \
if (CardServices(fn, args) != 0) goto next_entry if (CardServices(fn, args) != 0) goto next_entry
int idecs_register (int arg1, int arg2, int irq) int idecs_register(int arg1, int arg2, int irq)
{ {
hw_regs_t hw; hw_regs_t hw;
ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
hw.irq = irq;
hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */
return ide_register_hw(&hw); DEBUG(0, "idecs_register\n");
ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2,
NULL);
hw.irq = irq;
hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */
return ide_register_hw(&hw);
} }
void ide_config(dev_link_t *link) void ide_config(dev_link_t * link)
{ {
client_handle_t handle = link->handle; client_handle_t handle = link->handle;
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
tuple_t tuple; tuple_t tuple;
u_short buf[128]; u_short buf[128];
cisparse_t parse; cisparse_t parse;
config_info_t conf; config_info_t conf;
cistpl_cftable_entry_t *cfg = &parse.cftable_entry; cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t dflt = { 0 };
int i, pass, last_ret, last_fn, hd=-1, io_base, ctl_base; int i, pass, last_ret, last_fn, hd = -1, io_base, ctl_base;
DEBUG(0, "ide_config(0x%p)\n", link); DEBUG(0, "ide_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *)buf; tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.TupleOffset = 0;
tuple.Attributes = 0; tuple.TupleDataMax = 255;
tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, handle, &tuple); tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetTupleData, handle, &tuple); CS_CHECK(GetFirstTuple, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse); CS_CHECK(GetTupleData, handle, &tuple);
link->conf.ConfigBase = parse.config.base; CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.Present = parse.config.rmask[0]; link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG; /* Configure card */
link->state |= DEV_CONFIG;
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, handle, &conf); /* Not sure if this is right... look up the current Vcc */
link->conf.Vcc = conf.Vcc; CS_CHECK(GetConfigurationInfo, handle, &conf);
link->conf.Vcc = conf.Vcc;
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; pass = io_base = ctl_base = 0;
tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, handle, &tuple); tuple.Attributes = 0;
while (1) { CS_CHECK(GetFirstTuple, handle, &tuple);
CFG_CHECK(GetTupleData, handle, &tuple); while (1) {
CFG_CHECK(ParseTuple, handle, &tuple, &parse); CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse);
/* Check for matching Vcc, unless we're desperate */
if (!pass) { /* Check for matching Vcc, unless we're desperate */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { if (!pass) {
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
goto next_entry; if (conf.Vcc !=
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { cfg->vcc.param[CISTPL_POWER_VNOM] /
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) 10000)
goto next_entry; goto next_entry;
} } else if (dflt.vcc.
} present & (1 << CISTPL_POWER_VNOM)) {
if (conf.Vcc !=
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) dflt.vcc.param[CISTPL_POWER_VNOM] /
link->conf.Vpp1 = link->conf.Vpp2 = 10000)
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; goto next_entry;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) }
link->conf.Vpp1 = link->conf.Vpp2 = }
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { link->conf.Vpp1 = link->conf.Vpp2 =
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
link->conf.ConfigIndex = cfg->index; else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->io.BasePort1 = io->win[0].base; link->conf.Vpp1 = link->conf.Vpp2 =
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
if (io->nwin == 2) { cistpl_io_t *io =
link->io.NumPorts1 = 8; (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.BasePort2 = io->win[1].base; link->conf.ConfigIndex = cfg->index;
link->io.NumPorts2 = 1; link->io.BasePort1 = io->win[0].base;
CFG_CHECK(RequestIO, link->handle, &link->io); link->io.IOAddrLines =
io_base = link->io.BasePort1; io->flags & CISTPL_IO_LINES_MASK;
ctl_base = link->io.BasePort2; if (!(io->flags & CISTPL_IO_16BIT))
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) { link->io.Attributes1 =
link->io.NumPorts1 = io->win[0].len; IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 0; if (io->nwin == 2) {
CFG_CHECK(RequestIO, link->handle, &link->io); link->io.NumPorts1 = 8;
io_base = link->io.BasePort1; link->io.BasePort2 = io->win[1].base;
ctl_base = link->io.BasePort1+0x0e; link->io.NumPorts2 = 1;
} else goto next_entry; CFG_CHECK(RequestIO, link->handle,
/* If we've got this far, we're done */ &link->io);
break; io_base = link->io.BasePort1;
ctl_base = link->io.BasePort2;
} else if ((io->nwin == 1)
&& (io->win[0].len >= 16)) {
link->io.NumPorts1 = io->win[0].len;
link->io.NumPorts2 = 0;
CFG_CHECK(RequestIO, link->handle,
&link->io);
io_base = link->io.BasePort1;
ctl_base = link->io.BasePort1 + 0x0e;
} else
goto next_entry;
/* If we've got this far, we're done */
break;
}
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
if (pass) {
CS_CHECK(GetNextTuple, handle, &tuple);
} else if (CardServices(GetNextTuple, handle, &tuple) != 0) {
CS_CHECK(GetFirstTuple, handle, &tuple);
memset(&dflt, 0, sizeof(dflt));
pass++;
}
} }
next_entry: CS_CHECK(RequestIRQ, handle, &link->irq);
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; CS_CHECK(RequestConfiguration, handle, &link->conf);
if (pass) {
CS_CHECK(GetNextTuple, handle, &tuple); /* deal with brain dead IDE resource management */
} else if (CardServices(GetNextTuple, handle, &tuple) != 0) { release_region(link->io.BasePort1, link->io.NumPorts1);
CS_CHECK(GetFirstTuple, handle, &tuple); if (link->io.NumPorts2)
memset(&dflt, 0, sizeof(dflt)); release_region(link->io.BasePort2, link->io.NumPorts2);
pass++;
/* retry registration in case device is still spinning up */
for (i = 0; i < 10; i++) {
if (ctl_base)
outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */
hd = idecs_register(io_base, ctl_base,
link->irq.AssignedIRQ);
if (hd >= 0)
break;
if (link->io.NumPorts1 == 0x20) {
if (ctl_base)
outb(0x02, ctl_base + 0x10);
hd = idecs_register(io_base + 0x10,
ctl_base + 0x10,
link->irq.AssignedIRQ);
if (hd >= 0) {
io_base += 0x10;
ctl_base += 0x10;
break;
}
}
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ / 10);
} }
}
if (hd < 0) {
CS_CHECK(RequestIRQ, handle, &link->irq); printk(KERN_NOTICE
CS_CHECK(RequestConfiguration, handle, &link->conf); "ide_cs: ide_register() at 0x%03x & 0x%03x"
", irq %u failed\n", io_base, ctl_base,
/* deal with brain dead IDE resource management */ link->irq.AssignedIRQ);
release_region(link->io.BasePort1, link->io.NumPorts1); goto failed;
if (link->io.NumPorts2)
release_region(link->io.BasePort2, link->io.NumPorts2);
/* retry registration in case device is still spinning up */
for (i = 0; i < 10; i++) {
if (ctl_base)
outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */
hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
if (hd >= 0) break;
if (link->io.NumPorts1 == 0x20) {
if (ctl_base)
outb(0x02, ctl_base+0x10);
hd = idecs_register(io_base+0x10, ctl_base+0x10,
link->irq.AssignedIRQ);
if (hd >= 0) {
io_base += 0x10; ctl_base += 0x10;
break;
}
} }
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/10); MOD_INC_USE_COUNT;
} info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
if (hd < 0) { info->node.major = ide_major[hd];
printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x" info->node.minor = 0;
", irq %u failed\n", io_base, ctl_base, info->hd = hd;
link->irq.AssignedIRQ); link->dev = &info->node;
goto failed; printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
} info->node.dev_name, link->conf.Vcc / 10,
link->conf.Vcc % 10, link->conf.Vpp1 / 10,
MOD_INC_USE_COUNT; link->conf.Vpp1 % 10);
info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2)); link->state &= ~DEV_CONFIG_PENDING;
info->node.major = ide_major[hd]; return;
info->node.minor = 0;
info->hd = hd; cs_failed:
link->dev = &info->node; cs_error(link->handle, last_fn, last_ret);
printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", failed:
info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10, ide_release((u_long) link);
link->conf.Vpp1/10, link->conf.Vpp1%10);
} /* ide_config */
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
ide_release((u_long)link);
} /* ide_config */
/*====================================================================== /*======================================================================
After a card is removed, ide_release() will unregister the net After a card is removed, ide_release() will unregister the net
device, and release the PCMCIA configuration. If the device is device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed. still open, this will be postponed until it is closed.
======================================================================*/ ======================================================================*/
void ide_release(u_long arg) void ide_release(u_long arg)
{ {
dev_link_t *link = (dev_link_t *)arg; dev_link_t *link = (dev_link_t *) arg;
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
DEBUG(0, "ide_release(0x%p)\n", link); DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) { if (info->ndev) {
ide_unregister(&ide_hwifs[info->hd]); ide_unregister(&ide_hwifs[info->hd]);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs"); request_region(link->io.BasePort1, link->io.NumPorts1, "ide-cs");
if (link->io.NumPorts2) if (link->io.NumPorts2)
request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs"); request_region(link->io.BasePort2, link->io.NumPorts2,
"ide-cs");
info->ndev = 0;
link->dev = NULL; info->ndev = 0;
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIRQ, link->handle, &link->irq); CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
link->state &= ~DEV_CONFIG;
} /* ide_release */
} /* ide_release */
/*====================================================================== /*======================================================================
...@@ -427,66 +458,67 @@ void ide_release(u_long arg) ...@@ -427,66 +458,67 @@ void ide_release(u_long arg)
stuff to run after an event is received. A CARD_REMOVAL event stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the ide drivers from also sets some flags to discourage the ide drivers from
talking to the ports. talking to the ports.
======================================================================*/ ======================================================================*/
int ide_event(event_t event, int priority, int ide_event(event_t event, int priority, event_callback_args_t * args)
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
DEBUG(1, "ide_event(0x%06x)\n", event); DEBUG(1, "ide_event(0x%06x)\n", event);
switch (event) { switch (event) {
case CS_EVENT_CARD_REMOVAL: case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT; link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
mod_timer(&link->release, jiffies + HZ/20); mod_timer(&link->release, jiffies + HZ / 20);
break; break;
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link); ide_config(link);
break; break;
case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND; link->state |= DEV_SUSPEND;
/* Fall through... */ /* Fall through... */
case CS_EVENT_RESET_PHYSICAL: case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseConfiguration, link->handle);
break; break;
case CS_EVENT_PM_RESUME: case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND; link->state &= ~DEV_SUSPEND;
/* Fall through... */ /* Fall through... */
case CS_EVENT_CARD_RESET: case CS_EVENT_CARD_RESET:
if (DEV_OK(link)) if (DEV_OK(link))
CardServices(RequestConfiguration, link->handle, &link->conf); CardServices(RequestConfiguration, link->handle,
break; &link->conf);
} break;
return 0; }
} /* ide_event */ return 0;
} /* ide_event */
/*====================================================================*/ /*====================================================================*/
static int __init init_ide_cs(void) static int __init init_ide_cs(void)
{ {
servinfo_t serv; servinfo_t serv;
DEBUG(0, "%s\n", version); DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv); CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) { if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "ide_cs: Card Services release " printk(KERN_NOTICE "ide_cs: Card Services release "
"does not match!\n"); "does not match!\n");
return -1; return -1;
} }
register_pccard_driver(&dev_info, &ide_attach, &ide_detach); register_pccard_driver(&dev_info, &ide_attach, &ide_detach);
return 0;
return 0;
} }
static void __exit exit_ide_cs(void) static void __exit exit_ide_cs(void)
{ {
DEBUG(0, "ide_cs: unloading\n"); DEBUG(0, "ide_cs: unloading\n");
unregister_pccard_driver(&dev_info); unregister_pccard_driver(&dev_info);
while (dev_list != NULL) while (dev_list != NULL)
ide_detach(dev_list); ide_detach(dev_list);
} }
module_init(init_ide_cs); module_init(init_ide_cs);
......
...@@ -176,6 +176,9 @@ int drive_is_ready(struct ata_device *drive) ...@@ -176,6 +176,9 @@ int drive_is_ready(struct ata_device *drive)
return 1; /* drive ready: *might* be interrupting */ return 1; /* drive ready: *might* be interrupting */
} }
/*
* FIXME: Channel lock should be held on entry.
*/
ide_startstop_t ata_taskfile(struct ata_device *drive, ide_startstop_t ata_taskfile(struct ata_device *drive,
struct ata_taskfile *ar, struct request *rq) struct ata_taskfile *ar, struct request *rq)
{ {
......
...@@ -325,7 +325,6 @@ void ide_driver_module(void) ...@@ -325,7 +325,6 @@ void ide_driver_module(void)
int i; int i;
/* Don't reinit the probe if there is already one channel detected. */ /* Don't reinit the probe if there is already one channel detected. */
for (i = 0; i < MAX_HWIFS; ++i) { for (i = 0; i < MAX_HWIFS; ++i) {
if (ide_hwifs[i].present) if (ide_hwifs[i].present)
goto revalidate; goto revalidate;
...@@ -565,33 +564,12 @@ static int subdriver_match(struct ata_channel *channel, struct ata_operations *o ...@@ -565,33 +564,12 @@ static int subdriver_match(struct ata_channel *channel, struct ata_operations *o
if (drive->present && !drive->driver) { if (drive->present && !drive->driver) {
(*ops->attach)(drive); (*ops->attach)(drive);
if (drive->driver != NULL) if (drive->driver != NULL)
count++; ++count;
} }
} }
return count; return count;
} }
static struct ata_operations * subdriver_iterator(struct ata_operations *prev)
{
struct ata_operations *tmp;
unsigned long flags;
spin_lock_irqsave(&ata_drivers_lock, flags);
/* Restart from beginning if current ata_operations was deallocated,
or if prev is NULL. */
for(tmp = ata_drivers; tmp != prev && tmp; tmp = tmp->next);
if (!tmp)
tmp = ata_drivers;
else
tmp = tmp->next;
spin_unlock_irqrestore(&ata_drivers_lock, flags);
return tmp;
}
/* /*
* Register an IDE interface, specifing exactly the registers etc * Register an IDE interface, specifing exactly the registers etc
* Set initializing=1 iff calling before probes have taken place. * Set initializing=1 iff calling before probes have taken place.
...@@ -601,7 +579,6 @@ int ide_register_hw(hw_regs_t *hw) ...@@ -601,7 +579,6 @@ int ide_register_hw(hw_regs_t *hw)
int h; int h;
int retry = 1; int retry = 1;
struct ata_channel *ch; struct ata_channel *ch;
struct ata_operations *subdriver;
do { do {
for (h = 0; h < MAX_HWIFS; ++h) { for (h = 0; h < MAX_HWIFS; ++h) {
...@@ -639,12 +616,20 @@ int ide_register_hw(hw_regs_t *hw) ...@@ -639,12 +616,20 @@ int ide_register_hw(hw_regs_t *hw)
} }
/* Look up whatever there is a subdriver, which will serve this /* Look up whatever there is a subdriver, which will serve this
* device. * device and execute the attach method it is providing.
*/ */
subdriver = NULL; {
while ((subdriver = subdriver_iterator(subdriver))) { struct ata_operations *tmp;
if (subdriver_match(ch, subdriver) > 0) unsigned long flags;
break;
struct ata_operations *sd = NULL;
spin_lock_irqsave(&ata_drivers_lock, flags);
for(tmp = ata_drivers; tmp; tmp = tmp->next) {
if (subdriver_match(ch, tmp) > 0)
break;
}
spin_unlock_irqrestore(&ata_drivers_lock, flags);
} }
return (initializing || ch->present) ? h : -1; return (initializing || ch->present) ? h : -1;
......
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
* linux/drivers/ide/pdc202xx.c Version 0.30 May. 28, 2002 * linux/drivers/ide/pdc202xx.c Version 0.30 May. 28, 2002
* *
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Bartlomiej Zolnierkiewicz
*
* Portions Copyright (C) 1999 Promise Technology, Inc.
* Author: Frank Tiernan (frankt@promise.com)
*
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
* *
* Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
...@@ -24,12 +29,6 @@ ...@@ -24,12 +29,6 @@
* *
*/ */
/*
* Portions Copyright (C) 1999 Promise Technology, Inc.
* Author: Frank Tiernan (frankt@promise.com)
* Released under terms of General Public License
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -61,9 +60,10 @@ ...@@ -61,9 +60,10 @@
#define IORDY_EN 0x20 /* PIO: IOREADY */ #define IORDY_EN 0x20 /* PIO: IOREADY */
#define PREFETCH_EN 0x10 /* PIO: PREFETCH */ #define PREFETCH_EN 0x10 /* PIO: PREFETCH */
#define PDC_CLK 0x11
#define PDC_CLOCK(high_16) IN_BYTE(high_16 + 0x11) #define PDC_PRIMARY 0x1a
#define UDMA_SPEED_FLAG(high_16) IN_BYTE(high_16 + 0x001f) #define PDC_SECONDARY 0x1b
#define PDC_UDMA 0x1f
#if PDC202XX_DECODE_REGISTER_INFO #if PDC202XX_DECODE_REGISTER_INFO
...@@ -78,23 +78,12 @@ static struct pdc_bit_messages pdc_reg_A[] = { ...@@ -78,23 +78,12 @@ static struct pdc_bit_messages pdc_reg_A[] = {
{ 0x20, "IORDY_EN" }, { 0x20, "IORDY_EN" },
{ 0x10, "PREFETCH_EN" }, { 0x10, "PREFETCH_EN" },
/* PA3-PA0 - PIO "A" timing */ /* PA3-PA0 - PIO "A" timing */
{ 0x08, "PA3" },
{ 0x04, "PA2" },
{ 0x02, "PA1" },
{ 0x01, "PA0" }
}; };
static struct pdc_bit_messages pdc_reg_B[] = { static struct pdc_bit_messages pdc_reg_B[] = {
/* MB2-MB0 - DMA "B" timing */ /* MB2-MB0 - DMA "B" timing */
{ 0x80, "MB2" },
{ 0x40, "MB1" },
{ 0x20, "MB0" },
{ 0x10, "PIO_FORCED/PB4" }, /* PIO_FORCE 1:0 */ { 0x10, "PIO_FORCED/PB4" }, /* PIO_FORCE 1:0 */
/* PB3-PB0 - PIO "B" timing */ /* PB3-PB0 - PIO "B" timing */
{ 0x08, "PB3" }, /* PIO flow Control mode */
{ 0x04, "PB2" }, /* PIO 4 */
{ 0x02, "PB1" }, /* PIO 3 half */
{ 0x01, "PB0" } /* PIO 3 other half */
}; };
static struct pdc_bit_messages pdc_reg_C[] = { static struct pdc_bit_messages pdc_reg_C[] = {
...@@ -103,10 +92,6 @@ static struct pdc_bit_messages pdc_reg_C[] = { ...@@ -103,10 +92,6 @@ static struct pdc_bit_messages pdc_reg_C[] = {
{ 0x20, "DMAR_EN" }, { 0x20, "DMAR_EN" },
{ 0x10, "DMAW_EN" }, { 0x10, "DMAW_EN" },
/* MC3-MC0 - DMA "C" timing */ /* MC3-MC0 - DMA "C" timing */
{ 0x08, "MC3" },
{ 0x04, "MC2" },
{ 0x02, "MC1" },
{ 0x01, "MC0" }
}; };
static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
...@@ -115,7 +100,7 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) ...@@ -115,7 +100,7 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
printk(KERN_DEBUG " { "); printk(KERN_DEBUG " { ");
for (i = 0; i < 8; i++, msgs++) for (i = 0; i < ARRAY_SIZE(msgs); i++, msgs++)
if (bits & msgs->mask) if (bits & msgs->mask)
printk(KERN_DEBUG "%s ", msgs->msg); printk(KERN_DEBUG "%s ", msgs->msg);
...@@ -123,13 +108,6 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) ...@@ -123,13 +108,6 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
} }
#endif /* PDC202XX_DECODE_REGISTER_INFO */ #endif /* PDC202XX_DECODE_REGISTER_INFO */
static inline int init_high_16 (struct pci_dev *dev)
{
return pci_resource_start(dev, 4);
}
int check_in_drive_lists(struct ata_device *drive) int check_in_drive_lists(struct ata_device *drive)
{ {
static const char *pdc_quirk_drives[] = { static const char *pdc_quirk_drives[] = {
...@@ -179,14 +157,11 @@ static int pdc202xx_ratemask(struct ata_device *drive) ...@@ -179,14 +157,11 @@ static int pdc202xx_ratemask(struct ata_device *drive)
static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
{ {
struct ata_channel *hwif = drive->channel; struct pci_dev *dev = drive->channel->pci_dev;
struct pci_dev *dev = hwif->pci_dev; u32 drive_conf;
u8 drive_pci, AP, BP, CP, DP, TA = 0, TB, TC = 0;
unsigned int drive_conf;
byte drive_pci, AP, BP, CP;
byte TA = 0, TB = 0, TC = 0;
if (drive->dn > 3) if (drive->dn > 3) /* FIXME: remove this --bkz */
return -1; return -1;
drive_pci = 0x60 + (drive->dn << 2); drive_pci = 0x60 + (drive->dn << 2);
...@@ -195,37 +170,12 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) ...@@ -195,37 +170,12 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
return -1; return -1;
pci_read_config_dword(dev, drive_pci, &drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf);
pci_read_config_byte(dev, (drive_pci), &AP); pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP); pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP); pci_read_config_byte(dev, drive_pci + 2, &CP);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0) {
if ((BP & 0xF0) && (CP & 0x0F)) {
/* clear DMA modes of upper 842 bits of B Register */
/* clear PIO forced mode upper 1 bit of B Register */
pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0);
/* clear DMA modes of lower 8421 bits of C Register */
pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F);
}
} else
#endif /* CONFIG_BLK_DEV_IDEDMA */
{
if ((AP & 0x0F) || (BP & 0x07)) {
/* clear PIO modes of lower 8421 bits of A Register */
pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
/* clear PIO modes of lower 421 bits of B Register */
pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
}
}
pci_read_config_byte(dev, (drive_pci), &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
switch(speed) { switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
/* case XFER_UDMA_6: */
case XFER_UDMA_5: case XFER_UDMA_5:
case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; case XFER_UDMA_4: TB = 0x20; TC = 0x01; break;
case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; case XFER_UDMA_3: TB = 0x40; TC = 0x02; break;
...@@ -249,20 +199,20 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) ...@@ -249,20 +199,20 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0) { if (speed >= XFER_SW_DMA_0) {
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); pci_write_config_byte(dev, drive_pci + 1, (BP & ~0xf0) | TB);
pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); pci_write_config_byte(dev, drive_pci + 2, (CP & ~0x0f) | TC);
} else } else
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
{ {
pci_write_config_byte(dev, (drive_pci), AP|TA); pci_write_config_byte(dev, drive_pci, (AP & ~0x0f) | TA);
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); pci_write_config_byte(dev, drive_pci + 1, (BP & ~0x07) | TB);
} }
#if PDC202XX_DECODE_REGISTER_INFO #if PDC202XX_DECODE_REGISTER_INFO
pci_read_config_byte(dev, (drive_pci), &AP); pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP); pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP); pci_read_config_byte(dev, drive_pci + 2, &CP);
pci_read_config_byte(dev, (drive_pci)|0x03, &DP); pci_read_config_byte(dev, drive_pci + 3, &DP);
printk(KERN_DEBUG "AP(%x): PIO(A) = %d\n", AP, AP & 0x0f); printk(KERN_DEBUG "AP(%x): PIO(A) = %d\n", AP, AP & 0x0f);
pdc_dump_bits(pdc_reg_A, AP); pdc_dump_bits(pdc_reg_A, AP);
...@@ -298,7 +248,6 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) ...@@ -298,7 +248,6 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
OUT_BYTE(value, reg); \ OUT_BYTE(value, reg); \
mdelay(delay); mdelay(delay);
static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed) static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed)
{ {
struct ata_channel *hwif = drive->channel; struct ata_channel *hwif = drive->channel;
...@@ -306,7 +255,7 @@ static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed) ...@@ -306,7 +255,7 @@ static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed)
unsigned long indexreg = (hwif->dma_base + 1); unsigned long indexreg = (hwif->dma_base + 1);
unsigned long datareg = (hwif->dma_base + 3); unsigned long datareg = (hwif->dma_base + 3);
#else #else
unsigned long high_16 = init_high_16(hwif->pci_dev); u32 high_16 = pci_resource_start(hwif->pci_dev, 4);
unsigned long indexreg = high_16 + (hwif->unit ? 0x09 : 0x01); unsigned long indexreg = high_16 + (hwif->unit ? 0x09 : 0x01);
unsigned long datareg = (indexreg + 2); unsigned long datareg = (indexreg + 2);
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
...@@ -431,23 +380,19 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma) ...@@ -431,23 +380,19 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
struct ata_channel *hwif = drive->channel; struct ata_channel *hwif = drive->channel;
struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id; struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id;
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
unsigned long high_16 = init_high_16(dev); u32 high_16 = pci_resource_start(dev, 4);
unsigned long dma_base = hwif->dma_base; u32 dma_base = hwif->dma_base;
unsigned long indexreg = dma_base + 1; u32 indexreg = dma_base + 1;
unsigned long datareg = dma_base + 3; u32 datareg = dma_base + 3;
byte adj = (drive->dn%2) ? 0x08 : 0x00; byte adj = (drive->dn%2) ? 0x08 : 0x00;
byte jumpbit = 0; u8 jumpbit;
unsigned int drive_conf; u32 drive_conf;
byte drive_pci = 0, AP, tmp, mode = -1; u8 drive_pci = 0, AP, tmp, mode = -1;
byte CLKSPD = 0; u8 CLKSPD, mask = hwif->unit ? 0x08 : 0x02;
/* primary - second bit, secondary - fourth bit */
byte mask = hwif->unit ? 0x08 : 0x02;
int map; int map;
byte needs_80w = ((id->dma_ultra & 0x0008) || /* UDMA 3, 4, 5 and 6 */
(id->dma_ultra & 0x0010) || u8 needs_80w = (id->dma_ultra & 0x0078);
(id->dma_ultra & 0x0020) ||
(id->dma_ultra & 0x0040));
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_PROMISE_20267:
...@@ -456,52 +401,44 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma) ...@@ -456,52 +401,44 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20246:
jumpbit = 0; jumpbit = 0;
break; break;
default: /* chipsets newer then 20268 */ default: /* chipsets newer then 20267 */
jumpbit = 1; jumpbit = 1;
break; break;
} }
if (!jumpbit) /* FIXME: this check is wrong for 20246 --bkz */
CLKSPD = PDC_CLOCK(high_16); /* */
if (needs_80w && !hwif->udma_four) {
printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name);
printk(KERN_INFO "%s: reduced to UDMA(33) mode.\n", drive->name);
}
if (jumpbit)
goto chipset_is_set;
/* /*
* Set the control register to use the 66Mhz system * Set the control register to use the 66Mhz system
* clock for UDMA 3/4 mode operation. If one drive on * clock for UDMA 3/4 mode operations. If one drive on
* a channel is U66 capable but the other isn't we * a channel is U66 capable but the other isn't we
* fall back to U33 mode. The BIOS INT 13 hooks turn * fall back to U33 mode. The BIOS INT 13 hooks turn
* the clock on then off for each read/write issued. I don't * the clock on then off for each read/write issued.
* do that here because it would require modifying the * We can do the same in device specific udma_start/stop()
* kernel, seperating the fop routines from the kernel or * routines or better try to readjust timings.
* somehow hooking the fops calls. It may also be possible to *
* leave the 66Mhz clock on and readjust the timing * FIXME: move this to pdc202xx_tuneproc()
* parameters. * right now you can't downgrade from U66 to U33 --bkz
*/ */
if (needs_80w) { if (needs_80w) {
/* FIXME: this check is wrong for 20246 --bkz */ CLKSPD = IN_BYTE(high_16 + PDC_CLK);
if (!hwif->udma_four) { /* check cable and mate (must be at least udma3 capable) */
printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name); if (!hwif->udma_four ||
printk(KERN_WARNING "%s: reduced to UDMA(33) mode.\n", drive->name); !mate_id || !(mate_id->dma_ultra & 0x0078))
if (!jumpbit) OUT_BYTE(CLKSPD & ~mask, high_16 + PDC_CLK);
OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); else
} /* cable ok, mate ok or single drive */
if (!jumpbit) { OUT_BYTE(CLKSPD | mask, high_16 + PDC_CLK);
if (mate_id) { /* check if mate is at least udma3 */
if ((mate_id->dma_ultra & 0x0040) ||
(mate_id->dma_ultra & 0x0020) ||
(mate_id->dma_ultra & 0x0010) ||
(mate_id->dma_ultra & 0x0008)) {
OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
} else {
OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
}
} else { /* single drive */
OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
}
}
} }
if (jumpbit)
goto chipset_is_set;
if (drive->dn > 3) /* FIXME: remove this --bkz */ if (drive->dn > 3) /* FIXME: remove this --bkz */
return 0; return 0;
...@@ -560,7 +497,7 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma) ...@@ -560,7 +497,7 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
return 0; return 0;
} }
return !(hwif->speedproc(drive, mode)); return !hwif->speedproc(drive, mode);
} }
static int pdc202xx_udma_setup(struct ata_device *drive) static int pdc202xx_udma_setup(struct ata_device *drive)
...@@ -614,14 +551,14 @@ static int pdc202xx_udma_setup(struct ata_device *drive) ...@@ -614,14 +551,14 @@ static int pdc202xx_udma_setup(struct ata_device *drive)
static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq) static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned long high_16 = init_high_16(ch->pci_dev); u32 high_16 = pci_resource_start(ch->pci_dev, 4);
unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00); unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
if (drive->addressing) { if (drive->addressing) {
unsigned long word_count = 0; unsigned long word_count = 0;
u8 clock = PDC_CLOCK(high_16); u8 clock = IN_BYTE(high_16 + PDC_CLK);
outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + 0x11); outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + PDC_CLK);
word_count = (rq->nr_sectors << 8); word_count = (rq->nr_sectors << 8);
word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000; word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
outl(word_count, atapi_reg); outl(word_count, atapi_reg);
...@@ -640,15 +577,15 @@ static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq) ...@@ -640,15 +577,15 @@ static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
int pdc202xx_udma_stop(struct ata_device *drive) int pdc202xx_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned long high_16 = init_high_16(ch->pci_dev); u32 high_16 = pci_resource_start(ch->pci_dev, 4);
unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00); unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
u8 dma_stat, clock; u8 dma_stat, clock;
if (drive->addressing) { if (drive->addressing) {
outl(0, atapi_reg); /* zero out extra */ outl(0, atapi_reg); /* zero out extra */
clock = PDC_CLOCK(high_16); clock = IN_BYTE(high_16 + PDC_CLK);
OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11); OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK);
} }
drive->waiting_for_dma = 0; drive->waiting_for_dma = 0;
...@@ -660,16 +597,6 @@ int pdc202xx_udma_stop(struct ata_device *drive) ...@@ -660,16 +597,6 @@ int pdc202xx_udma_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 pdc202xx_udma_irq_status(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
u8 dma_stat;
dma_stat = IN_BYTE(ch->dma_base + 2);
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
}
static void pdc202xx_bug(struct ata_device *drive) static void pdc202xx_bug(struct ata_device *drive)
{ {
if (!drive->channel->resetproc) if (!drive->channel->resetproc)
...@@ -690,55 +617,51 @@ void pdc202xx_new_reset(struct ata_device *drive) ...@@ -690,55 +617,51 @@ void pdc202xx_new_reset(struct ata_device *drive)
drive->channel->unit ? "Secondary" : "Primary"); drive->channel->unit ? "Secondary" : "Primary");
} }
void pdc202xx_reset(struct ata_device *drive) /*
* software host reset
*
* BIOS will set UDMA timing on if the drive supports it.
* The user may then want to turn it off. A bug is that
* that device cannot handle a downgrade in timing from
* UDMA to DMA. Disk accesses after issuing a set
* feature command will result in errors.
*
* A software reset leaves the timing registers intact,
* but resets the drives on both channels.
*/
static void pdc202xx_reset_host(struct pci_dev *dev)
{ {
unsigned long high_16 = init_high_16(drive->channel->pci_dev); u32 high_16 = pci_resource_start(dev, 4);
byte udma_speed_flag = UDMA_SPEED_FLAG(high_16); u8 burst = IN_BYTE(high_16 + PDC_UDMA);
set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100); set_reg_and_wait(burst | 0x10, high_16 + PDC_UDMA, 100);
set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000); /* 2 seconds ?! */ /* FIXME: 2 seconds ?! */
printk("PDC202XX: %s channel reset.\n", set_reg_and_wait(burst & ~0x10, high_16 + PDC_UDMA, 2000);
drive->channel->unit ? "Secondary" : "Primary"); printk(KERN_INFO "%s: device reseted.\n", dev->name);
}
void pdc202xx_reset(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
printk(KERN_INFO "%s: channel needs reset.\n", ch->name);
pdc202xx_reset_host(ch->pci_dev);
} }
/* FIXME: should be splited for old & new chipsets --bkz */
static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev) static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev)
{ {
unsigned long high_16 = init_high_16(dev); u32 high_16 = pci_resource_start(dev, 4);
byte udma_speed_flag = UDMA_SPEED_FLAG(high_16); u8 burst = IN_BYTE(high_16 + PDC_UDMA);
byte primary_mode = IN_BYTE(high_16 + 0x001a);
byte secondary_mode = IN_BYTE(high_16 + 0x001b);
byte newchip = 0;
if (dev->resource[PCI_ROM_RESOURCE].start) { if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
printk("%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start); printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
} }
switch (dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268:
newchip = 1;
break;
case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265: case PCI_DEVICE_ID_PROMISE_20265:
case PCI_DEVICE_ID_PROMISE_20262: case PCI_DEVICE_ID_PROMISE_20262:
/* pdc202xx_reset_host(dev);
* software reset - this is required because the BIOS
* will set UDMA timing on if the drive supports it.
* The user may want to turn udma off. A bug is that
* that device cannot handle a downgrade in timing from
* UDMA to DMA. Disk accesses after issuing a set
* feature command will result in errors.
*
* A software reset leaves the timing registers intact,
* but resets the drives.
*/
set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100);
set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000); /* 2 seconds ?! */
break; break;
default: default:
/* FIXME: only checked for 20246 - is this right?, /* FIXME: only checked for 20246 - is this right?,
...@@ -755,46 +678,44 @@ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev) ...@@ -755,46 +678,44 @@ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev)
break; break;
} }
if (newchip)
goto fttk_tx_series;
printk("%s: (U)DMA Burst Bit %sABLED " \
"Primary %s Mode " \
"Secondary %s Mode.\n",
dev->name,
(udma_speed_flag & 1) ? "EN" : "DIS",
(primary_mode & 1) ? "MASTER" : "PCI",
(secondary_mode & 1) ? "MASTER" : "PCI" );
#ifdef CONFIG_PDC202XX_BURST #ifdef CONFIG_PDC202XX_BURST
if (!(udma_speed_flag & 1)) { if (!(burst & 1)) {
printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", dev->name, udma_speed_flag, (udma_speed_flag|1)); printk(KERN_INFO "%s: forcing (U)DMA BURST.\n", dev->name);
OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f); OUT_BYTE(burst | 1, high_16 + PDC_UDMA);
printk("%sCTIVE\n", (UDMA_SPEED_FLAG(high_16) & 1) ? "A" : "INA");
} }
#endif /* CONFIG_PDC202XX_BURST */ #endif
printk(KERN_INFO "%s: (U)DMA BURST %sabled, "
"primary %s mode, secondary %s mode.\n",
dev->name, (burst & 1) ? "en" : "dis",
(IN_BYTE(high_16 + PDC_PRIMARY) & 1) ? "MASTER" : "PCI",
(IN_BYTE(high_16 + PDC_SECONDARY) & 1) ? "MASTER" : "PCI" );
fttk_tx_series:
return dev->irq; return dev->irq;
} }
static unsigned int __init ata66_pdc202xx(struct ata_channel *hwif) /* chipsets newer then 20267 */
static unsigned int __init pdc202xx_tx_init_chipset(struct pci_dev *dev)
{ {
unsigned short mask = (hwif->unit) ? (1<<11) : (1<<10); if (dev->resource[PCI_ROM_RESOURCE].start) {
unsigned short CIS; pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
printk(KERN_INFO "%s: ROM enabled at 0x%08lx.\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R:
OUT_BYTE(0x0b, (hwif->dma_base + 1));
return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04));
default:
pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
return (!(CIS & mask));
} }
return dev->irq;
}
static unsigned int __init pdc202xx_ata66_check(struct ata_channel *ch)
{
u16 CIS;
pci_read_config_word(ch->pci_dev, 0x50, &CIS);
return !(CIS & (1 << (10 + ch->unit)));
}
/* chipsets newer then 20267 */
static unsigned int __init pdc202xx_tx_ata66_check(struct ata_channel *ch)
{
OUT_BYTE(0x0b, ch->dma_base + 1);
return !(IN_BYTE(ch->dma_base + 3) & 0x04);
} }
static void __init ide_init_pdc202xx(struct ata_channel *hwif) static void __init ide_init_pdc202xx(struct ata_channel *hwif)
...@@ -820,7 +741,6 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif) ...@@ -820,7 +741,6 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif)
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->udma_start = pdc202xx_udma_start; hwif->udma_start = pdc202xx_udma_start;
hwif->udma_stop = pdc202xx_udma_stop; hwif->udma_stop = pdc202xx_udma_stop;
hwif->udma_irq_status = pdc202xx_udma_irq_status;
} }
#endif #endif
/* FIXME: check whether 20246 works with lba48 --bkz */ /* FIXME: check whether 20246 works with lba48 --bkz */
...@@ -867,7 +787,7 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -867,7 +787,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20262, device: PCI_DEVICE_ID_PROMISE_20262,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE #ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
...@@ -880,7 +800,7 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -880,7 +800,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20265, device: PCI_DEVICE_ID_PROMISE_20265,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE #ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
...@@ -895,7 +815,7 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -895,7 +815,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20267, device: PCI_DEVICE_ID_PROMISE_20267,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE #ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
...@@ -907,8 +827,8 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -907,8 +827,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{ {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268, device: PCI_DEVICE_ID_PROMISE_20268,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_tx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD, bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
...@@ -920,8 +840,8 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -920,8 +840,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{ {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268R, device: PCI_DEVICE_ID_PROMISE_20268R,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_tx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD, bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
...@@ -929,8 +849,8 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -929,8 +849,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{ {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20269, device: PCI_DEVICE_ID_PROMISE_20269,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_tx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD, bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
...@@ -938,8 +858,8 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -938,8 +858,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{ {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20275, device: PCI_DEVICE_ID_PROMISE_20275,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_tx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD, bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
...@@ -947,8 +867,8 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -947,8 +867,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{ {
vendor: PCI_VENDOR_ID_PROMISE, vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20276, device: PCI_DEVICE_ID_PROMISE_20276,
init_chipset: pdc202xx_init_chipset, init_chipset: pdc202xx_tx_init_chipset,
ata66_check: ata66_pdc202xx, ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx, init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD, bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
......
...@@ -613,7 +613,6 @@ extern u8 ata_dump(struct ata_device *, struct request *, const char *); ...@@ -613,7 +613,6 @@ extern u8 ata_dump(struct ata_device *, struct request *, const char *);
extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *); extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *);
extern void ide_fixstring(char *s, const int bytecount, const int byteswap); extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
/* /*
* This routine is called from the partition-table code in genhd.c * This routine is called from the partition-table code in genhd.c
......
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