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 @@
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Note, this driver is not used at all on other systems because
* there the "BIOS" has done all of the following already.
* Due to massive hardware bugs, UltraDMA is only supported
* on the 646U2 and not on the 646U.
* Due to massive hardware bugs, UDMA is not supported on the 646U.
*
* Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be>
* Copyright (C) 1998 David S. Miller <davem@redhat.com>
......@@ -28,10 +27,6 @@
#include "ata-timing.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
#if CMD_DEBUG
......@@ -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.
* 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);
clock_time = 1000000 / system_bus_speed;
......@@ -256,9 +252,7 @@ static int cmd64x_ratemask(struct ata_device *drive)
case 0x07:
case 0x05:
map |= XFER_UDMA;
case 0x03:
case 0x01:
default:
default: /* 0x03, 0x01 */
break;
}
}
......@@ -272,13 +266,12 @@ static int cmd64x_ratemask(struct ata_device *drive)
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;
byte addr_mask = (hwif->unit) ? 0xB2 : 0xA2;
unsigned short timing;
u8 addr_mask = (ch->unit) ? 0xB2 : 0xA2;
u16 timing;
pci_read_config_word(dev, addr_mask, &timing);
pci_read_config_word(ch->pci_dev, addr_mask, &timing);
switch (timing) {
case 0x10c1: return 4;
......@@ -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 pci_dev *dev = hwif->pci_dev;
byte drive_pci;
unsigned short speedt;
u8 drive_pci;
u16 speedt;
switch (drive->dn) {
case 0: drive_pci = 0xA4; break;
......@@ -320,25 +313,23 @@ static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
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;
byte 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;
cmd64x_tuneproc(drive, set_pio);
speed = XFER_PIO_0 + set_pio;
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 pci_dev *dev = hwif->pci_dev;
u8 unit = (drive->select.b.unit & 0x01);
u8 addr_mask = (hwif->unit) ? 0x84 : 0x80;
u8 speed = 0x00;
u8 mode_pci = 0x00;
u8 speed;
u8 mode_pci;
u8 channel_timings = cmd680_taskfile_timing(hwif);
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)
u8 unit = (drive->select.b.unit & 0x01);
u8 pciU = (hwif->unit) ? UDIDETCR1 : UDIDETCR0;
u8 pciD = (hwif->unit) ? BMIDESR1 : BMIDESR0;
u8 regU = 0;
u8 regD = 0;
u8 regU, regD;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return 1;
......@@ -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, pciU, &regU);
/* FIXME: get unit checking out of here --bkz */
switch(speed) {
case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); 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)
#else
switch(speed) {
#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break;
case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break;
case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break;
case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break;
case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break;
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
case XFER_PIO_1:
case XFER_PIO_0:
cmd64x_tuneproc(drive, speed - XFER_PIO_0);
break;
default:
return 1;
}
......@@ -436,12 +428,9 @@ static int cmd680_tune_chipset(struct ata_device *drive, byte speed)
struct pci_dev *dev = hwif->pci_dev;
u8 addr_mask = (hwif->unit) ? 0x84 : 0x80;
u8 unit = (drive->select.b.unit & 0x01);
u8 dma_pci = 0;
u8 udma_pci = 0;
u8 mode_pci = 0;
u8 scsc = 0;
u16 ultra = 0;
u16 multi = 0;
u8 dma_pci, udma_pci;
u8 mode_pci, scsc;
u16 ultra, multi;
pci_read_config_byte(dev, addr_mask, &mode_pci);
pci_read_config_byte(dev, 0x8A, &scsc);
......@@ -515,11 +504,13 @@ speed_break :
multi = 0x2208;
break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd680_tuneproc(drive, 4); break;
case XFER_PIO_3: cmd680_tuneproc(drive, 3); break;
case XFER_PIO_2: cmd680_tuneproc(drive, 2); break;
case XFER_PIO_1: cmd680_tuneproc(drive, 1); break;
case XFER_PIO_0: cmd680_tuneproc(drive, 0); break;
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
case XFER_PIO_1:
case XFER_PIO_0:
cmd680_tuneproc(drive, speed - XFER_PIO_0);
break;
default:
return 1;
}
......@@ -570,7 +561,7 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
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 ata_channel *hwif = drive->channel;
......@@ -627,11 +618,6 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive)
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)
{
struct ata_channel *ch = drive->channel;
......@@ -680,11 +666,10 @@ static int cmd64x_udma_irq_status(struct ata_device *drive)
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
}
static int cmd64x_udma_setup(struct ata_device *drive)
{
return cmd64x_config_drive_for_dma(drive);
}
/*
* ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
* event order for DMA transfers.
*/
static int cmd646_1_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
......@@ -699,14 +684,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive)
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
static int cmd680_busproc(struct ata_device * drive, int state)
......@@ -808,10 +785,7 @@ static unsigned int cmd64x_pci_init(struct pci_dev *dev)
}
printk("\n");
break;
case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_649:
break;
default:
default: /* 648, 649 */
break;
}
......@@ -863,8 +837,8 @@ static unsigned int __init cmd64x_init_chipset(struct pci_dev *dev)
static unsigned int cmd680_ata66(struct ata_channel *hwif)
{
byte ata66 = 0;
byte addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
u8 ata66;
u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66);
return (ata66 & 0x01) ? 1 : 0;
......@@ -872,8 +846,8 @@ static unsigned int cmd680_ata66(struct ata_channel *hwif)
static unsigned int cmd64x_ata66(struct ata_channel *hwif)
{
byte ata66 = 0;
byte mask = (hwif->unit) ? 0x02 : 0x01;
u8 ata66;
u8 mask = (hwif->unit) ? 0x02 : 0x01;
pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
return (ata66 & mask) ? 1 : 0;
......@@ -881,8 +855,7 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif)
static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
if (dev->device == PCI_DEVICE_ID_CMD_680)
if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680)
return cmd680_ata66(hwif);
return cmd64x_ata66(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)
{
struct pci_dev *dev = hwif->pci_dev;
unsigned int class_rev;
u32 class_rev;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
......@@ -903,7 +876,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
hwif->busproc = cmd680_busproc;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base)
hwif->udma_setup = cmd680_udma_setup;
hwif->udma_setup = cmd6xx_udma_setup;
#endif
hwif->resetproc = cmd680_reset;
hwif->speedproc = cmd680_tune_chipset;
......@@ -914,7 +887,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
case PCI_DEVICE_ID_CMD_643:
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->udma_setup = cmd64x_udma_setup;
hwif->udma_setup = cmd6xx_udma_setup;
hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status;
}
......@@ -926,11 +899,10 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
hwif->chipset = ide_cmd646;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->udma_setup = cmd6xx_udma_setup;
if (class_rev == 0x01) {
hwif->udma_setup = cmd646_1_udma_setup;
hwif->udma_stop = cmd646_1_udma_stop;
} else {
hwif->udma_setup = cmd64x_udma_setup;
hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status;
}
......@@ -1007,9 +979,8 @@ int __init init_cmd64x(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
ata_register_chipset(&chipsets[i]);
}
return 0;
}
......@@ -21,12 +21,9 @@
* 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
* 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
* (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
* problem with sound - the BusMaster IDE TimeOut should fixed this
*
......@@ -83,6 +80,9 @@
/* here are the offset definitions for the registers */
#define CY82_IDE_CMDREG 0x04
#define CY82_IDE_ADDRSETUP 0x48
#define CYPRESS_TIMINGS 0x4C
#define CY82_IDE_MASTER_IOR 0x4C
#define CY82_IDE_MASTER_IOW 0x4D
#define CY82_IDE_SLAVE_IOR 0x4E
......@@ -105,19 +105,20 @@
#define CY82C963_MIN_BUS_SPEED 25
#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 {
byte address_time; /* Address setup (clocks) */
byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
u8 address_time; /* Address setup */
/* 0xF0=Active/data, 0x0F=Recovery */
u8 time_16r; /* 16bit IOR */
u8 time_16w; /* 16bit IOW */
u8 time_8; /* 8bit */
} pio_clocks_t;
/*
* calc clocks using bus_speed
* 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;
......@@ -129,7 +130,7 @@ static int calc_clk (int time, int bus_speed)
if (clocks > 0x0F)
clocks = 0x0F;
return clocks;
return (u8)clocks;
}
/*
......@@ -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
*
*/
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;
int clk1, clk2;
......@@ -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,
* so you can play with the idebus=xx parameter
* FIXME: warn about going out of specification --bkz
*/
if (pio > CY82C693_MAX_PIO)
pio = CY82C693_MAX_PIO;
/* let's calc the address setup time clocks */
p_pclk->address_time = (byte)calc_clk(t->setup, system_bus_speed);
/* address setup */
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);
/* calc recovery timing */
clk2 = t->cycle - t->active - t->setup;
clk2 = calc_clk(clk2, system_bus_speed);
/* FIXME: check why not t->cycle - t->active ? --bkz */
/* recovery */
clk2 = calc_clk(t->cycle - t->active - t->setup, 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
* those are all the same, since I don't have other
* timings than those from ata-timing.h
*/
p_pclk->time_16w = p_pclk->time_16r = clk1;
p_pclk->time_16r = (byte)clk1;
p_pclk->time_16w = (byte)clk1;
/* FIXME: ugh... --bkz */
/* what are good values for 8bit ?? */
p_pclk->time_8 = (byte)clk1;
p_pclk->time_8 = clk1;
}
#ifdef CONFIG_BLK_DEV_IDEDMA
......@@ -276,7 +277,9 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio)
struct pci_dev *dev = hwif->pci_dev;
pio_clocks_t pclk;
unsigned int addrCtrl;
u8 ior, iow, bit8;
/* FIXME: probaly broken --bkz */
/* select primary or secondary channel */
if (hwif->index > 0) { /* drive is on the secondary channel */
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)
}
}
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
/* for debug let's show the register values */
if (drive->select.b.unit == 0) {
/*
* get master drive registers
* address setup control register
* is 32 bit !!!
*/
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);
/*
* get address setup control register
* mine master or slave data
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
if (drive->select.b.unit == 0)
addrCtrl &= 0x0F;
else {
addrCtrl &= 0xF0;
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 */
/* first let's calc the pio modes */
......@@ -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 */
/* 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) {
/*
* set master drive
* address setup control register
* is 32 bit !!!
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF);
addrCtrl &= (~0x0F);
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 {
/*
* set slave drive
* address setup control register
* is 32 bit !!!
*/
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF0);
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
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);
#endif /* 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);
#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)
{
#ifdef CY82C693_SETDMA_CLOCK
byte data;
#endif /* CY82C693_SETDMA_CLOCK */
u8 data;
#endif
/* write info about this verion of the driver */
printk (KERN_INFO CY82_VERSION "\n");
......@@ -402,7 +378,7 @@ static unsigned int __init pci_init_cy82c693(struct pci_dev *dev)
#if CY82C693_DEBUG_INFO
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
......
......@@ -5,19 +5,7 @@
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
*
* 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
* ide-pci.c reference:
*
* Since there are two cards that report almost identically,
* the only discernable difference is the values reported in pcicmd.
......@@ -45,53 +33,34 @@
#include "ata-timing.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
static void hpt34x_clear_chipset(struct ata_device *drive)
{
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)
static int hpt34x_tune_chipset(struct ata_device *drive, u8 speed)
{
byte hi_speed, lo_speed;
unsigned int reg1 = 0, tmp1 = 0;
unsigned int reg2 = 0, tmp2 = 0;
SPLIT_BYTE(speed, hi_speed, lo_speed);
if (hi_speed & 7) {
hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
} else {
lo_speed <<= 5;
lo_speed >>= 5;
}
struct pci_dev *dev = drive->channel->pci_dev;
u8 udma = 0, pio = 0;
u32 reg1, reg2, tmp1, tmp2;
if (speed >= XFER_UDMA_0)
udma = 0x01;
else if (speed >= XFER_SW_DMA_0)
udma = 0x10;
else
pio = speed & 7;
pci_read_config_dword(drive->channel->pci_dev, 0x44, &reg1);
pci_read_config_dword(drive->channel->pci_dev, 0x48, &reg2);
tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
tmp2 = ((hi_speed << drive->dn) | reg2);
pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1);
pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2);
pci_read_config_dword(dev, 0x44, &reg1);
pci_read_config_dword(dev, 0x48, &reg2);
tmp1 = (pio << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)));
tmp2 = (udma << drive->dn) | (reg2 & ~(0x11 << drive->dn));
pci_write_config_dword(dev, 0x44, tmp1);
pci_write_config_dword(dev, 0x48, tmp2);
#if HPT343_DEBUG_DRIVE_INFO
printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
" (0x%02x 0x%02x) 0x%04x\n",
drive->name, speed,
drive->dn, reg1, tmp1, reg2, tmp2,
hi_speed, lo_speed, err);
udma, pio, err);
#endif
drive->current_speed = speed;
......@@ -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 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;
......@@ -135,19 +104,9 @@ static void config_chipset_for_pio(struct ata_device *drive)
(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;
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);
(void) hpt34x_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
}
#ifdef CONFIG_BLK_DEV_IDEDMA
......@@ -168,7 +127,6 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
if (mode < XFER_SW_DMA_0)
return 0;
hpt34x_clear_chipset(drive);
return !hpt34x_tune_chipset(drive, mode);
}
......
......@@ -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_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)
{
struct hd_driveid *id = drive->id;
......@@ -515,29 +513,24 @@ static unsigned int hpt_revision(struct pci_dev *dev)
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)
{
struct pci_dev *dev = drive->channel->pci_dev;
u32 rev = hpt_revision(drive->channel->pci_dev);
int map = XFER_UDMA;
if (hpt_min_rev(dev, 8)) { /* HPT374 */
if (rev >= 8) { /* HPT374 */
if (HPT374_ALLOW_ATA133_6)
map |= XFER_UDMA_133;
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)
map |= XFER_UDMA_133;
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)
map |= XFER_UDMA_100;
map |= XFER_UDMA_66;
} else if (hpt_min_rev(dev, 3)) { /* HPT370 */
} else if (rev >= 3) { /* HPT370 */
if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100;
map |= XFER_UDMA_66;
......@@ -600,11 +593,6 @@ static void hpt366_tune_chipset(struct ata_device *drive, u8 speed)
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)
{
u8 regfast = (drive->channel->unit) ? 0x55 : 0x51;
......@@ -674,31 +662,24 @@ static void hpt372_tune_chipset(struct ata_device *drive, u8 speed)
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)
{
struct pci_dev *dev = drive->channel->pci_dev;
u32 rev;
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
return -1;
if (hpt_min_rev(dev, 7)) {
hpt374_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 5)) {
rev = hpt_revision(drive->channel->pci_dev);
if (rev >= 5) {
hpt372_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 3)) {
} else if (rev >= 3) {
hpt370_tune_chipset(drive, speed);
} else if (hpt_min_rev(dev, 2)) {
hpt368_tune_chipset(drive, speed);
} else {
hpt366_tune_chipset(drive, 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)
......@@ -755,13 +736,15 @@ static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive)
{
struct pci_dev *dev = drive->channel->pci_dev;
int map;
u32 rev;
u8 mode;
if (drive->type != ATA_DISK)
return 0;
rev = hpt_revision(drive->channel->pci_dev);
/* FIXME: check SWDMA modes --bkz */
map = hpt3xx_ratemask(drive) | XFER_MWDMA;
mode = ata_timing_mode(drive, map);
......@@ -770,7 +753,7 @@ static int config_chipset_for_dma(struct ata_device *drive)
bad_ata100_5 is for HPT370/370A,
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)) {
/* FIXME: make XFER_UDMA_66/100/133
independent of XFER_UDMA --bkz */
......@@ -779,7 +762,7 @@ static int config_chipset_for_dma(struct ata_device *drive)
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 (drive->id->dma_ultra & 0x0008) {
mode = XFER_UDMA_3;
......@@ -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)) {
map &= ~XFER_UDMA_66;
map |= XFER_UDMA;
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);
return !hpt3xx_tune_chipset(drive, mode);
......@@ -823,7 +806,8 @@ static void hpt3xx_maskproc(struct ata_device *drive)
struct ata_channel *ch = drive->channel;
if (drive->quirk_list) {
if (hpt_min_rev(dev, 3)) {
u32 rev = hpt_revision(dev);
if (rev >= 3) {
u8 reg5a;
pci_read_config_byte(dev, 0x5a, &reg5a);
if ((reg5a & 0x10) >> 4)
......@@ -892,15 +876,16 @@ static int hpt3xx_udma_setup(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;
pci_read_config_byte(drive->channel->pci_dev, 0x50, &reg50h);
pci_read_config_byte(drive->channel->pci_dev, 0x52, &reg52h);
pci_read_config_byte(drive->channel->pci_dev, 0x5a, &reg5ah);
pci_read_config_byte(dev, 0x50, &reg50h);
pci_read_config_byte(dev, 0x52, &reg52h);
pci_read_config_byte(dev, 0x5a, &reg5ah);
printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
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)
......@@ -1127,7 +1112,7 @@ static void __init hpt37x_init(struct pci_dev *dev)
{
int adjust, i;
u16 freq;
u32 pll;
u32 pll, rev = hpt_revision(dev);
u8 reg5bh;
/*
......@@ -1144,9 +1129,9 @@ static void __init hpt37x_init(struct pci_dev *dev)
freq &= 0x1FF;
if (freq < 0x9c) {
pll = F_LOW_PCI_33;
if (hpt_min_rev(dev, 7)) {
if (rev >= 7) {
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;
} else {
dev->sysdata = (void *) thirty_three_base_hpt370;
......@@ -1156,10 +1141,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
pll = F_LOW_PCI_40;
} else if (freq < 0xc8) {
pll = F_LOW_PCI_50;
if (hpt_min_rev(dev, 7)) {
if (rev >= 7) {
// dev->sysdata = (void *) fifty_base_hpt374;
BUG();
} else if (hpt_min_rev(dev, 5)) {
} else if (rev >= 5) {
dev->sysdata = (void *) fifty_base_hpt372;
} else {
dev->sysdata = (void *) fifty_base_hpt370;
......@@ -1167,10 +1152,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
printk("HPT37X: using 50MHz PCI clock\n");
} else {
pll = F_LOW_PCI_66;
if (hpt_min_rev(dev, 7)) {
if (rev >= 7) {
// dev->sysdata = (void *) sixty_six_base_hpt374;
BUG();
} else if (hpt_min_rev(dev, 5)) {
} else if (rev >= 5) {
dev->sysdata = (void *) sixty_six_base_hpt372;
} else {
dev->sysdata = (void *) sixty_six_base_hpt370;
......@@ -1213,10 +1198,10 @@ static void __init hpt37x_init(struct pci_dev *dev)
pci_write_config_dword(dev, 0x5c,
pll & ~0x100);
pci_write_config_byte(dev, 0x5b, 0x21);
if (hpt_min_rev(dev, 7)) {
if (rev >= 7) {
// dev->sysdata = (void *) fifty_base_hpt374;
BUG();
} else if (hpt_min_rev(dev, 5)) {
} else if (rev >= 5) {
dev->sysdata = (void *) fifty_base_hpt372;
} else {
dev->sysdata = (void *) fifty_base_hpt370;
......@@ -1269,6 +1254,7 @@ static void __init hpt366_init(struct pci_dev *dev)
static unsigned int __init hpt366_init_chipset(struct pci_dev *dev)
{
u32 rev = hpt_revision(dev);
u8 test;
if (dev->resource[PCI_ROM_RESOURCE].start)
......@@ -1290,7 +1276,7 @@ static unsigned int __init hpt366_init_chipset(struct pci_dev *dev)
if (test != 0x08)
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
if (hpt_min_rev(dev, 3))
if (rev >= 3)
hpt37x_init(dev);
else
hpt366_init(dev);
......@@ -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)
{
struct pci_dev *dev = ch->pci_dev;
u32 rev = hpt_revision(dev);
ch->tuneproc = hpt3xx_tune_drive;
ch->speedproc = hpt3xx_tune_chipset;
......@@ -1330,7 +1317,7 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (ch->dma_base) {
if (hpt_min_rev(dev, 3)) {
if (rev >= 3) {
u8 reg5ah;
pci_read_config_byte(dev, 0x5a, &reg5ah);
if (reg5ah & 0x10) /* interrupt force enable */
......@@ -1343,45 +1330,33 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
ch->resetproc = hpt3xx_reset;
ch->busproc = hpt370_busproc;
if (hpt_min_rev(dev, 7)) {
if (rev >= 5) {
ch->udma_stop = hpt374_udma_stop;
ch->udma_setup = hpt3xx_udma_setup;
} 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)) {
} else { /* rev >= 3 */
ch->udma_start = hpt370_udma_start;
ch->udma_stop = hpt370_udma_stop;
ch->udma_timeout = hpt370_udma_timeout;
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 {
ch->udma_irq_lost = hpt366_udma_irq_lost;
// ch->resetproc = hpt3xx_reset;
// ch->busproc = hpt3xx_tristate;
ch->udma_setup = hpt3xx_udma_setup;
}
ch->udma_setup = hpt3xx_udma_setup;
if (!noautodma)
ch->autodma = 1;
else
ch->autodma = 0;
ch->highmem = 1;
} else {
} else
#endif
{
ch->autodma = 0;
ch->drives[0].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)
......@@ -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_new = dma_old;
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, secondary, &slavedma);
pci_read_config_byte(ch->pci_dev, primary + 4, &slavedma);
if (masterdma & 0x30)
dma_new |= 0x20;
......@@ -1447,9 +1421,8 @@ int __init init_hpt366(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(chipsets); ++i) {
for (i = 0; i < ARRAY_SIZE(chipsets); ++i)
ata_register_chipset(&chipsets[i]);
}
return 0;
}
/*======================================================================
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
A driver for PCMCIA IDE/ATA disk cards
ide_cs.c 1.26 1999/11/16 02:10:49
......@@ -28,8 +28,8 @@
and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this
file under either the MPL or the GPL.
======================================================================*/
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
......@@ -54,12 +54,12 @@
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#define PCMCIA_DEBUG 100
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i");
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version =
"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
static const char *version = "ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
#else
#define DEBUG(n, args...)
#endif
......@@ -81,23 +81,23 @@ MODULE_LICENSE("GPL");
/*====================================================================*/
static const char ide_major[] = {
IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
#ifdef IDE4_MAJOR
IDE4_MAJOR, IDE5_MAJOR
IDE4_MAJOR, IDE5_MAJOR
#endif
};
typedef struct ide_info_t {
dev_link_t link;
int ndev;
dev_node_t node;
int hd;
dev_link_t link;
int ndev;
dev_node_t node;
int hd;
} 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 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";
......@@ -110,8 +110,11 @@ static dev_link_t *dev_list = NULL;
static void cs_error(client_handle_t handle, int func, int ret)
{
error_info_t err = { func, ret };
CardServices(ReportError, handle, &err);
error_info_t err = { func, ret };
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)
static dev_link_t *ide_attach(void)
{
ide_info_t *info;
dev_link_t *link;
client_reg_t client_reg;
int i, ret;
DEBUG(0, "ide_attach()\n");
/* Create new ide device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
link->release.function = &ide_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
if (irq_list[0] == -1)
link->irq.IRQInfo2 = irq_mask;
else
for (i = 0; i < 4; i++)
link->irq.IRQInfo2 |= 1 << irq_list[i];
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.event_handler = &ide_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = CardServices(RegisterClient, &link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
ide_detach(link);
return NULL;
}
return link;
} /* ide_attach */
ide_info_t *info;
dev_link_t *link;
client_reg_t client_reg;
int i, ret;
DEBUG(0, "ide_attach\n");
/* Create new ide device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
link->release.function = &ide_release;
link->release.data = (u_long) link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = 3;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
if (irq_list[0] == -1)
link->irq.IRQInfo2 = irq_mask;
else
for (i = 0; i < 4; i++)
link->irq.IRQInfo2 |= 1 << irq_list[i];
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.event_handler = &ide_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = CardServices(RegisterClient, &link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
ide_detach(link);
return NULL;
}
return link;
} /* ide_attach */
/*======================================================================
......@@ -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;
int ret;
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;
dev_link_t **linkp;
int ret;
DEBUG(0, "ide_detach(0x%p)\n", link);
del_timer(&link->release);
if (link->state & DEV_CONFIG)
ide_release((u_long)link);
if (link->handle) {
ret = CardServices(DeregisterClient, link->handle);
if (ret != CS_SUCCESS)
cs_error(link->handle, DeregisterClient, ret);
}
/* Unlink, free device structure */
*linkp = link->next;
kfree(link->priv);
} /* ide_detach */
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link)
break;
if (*linkp == NULL)
return;
del_timer(&link->release);
if (link->state & DEV_CONFIG)
ide_release((u_long) link);
if (link->handle) {
ret = CardServices(DeregisterClient, link->handle);
if (ret != CS_SUCCESS)
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
#define CFG_CHECK(fn, args...) \
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;
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 */
hw_regs_t hw;
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;
ide_info_t *info = link->priv;
tuple_t tuple;
u_short buf[128];
cisparse_t parse;
config_info_t conf;
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
cistpl_cftable_entry_t dflt = { 0 };
int i, pass, last_ret, last_fn, hd=-1, io_base, ctl_base;
DEBUG(0, "ide_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, handle, &tuple);
CS_CHECK(GetTupleData, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, handle, &conf);
link->conf.Vcc = conf.Vcc;
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, handle, &tuple);
while (1) {
CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse);
/* Check for matching Vcc, unless we're desperate */
if (!pass) {
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
goto next_entry;
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
goto next_entry;
}
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->conf.ConfigIndex = cfg->index;
link->io.BasePort1 = io->win[0].base;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
link->io.NumPorts1 = 8;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = 1;
CFG_CHECK(RequestIO, link->handle, &link->io);
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;
client_handle_t handle = link->handle;
ide_info_t *info = link->priv;
tuple_t tuple;
u_short buf[128];
cisparse_t parse;
config_info_t conf;
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
cistpl_cftable_entry_t dflt = { 0 };
int i, pass, last_ret, last_fn, hd = -1, io_base, ctl_base;
DEBUG(0, "ide_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, handle, &tuple);
CS_CHECK(GetTupleData, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, handle, &conf);
link->conf.Vcc = conf.Vcc;
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, handle, &tuple);
while (1) {
CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse);
/* Check for matching Vcc, unless we're desperate */
if (!pass) {
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (conf.Vcc !=
cfg->vcc.param[CISTPL_POWER_VNOM] /
10000)
goto next_entry;
} else if (dflt.vcc.
present & (1 << CISTPL_POWER_VNOM)) {
if (conf.Vcc !=
dflt.vcc.param[CISTPL_POWER_VNOM] /
10000)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io =
(cfg->io.nwin) ? &cfg->io : &dflt.io;
link->conf.ConfigIndex = cfg->index;
link->io.BasePort1 = io->win[0].base;
link->io.IOAddrLines =
io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 =
IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
link->io.NumPorts1 = 8;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = 1;
CFG_CHECK(RequestIO, link->handle,
&link->io);
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:
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++;
CS_CHECK(RequestIRQ, handle, &link->irq);
CS_CHECK(RequestConfiguration, handle, &link->conf);
/* deal with brain dead IDE resource management */
release_region(link->io.BasePort1, link->io.NumPorts1);
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);
}
}
CS_CHECK(RequestIRQ, handle, &link->irq);
CS_CHECK(RequestConfiguration, handle, &link->conf);
/* deal with brain dead IDE resource management */
release_region(link->io.BasePort1, link->io.NumPorts1);
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;
}
if (hd < 0) {
printk(KERN_NOTICE
"ide_cs: ide_register() at 0x%03x & 0x%03x"
", irq %u failed\n", io_base, ctl_base,
link->irq.AssignedIRQ);
goto failed;
}
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/10);
}
if (hd < 0) {
printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x"
", irq %u failed\n", io_base, ctl_base,
link->irq.AssignedIRQ);
goto failed;
}
MOD_INC_USE_COUNT;
info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2));
info->node.major = ide_major[hd];
info->node.minor = 0;
info->hd = hd;
link->dev = &info->node;
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, link->conf.Vpp1%10);
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
ide_release((u_long)link);
} /* ide_config */
MOD_INC_USE_COUNT;
info->ndev = 1;
sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
info->node.major = ide_major[hd];
info->node.minor = 0;
info->hd = hd;
link->dev = &info->node;
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,
link->conf.Vpp1 % 10);
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
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
void ide_release(u_long arg)
{
dev_link_t *link = (dev_link_t *)arg;
ide_info_t *info = link->priv;
DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) {
ide_unregister(&ide_hwifs[info->hd]);
MOD_DEC_USE_COUNT;
}
request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs");
if (link->io.NumPorts2)
request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs");
info->ndev = 0;
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
} /* ide_release */
dev_link_t *link = (dev_link_t *) arg;
ide_info_t *info = link->priv;
DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) {
ide_unregister(&ide_hwifs[info->hd]);
MOD_DEC_USE_COUNT;
}
request_region(link->io.BasePort1, link->io.NumPorts1, "ide-cs");
if (link->io.NumPorts2)
request_region(link->io.BasePort2, link->io.NumPorts2,
"ide-cs");
info->ndev = 0;
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
} /* ide_release */
/*======================================================================
......@@ -427,66 +458,67 @@ void ide_release(u_long arg)
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the ide drivers from
talking to the ports.
======================================================================*/
int ide_event(event_t event, int priority,
event_callback_args_t *args)
int ide_event(event_t event, int priority, 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);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
CardServices(ReleaseConfiguration, link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
CardServices(RequestConfiguration, link->handle, &link->conf);
break;
}
return 0;
} /* ide_event */
DEBUG(1, "ide_event(0x%06x)\n", event);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
mod_timer(&link->release, jiffies + HZ / 20);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
CardServices(ReleaseConfiguration, link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
CardServices(RequestConfiguration, link->handle,
&link->conf);
break;
}
return 0;
} /* ide_event */
/*====================================================================*/
static int __init init_ide_cs(void)
{
servinfo_t serv;
DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "ide_cs: Card Services release "
"does not match!\n");
return -1;
}
register_pccard_driver(&dev_info, &ide_attach, &ide_detach);
return 0;
servinfo_t serv;
DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "ide_cs: Card Services release "
"does not match!\n");
return -1;
}
register_pccard_driver(&dev_info, &ide_attach, &ide_detach);
return 0;
}
static void __exit exit_ide_cs(void)
{
DEBUG(0, "ide_cs: unloading\n");
unregister_pccard_driver(&dev_info);
while (dev_list != NULL)
ide_detach(dev_list);
DEBUG(0, "ide_cs: unloading\n");
unregister_pccard_driver(&dev_info);
while (dev_list != NULL)
ide_detach(dev_list);
}
module_init(init_ide_cs);
......
......@@ -176,6 +176,9 @@ int drive_is_ready(struct ata_device *drive)
return 1; /* drive ready: *might* be interrupting */
}
/*
* FIXME: Channel lock should be held on entry.
*/
ide_startstop_t ata_taskfile(struct ata_device *drive,
struct ata_taskfile *ar, struct request *rq)
{
......
......@@ -325,7 +325,6 @@ void ide_driver_module(void)
int i;
/* Don't reinit the probe if there is already one channel detected. */
for (i = 0; i < MAX_HWIFS; ++i) {
if (ide_hwifs[i].present)
goto revalidate;
......@@ -565,33 +564,12 @@ static int subdriver_match(struct ata_channel *channel, struct ata_operations *o
if (drive->present && !drive->driver) {
(*ops->attach)(drive);
if (drive->driver != NULL)
count++;
++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
* Set initializing=1 iff calling before probes have taken place.
......@@ -601,7 +579,6 @@ int ide_register_hw(hw_regs_t *hw)
int h;
int retry = 1;
struct ata_channel *ch;
struct ata_operations *subdriver;
do {
for (h = 0; h < MAX_HWIFS; ++h) {
......@@ -639,12 +616,20 @@ int ide_register_hw(hw_regs_t *hw)
}
/* 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))) {
if (subdriver_match(ch, subdriver) > 0)
break;
{
struct ata_operations *tmp;
unsigned long flags;
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;
......
......@@ -3,6 +3,11 @@
* linux/drivers/ide/pdc202xx.c Version 0.30 May. 28, 2002
*
* 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
*
* Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
......@@ -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/types.h>
#include <linux/kernel.h>
......@@ -61,9 +60,10 @@
#define IORDY_EN 0x20 /* PIO: IOREADY */
#define PREFETCH_EN 0x10 /* PIO: PREFETCH */
#define PDC_CLOCK(high_16) IN_BYTE(high_16 + 0x11)
#define UDMA_SPEED_FLAG(high_16) IN_BYTE(high_16 + 0x001f)
#define PDC_CLK 0x11
#define PDC_PRIMARY 0x1a
#define PDC_SECONDARY 0x1b
#define PDC_UDMA 0x1f
#if PDC202XX_DECODE_REGISTER_INFO
......@@ -78,23 +78,12 @@ static struct pdc_bit_messages pdc_reg_A[] = {
{ 0x20, "IORDY_EN" },
{ 0x10, "PREFETCH_EN" },
/* PA3-PA0 - PIO "A" timing */
{ 0x08, "PA3" },
{ 0x04, "PA2" },
{ 0x02, "PA1" },
{ 0x01, "PA0" }
};
static struct pdc_bit_messages pdc_reg_B[] = {
/* MB2-MB0 - DMA "B" timing */
{ 0x80, "MB2" },
{ 0x40, "MB1" },
{ 0x20, "MB0" },
{ 0x10, "PIO_FORCED/PB4" }, /* PIO_FORCE 1:0 */
/* 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[] = {
......@@ -103,10 +92,6 @@ static struct pdc_bit_messages pdc_reg_C[] = {
{ 0x20, "DMAR_EN" },
{ 0x10, "DMAW_EN" },
/* 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)
......@@ -115,7 +100,7 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
printk(KERN_DEBUG " { ");
for (i = 0; i < 8; i++, msgs++)
for (i = 0; i < ARRAY_SIZE(msgs); i++, msgs++)
if (bits & msgs->mask)
printk(KERN_DEBUG "%s ", msgs->msg);
......@@ -123,13 +108,6 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits)
}
#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)
{
static const char *pdc_quirk_drives[] = {
......@@ -179,14 +157,11 @@ static int pdc202xx_ratemask(struct ata_device *drive)
static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
{
struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev;
unsigned int drive_conf;
byte drive_pci, AP, BP, CP;
byte TA = 0, TB = 0, TC = 0;
struct pci_dev *dev = drive->channel->pci_dev;
u32 drive_conf;
u8 drive_pci, AP, BP, CP, DP, TA = 0, TB, TC = 0;
if (drive->dn > 3)
if (drive->dn > 3) /* FIXME: remove this --bkz */
return -1;
drive_pci = 0x60 + (drive->dn << 2);
......@@ -195,37 +170,12 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
return -1;
pci_read_config_dword(dev, drive_pci, &drive_conf);
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);
#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);
pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, drive_pci + 2, &CP);
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
/* case XFER_UDMA_6: */
case XFER_UDMA_5:
case XFER_UDMA_4: TB = 0x20; TC = 0x01; 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)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0) {
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
pci_write_config_byte(dev, drive_pci + 1, (BP & ~0xf0) | TB);
pci_write_config_byte(dev, drive_pci + 2, (CP & ~0x0f) | TC);
} else
#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif
{
pci_write_config_byte(dev, (drive_pci), AP|TA);
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
pci_write_config_byte(dev, drive_pci, (AP & ~0x0f) | TA);
pci_write_config_byte(dev, drive_pci + 1, (BP & ~0x07) | TB);
}
#if PDC202XX_DECODE_REGISTER_INFO
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);
pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, drive_pci + 2, &CP);
pci_read_config_byte(dev, drive_pci + 3, &DP);
printk(KERN_DEBUG "AP(%x): PIO(A) = %d\n", AP, AP & 0x0f);
pdc_dump_bits(pdc_reg_A, AP);
......@@ -298,7 +248,6 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
OUT_BYTE(value, reg); \
mdelay(delay);
static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed)
{
struct ata_channel *hwif = drive->channel;
......@@ -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 datareg = (hwif->dma_base + 3);
#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 datareg = (indexreg + 2);
#endif /* CONFIG_BLK_DEV_IDEDMA */
......@@ -431,23 +380,19 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
struct ata_channel *hwif = drive->channel;
struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id;
struct pci_dev *dev = hwif->pci_dev;
unsigned long high_16 = init_high_16(dev);
unsigned long dma_base = hwif->dma_base;
unsigned long indexreg = dma_base + 1;
unsigned long datareg = dma_base + 3;
u32 high_16 = pci_resource_start(dev, 4);
u32 dma_base = hwif->dma_base;
u32 indexreg = dma_base + 1;
u32 datareg = dma_base + 3;
byte adj = (drive->dn%2) ? 0x08 : 0x00;
byte jumpbit = 0;
unsigned int drive_conf;
byte drive_pci = 0, AP, tmp, mode = -1;
byte CLKSPD = 0;
/* primary - second bit, secondary - fourth bit */
byte mask = hwif->unit ? 0x08 : 0x02;
u8 jumpbit;
u32 drive_conf;
u8 drive_pci = 0, AP, tmp, mode = -1;
u8 CLKSPD, mask = hwif->unit ? 0x08 : 0x02;
int map;
byte needs_80w = ((id->dma_ultra & 0x0008) ||
(id->dma_ultra & 0x0010) ||
(id->dma_ultra & 0x0020) ||
(id->dma_ultra & 0x0040));
/* UDMA 3, 4, 5 and 6 */
u8 needs_80w = (id->dma_ultra & 0x0078);
switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20267:
......@@ -456,52 +401,44 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
case PCI_DEVICE_ID_PROMISE_20246:
jumpbit = 0;
break;
default: /* chipsets newer then 20268 */
default: /* chipsets newer then 20267 */
jumpbit = 1;
break;
}
if (!jumpbit)
CLKSPD = PDC_CLOCK(high_16);
/* FIXME: this check is wrong for 20246 --bkz */
/* */
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
* 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
* fall back to U33 mode. The BIOS INT 13 hooks turn
* the clock on then off for each read/write issued. I don't
* do that here because it would require modifying the
* kernel, seperating the fop routines from the kernel or
* somehow hooking the fops calls. It may also be possible to
* leave the 66Mhz clock on and readjust the timing
* parameters.
* the clock on then off for each read/write issued.
* We can do the same in device specific udma_start/stop()
* routines or better try to readjust timings.
*
* FIXME: move this to pdc202xx_tuneproc()
* right now you can't downgrade from U66 to U33 --bkz
*/
if (needs_80w) {
/* FIXME: this check is wrong for 20246 --bkz */
if (!hwif->udma_four) {
printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name);
printk(KERN_WARNING "%s: reduced to UDMA(33) mode.\n", drive->name);
if (!jumpbit)
OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
}
if (!jumpbit) {
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));
}
}
CLKSPD = IN_BYTE(high_16 + PDC_CLK);
/* check cable and mate (must be at least udma3 capable) */
if (!hwif->udma_four ||
!mate_id || !(mate_id->dma_ultra & 0x0078))
OUT_BYTE(CLKSPD & ~mask, high_16 + PDC_CLK);
else
/* cable ok, mate ok or single drive */
OUT_BYTE(CLKSPD | mask, high_16 + PDC_CLK);
}
if (jumpbit)
goto chipset_is_set;
if (drive->dn > 3) /* FIXME: remove this --bkz */
return 0;
......@@ -560,7 +497,7 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
return 0;
}
return !(hwif->speedproc(drive, mode));
return !hwif->speedproc(drive, mode);
}
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)
{
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);
if (drive->addressing) {
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_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
outl(word_count, atapi_reg);
......@@ -640,15 +577,15 @@ static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
int pdc202xx_udma_stop(struct ata_device *drive)
{
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 dma_base = ch->dma_base;
u8 dma_stat, clock;
if (drive->addressing) {
outl(0, atapi_reg); /* zero out extra */
clock = PDC_CLOCK(high_16);
OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11);
clock = IN_BYTE(high_16 + PDC_CLK);
OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK);
}
drive->waiting_for_dma = 0;
......@@ -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 */
}
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)
{
if (!drive->channel->resetproc)
......@@ -690,55 +617,51 @@ void pdc202xx_new_reset(struct ata_device *drive)
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);
byte udma_speed_flag = UDMA_SPEED_FLAG(high_16);
u32 high_16 = pci_resource_start(dev, 4);
u8 burst = IN_BYTE(high_16 + PDC_UDMA);
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 ?! */
printk("PDC202XX: %s channel reset.\n",
drive->channel->unit ? "Secondary" : "Primary");
set_reg_and_wait(burst | 0x10, high_16 + PDC_UDMA, 100);
/* FIXME: 2 seconds ?! */
set_reg_and_wait(burst & ~0x10, high_16 + PDC_UDMA, 2000);
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)
{
unsigned long high_16 = init_high_16(dev);
byte udma_speed_flag = UDMA_SPEED_FLAG(high_16);
byte primary_mode = IN_BYTE(high_16 + 0x001a);
byte secondary_mode = IN_BYTE(high_16 + 0x001b);
byte newchip = 0;
u32 high_16 = pci_resource_start(dev, 4);
u8 burst = IN_BYTE(high_16 + PDC_UDMA);
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);
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) {
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_20265:
case PCI_DEVICE_ID_PROMISE_20262:
/*
* 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 ?! */
pdc202xx_reset_host(dev);
break;
default:
/* FIXME: only checked for 20246 - is this right?,
......@@ -755,46 +678,44 @@ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev)
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
if (!(udma_speed_flag & 1)) {
printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", dev->name, udma_speed_flag, (udma_speed_flag|1));
OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f);
printk("%sCTIVE\n", (UDMA_SPEED_FLAG(high_16) & 1) ? "A" : "INA");
if (!(burst & 1)) {
printk(KERN_INFO "%s: forcing (U)DMA BURST.\n", dev->name);
OUT_BYTE(burst | 1, high_16 + PDC_UDMA);
}
#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;
}
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);
unsigned short CIS;
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));
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);
printk(KERN_INFO "%s: ROM enabled at 0x%08lx.\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start);
}
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)
......@@ -820,7 +741,6 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif)
if (hwif->dma_base) {
hwif->udma_start = pdc202xx_udma_start;
hwif->udma_stop = pdc202xx_udma_stop;
hwif->udma_irq_status = pdc202xx_udma_irq_status;
}
#endif
/* FIXME: check whether 20246 works with lba48 --bkz */
......@@ -867,7 +787,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20262,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
......@@ -880,7 +800,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20265,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
......@@ -895,7 +815,7 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20267,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
......@@ -907,8 +827,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
init_chipset: pdc202xx_tx_init_chipset,
ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
......@@ -920,8 +840,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268R,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
init_chipset: pdc202xx_tx_init_chipset,
ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
......@@ -929,8 +849,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20269,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
init_chipset: pdc202xx_tx_init_chipset,
ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
......@@ -938,8 +858,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20275,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
init_chipset: pdc202xx_tx_init_chipset,
ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
......@@ -947,8 +867,8 @@ static struct ata_pci_device chipsets[] __initdata = {
{
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20276,
init_chipset: pdc202xx_init_chipset,
ata66_check: ata66_pdc202xx,
init_chipset: pdc202xx_tx_init_chipset,
ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
......
......@@ -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 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
......
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