Commit 3ddddcf2 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.13 IDE 53

 - Start splitting the functions for host chip handling in to separate entities.
   This change is quite sensitive and may cause some trouble but it's for
   certain worth it anyway, because it should for example provide a much better
   infrastructure for th handling of different architectures.
parent ab08629c
......@@ -33,16 +33,16 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
comment 'IDE chipset support'
comment 'ATA host chipset support'
dep_bool ' CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86
dep_bool ' CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED $CONFIG_BLK_DEV_CMD640
dep_bool ' ISA-PNP EIDE support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
dep_bool ' ISA-PNP support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
if [ "$CONFIG_PCI" = "y" ]; then
dep_bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86
bool ' Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI
bool ' PCI host chipset support' CONFIG_BLK_DEV_IDEPCI
if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
bool ' Sharing PCI ATA interrupts support' CONFIG_IDEPCI_SHARE_IRQ
bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
......@@ -82,11 +82,9 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' VIA chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 $CONFIG_BLK_DEV_IDEDMA_PCI
fi
if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
fi
fi
if [ "$CONFIG_ALL_PPC" = "y" ]; then
bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
......
......@@ -437,7 +437,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -459,7 +459,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......
......@@ -441,7 +441,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -463,7 +463,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -483,21 +483,25 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
return hwif->udma(dma_func, drive, NULL);
}
static int ali15x3_udma_write(struct ata_device *drive, struct request *rq)
{
if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
return 1; /* try PIO instead of DMA */
return ata_do_udma(0, drive, rq);
}
static int ali15x3_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
switch(func) {
case ide_dma_check:
return ali15x3_config_drive_for_dma(drive);
case ide_dma_write:
if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
return 1; /* try PIO instead of DMA */
break;
default:
break;
}
return ide_dmaproc(func, drive, rq); /* use standard DMA stuff */
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif
unsigned int __init pci_init_ali15x3(struct pci_dev *dev)
{
......@@ -679,6 +683,7 @@ void __init ide_init_ali15x3(struct ata_channel *hwif)
/*
* M1543C or newer for DMAing
*/
hwif->udma_write = ali15x3_udma_write;
hwif->udma = ali15x3_dmaproc;
hwif->autodma = 1;
}
......
......@@ -783,7 +783,7 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive)
if ((id != NULL) && ((id->capability & 1) != 0) &&
hwif->autodma && (drive->type == ATA_DISK)) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -805,7 +805,7 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -837,6 +837,34 @@ static int cmd680_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
return ide_dmaproc(func, drive, rq);
}
static int cmd64x_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
u8 dma_stat = 0;
unsigned long dma_base = ch->dma_base;
struct pci_dev *dev = ch->pci_dev;
u8 jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
if (jack_slap) {
byte dma_intr = 0;
byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
/*
* DAMN BMIDE is not connected to PCI space!
* Have to manually jack-slap that bitch!
* To allow the PCI side to read incoming interrupts.
*/
(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */
}
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
}
static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
......@@ -845,30 +873,10 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
u8 mask = (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
unsigned long dma_base = ch->dma_base;
struct pci_dev *dev = ch->pci_dev;
byte jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
switch (func) {
case ide_dma_check:
return cmd64x_config_drive_for_dma(drive);
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
if (jack_slap) {
byte dma_intr = 0;
byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
/*
* DAMN BMIDE is not connected to PCI space!
* Have to manually jack-slap that bitch!
* To allow the PCI side to read incoming interrupts.
*/
(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */
}
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
......@@ -886,26 +894,29 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
return ide_dmaproc(func, drive, rq);
}
static int cmd646_1_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* and free any DMA resources */
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_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
byte dma_stat;
switch (func) {
case ide_dma_check:
return cmd64x_config_drive_for_dma(drive);
case ide_dma_end:
drive->waiting_for_dma = 0;
dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
}
......@@ -1134,19 +1145,22 @@ void __init ide_init_cmd64x(struct ata_channel *hwif)
case PCI_DEVICE_ID_CMD_649:
case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_643:
hwif->udma = &cmd64x_dmaproc;
hwif->tuneproc = &cmd64x_tuneproc;
hwif->speedproc = &cmd64x_tune_chipset;
hwif->udma_stop = cmd64x_udma_stop;
hwif->udma = cmd64x_dmaproc;
hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset;
break;
case PCI_DEVICE_ID_CMD_646:
hwif->chipset = ide_cmd646;
if (class_rev == 0x01) {
hwif->udma_stop = &cmd646_1_udma_stop;
hwif->udma = &cmd646_1_dmaproc;
} else {
hwif->udma = &cmd64x_dmaproc;
hwif->udma_stop = cmd64x_udma_stop;
hwif->udma = cmd64x_dmaproc;
}
hwif->tuneproc = &cmd64x_tuneproc;
hwif->speedproc = &cmd64x_tune_chipset;
hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset;
break;
default:
break;
......
......@@ -158,7 +158,7 @@ static int cs5530_config_dma (ide_drive_t *drive)
*/
if (mate->present) {
struct hd_driveid *mateid = mate->id;
if (mateid && (mateid->capability & 1) && !hwif->udma(ide_dma_bad_drive, mate, NULL)) {
if (mateid && (mateid->capability & 1) && !udma_black_list(mate)) {
if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7))
udma_ok = 1;
else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7))
......@@ -172,7 +172,7 @@ static int cs5530_config_dma (ide_drive_t *drive)
* Now see what the current drive is capable of,
* selecting UDMA only if the mate said it was ok.
*/
if (id && (id->capability & 1) && hwif->autodma && !hwif->udma(ide_dma_bad_drive, drive, NULL)) {
if (id && (id->capability & 1) && hwif->autodma && !udma_black_list(drive)) {
if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) {
if (id->dma_ultra & 4)
mode = XFER_UDMA_2;
......
......@@ -256,7 +256,7 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, rq)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -278,7 +278,7 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, rq)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -304,6 +304,55 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
return drive->channel->udma(dma_func, drive, rq);
}
static int hpt34x_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
}
static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
unsigned int count;
if (!(count = udma_new_table(ch, rq)))
return 1; /* try PIO instead of DMA */
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
reading |= 0x01;
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
}
static int hpt34x_udma_read(struct ata_device *drive, struct request *rq)
{
return do_udma(1 << 3, drive, rq);
}
static int hpt34x_udma_write(struct ata_device *drive, struct request *rq)
{
return do_udma(0, drive, rq);
}
/*
* hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
*
......@@ -311,45 +360,17 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
* and HPT345 UDMA bios chipset (stamped HPT363)
* by HighPoint|Triones Technologies, Inc.
*/
int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
unsigned int count, reading = 0;
byte dma_stat;
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive, rq);
case ide_dma_read:
reading = 1 << 3;
case ide_dma_write:
if (!(count = udma_new_table(ch, rq)))
return 1; /* try PIO instead of DMA */
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
reading |= 0x01;
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
}
return ide_dmaproc(func, drive, rq); /* use standard DMA stuff */
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif
/*
* If the BIOS does not set the IO base addaress to XX00, 343 will fail.
......@@ -423,7 +444,10 @@ void __init ide_init_hpt34x(struct ata_channel *hwif)
else
hwif->autodma = 0;
hwif->udma = &hpt34x_dmaproc;
hwif->udma_stop = hpt34x_udma_stop;
hwif->udma_read = hpt34x_udma_read;
hwif->udma_write = hpt34x_udma_write;
hwif->udma = hpt34x_dmaproc;
hwif->highmem = 1;
} else {
hwif->drives[0].autotune = 1;
......
......@@ -748,7 +748,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -769,7 +769,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -830,6 +830,86 @@ int hpt366_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
return ide_dmaproc(func, drive, rq); /* use standard DMA stuff */
}
static void do_udma_start(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
u8 regstate = ch->unit ? 0x54 : 0x50;
pci_write_config_byte(ch->pci_dev, regstate, 0x37);
udelay(10);
}
static int hpt370_udma_start(struct ata_device *drive, struct request *__rq)
{
struct ata_channel *ch = drive->channel;
do_udma_start(drive);
/* Note that this is done *after* the cmd has been issued to the drive,
* as per the BM-IDE spec. The Promise Ultra33 doesn't work correctly
* when we do this part before issuing the drive cmd.
*/
outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */
return 0;
}
static void do_timeout_irq(struct ata_device *drive)
{
u8 dma_stat;
u8 regstate = drive->channel->unit ? 0x54 : 0x50;
u8 reginfo = drive->channel->unit ? 0x56 : 0x52;
unsigned long dma_base = drive->channel->dma_base;
pci_read_config_byte(drive->channel->pci_dev, reginfo, &dma_stat);
printk(KERN_INFO "%s: %d bytes in FIFO\n", drive->name, dma_stat);
pci_write_config_byte(drive->channel->pci_dev, regstate, 0x37);
udelay(10);
dma_stat = inb(dma_base);
outb(dma_stat & ~0x1, dma_base); /* stop dma */
dma_stat = inb(dma_base + 2);
outb(dma_stat | 0x6, dma_base+2); /* clear errors */
}
static void hpt370_udma_timeout(struct ata_device *drive)
{
do_timeout_irq(drive);
do_udma_start(drive);
}
static void hpt370_udma_lost_irq(struct ata_device *drive)
{
do_timeout_irq(drive);
do_udma_start(drive);
}
static int hpt370_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
dma_stat = inb(dma_base + 2);
if (dma_stat & 0x01) {
udelay(20); /* wait a little */
dma_stat = inb(dma_base + 2);
}
if ((dma_stat & 0x01) != 0) {
do_timeout_irq(drive);
do_udma_start(drive);
}
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
}
int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
......@@ -845,18 +925,6 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
dma_stat = inb(dma_base+2);
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
case ide_dma_end:
dma_stat = inb(dma_base + 2);
if (dma_stat & 0x01) {
udelay(20); /* wait a little */
dma_stat = inb(dma_base + 2);
}
if ((dma_stat & 0x01) == 0)
break;
func = ide_dma_timeout;
/* fallthrough */
case ide_dma_timeout:
case ide_dma_lostirq:
pci_read_config_byte(hwif->pci_dev, reginfo,
......@@ -871,11 +939,7 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
outb(dma_stat | 0x6, dma_base+2); /* clear errors */
/* fallthrough */
#ifdef HPT_RESET_STATE_ENGINE
case ide_dma_begin:
#endif
pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
udelay(10);
do_udma_start(drive);
break;
default:
......@@ -883,7 +947,7 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
}
return ide_dmaproc(func, drive, rq); /* use standard DMA stuff */
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
#endif
/*
* Since SUN Cobalt is attempting to do this operation, I should disclose
......@@ -1183,6 +1247,8 @@ void __init ide_init_hpt366(struct ata_channel *hwif)
pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
if (reg5ah & 0x10) /* interrupt force enable */
pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
hwif->udma_start = hpt370_udma_start;
hwif->udma_stop = hpt370_udma_stop;
hwif->udma = hpt370_dmaproc;
} else {
hwif->udma = hpt366_dmaproc;
......
......@@ -737,9 +737,9 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
if (info->dma) {
if (info->cmd == READ)
info->dma = !drive->channel->udma(ide_dma_read, drive, rq);
info->dma = !udma_read(drive, rq);
else if (info->cmd == WRITE)
info->dma = !drive->channel->udma(ide_dma_write, drive, rq);
info->dma = !udma_write(drive, rq);
else
printk("ide-cd: DMA set, but not allowed\n");
}
......@@ -755,7 +755,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
if (info->dma)
drive->channel->udma(ide_dma_begin, drive, NULL);
udma_start(drive, rq);
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
ide_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
......@@ -905,7 +905,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
/* Check for errors. */
if (dma) {
info->dma = 0;
if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL)))
if ((dma_error = udma_stop(drive)))
drive->channel->udma(ide_dma_off, drive, NULL);
}
......@@ -1480,7 +1480,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
/* Check for errors. */
if (dma) {
info->dma = 0;
if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL))) {
if ((dma_error = udma_stop(drive))) {
printk("ide-cd: write dma error\n");
drive->channel->udma(ide_dma_off, drive, NULL);
}
......
This diff is collapsed.
......@@ -901,7 +901,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
if (drive->channel->udma(ide_dma_end, drive, NULL)) {
if (udma_stop(drive)) {
set_bit (PC_DMA_ERROR, &pc->flags);
} else {
pc->actually_transferred=pc->request_transfer;
......@@ -1122,8 +1122,12 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
(void) drive->channel->udma(ide_dma_off, drive, NULL);
}
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
dma_ok=!drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
if (test_bit (PC_WRITING, &pc->flags))
dma_ok = !udma_write(drive, rq);
else
dma_ok = !udma_read(drive, rq);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (IDE_CONTROL_REG)
......@@ -1136,7 +1140,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
#ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
(void) drive->channel->udma(ide_dma_begin, drive, NULL);
udma_start(drive, rq);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
......
......@@ -709,7 +709,7 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
}
printk("%s: chipset revision %d\n", dev->name, class_rev);
printk(KERN_INFO "ATA: chipset rev.: %d\n", class_rev);
/*
* Can we trust the reported IRQ?
......@@ -722,11 +722,11 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
to act otherwise on those. The Supertrak however we need
to skip */
if (d->vendor == PCI_VENDOR_ID_PROMISE && d->device == PCI_DEVICE_ID_PROMISE_20265) {
printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
printk(KERN_INFO "ATA: Found promise 20265 in RAID mode.\n");
if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960)
{
printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
printk(KERN_INFO "ATA: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
return;
}
}
......@@ -734,9 +734,10 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
Suspect a fastrak and fall through */
}
if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
printk("%s: not 100%% native mode: will probe irqs later\n", dev->name);
printk(KERN_INFO "ATA: non-legacy mode: IRQ probe delayed\n");
/*
* This allows off board ide-pci cards the enable a BIOS,
* This allows off board ide-pci cards to enable a BIOS,
* verify interrupt settings of split-mirror pci-config
* space, place chipset into init-mode, and/or preserve
* an interrupt if the card is not native ide support.
......@@ -746,19 +747,18 @@ static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *
else
pciirq = trust_pci_irq(d, dev);
} else if (tried_config) {
printk("%s: will probe IRQs later\n", dev->name);
printk(KERN_INFO "ATA: will probe IRQs later\n");
pciirq = 0;
} else if (!pciirq) {
printk("%s: bad IRQ (%d): will probe later\n", dev->name, pciirq);
printk(KERN_INFO "ATA: invalid IRQ (%d): will probe later\n", pciirq);
pciirq = 0;
} else {
if (d->init_chipset)
d->init_chipset(dev);
#ifdef __sparc__
printk("%s: 100%% native mode on irq %s\n",
dev->name, __irq_itoa(pciirq));
printk(KERN_INFO "ATA: 100%% native mode on irq\n", __irq_itoa(pciirq));
#else
printk("%s: 100%% native mode on irq %d\n", dev->name, pciirq);
printk(KERN_INFO "ATA: 100%% native mode on irq %d\n", pciirq);
#endif
}
......@@ -889,10 +889,10 @@ static void __init scan_pcidev(struct pci_dev *dev)
pdc20270_device_order_fixup(dev, d);
else if (!(d->vendor == 0 && d->device == 0) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
if (d->vendor == 0 && d->device == 0)
printk(KERN_INFO "ATA: unknown ATA interface %s (%04x:%04x) on PCI slot %s\n",
printk(KERN_INFO "ATA: unknown interface: %s (%04x:%04x) on PCI slot %s\n",
dev->name, vendor, device, dev->slot_name);
else
printk(KERN_INFO "ATA: interface %s on PCI slot %s\n", dev->name, dev->slot_name);
printk(KERN_INFO "ATA: interface: %s, on PCI slot %s\n", dev->name, dev->slot_name);
setup_pci_device(dev, d);
}
}
......
......@@ -1449,7 +1449,6 @@ static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
case ide_dma_bad_drive:
case ide_dma_good_drive:
return check_drive_lists(drive, (func == ide_dma_good_drive));
case ide_dma_retune:
case ide_dma_lostirq:
case ide_dma_timeout:
printk(KERN_WARNING "ide_pmac_dmaproc: chipset supported func only: %d\n", func);
......
......@@ -2058,7 +2058,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
if (drive->channel->udma(ide_dma_end, drive, NULL)) {
if (udma_stop(drive)) {
/*
* A DMA error is sometimes expected. For example,
* if the tape is crossing a filemark during a
......@@ -2311,9 +2311,13 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
(void) drive->channel->udma(ide_dma_off, drive, NULL);
}
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
if (test_bit (PC_WRITING, &pc->flags))
dma_ok = !udma_write(drive, rq);
else
dma_ok = !udma_read(drive, rq);
}
#endif
if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
......@@ -2324,7 +2328,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
#ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
(void) drive->channel->udma(ide_dma_begin, drive, NULL);
udma_start(drive, rq);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
......
......@@ -461,7 +461,6 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
* regular dma proc -- basically split stuff that needs to act
* on a request from things like ide_dma_check etc.
*/
ide_dma_action_t dma_act;
if (!drive->using_dma)
return ide_started;
......@@ -469,10 +468,10 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
/* for dma commands we don't set the handler */
if (args->taskfile.command == WIN_WRITEDMA
|| args->taskfile.command == WIN_WRITEDMA_EXT)
dma_act = ide_dma_write;
udma_write(drive, rq);
else if (args->taskfile.command == WIN_READDMA
|| args->taskfile.command == WIN_READDMA_EXT)
dma_act = ide_dma_read;
udma_read(drive, rq);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
|| args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
......@@ -484,10 +483,6 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
return ide_stopped;
}
if (drive->channel->udma(dma_act, drive, rq))
return ide_stopped;
}
return ide_started;
......
......@@ -1407,7 +1407,7 @@ static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
/*
* end current dma transaction
*/
ch->udma(ide_dma_end, drive, rq);
ch->udma_stop(drive);
/*
* complain a little, later we might remove some of this verbosity
......@@ -2127,6 +2127,13 @@ void ide_unregister(struct ata_channel *ch)
ch->atapi_read = old.atapi_read;
ch->atapi_write = old.atapi_write;
ch->udma = old.udma;
ch->udma_start = old.udma_start;
ch->udma_stop = old.udma_stop;
ch->udma_read = old.udma_read;
ch->udma_write = old.udma_write;
ch->udma_irq_status = old.udma_irq_status;
ch->udma_timeout = old.udma_timeout;
ch->udma_lost_irq = old.udma_lost_irq;
ch->busproc = old.busproc;
ch->bus_state = old.bus_state;
ch->dma_base = old.dma_base;
......
......@@ -82,26 +82,50 @@ static void ns87415_selectproc (ide_drive_t *drive)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
static int ns87415_udma_stop(struct ata_device *drive)
{
struct ata_channel *hwif = drive->channel;
byte dma_stat;
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(ch->dma_base+2);
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(inb(dma_base)|6, dma_base); /* from ERRATA: clear the INTR & ERROR bits */
udma_destroy_table(ch); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
}
static int ns87415_udma_read(struct ata_device *drive, struct request *rq)
{
ns87415_prepare_drive(drive, 1); /* select DMA xfer */
if (!ata_do_udma(1, drive, rq)) /* use standard DMA stuff */
return 0;
ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */
return 1;
}
static int ns87415_udma_write(struct ata_device *drive, struct request *rq)
{
ns87415_prepare_drive(drive, 1); /* select DMA xfer */
if (!ata_do_udma(0, drive, rq)) /* use standard DMA stuff */
return 0;
ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */
return 1;
}
static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
switch (func) {
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
dma_stat = inb(hwif->dma_base+2);
outb(inb(hwif->dma_base)&~1, hwif->dma_base); /* stop DMA */
outb(inb(hwif->dma_base)|6, hwif->dma_base); /* from ERRATA: clear the INTR & ERROR bits */
udma_destroy_table(hwif); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_write:
case ide_dma_read:
ns87415_prepare_drive(drive, 1); /* select DMA xfer */
if (!ide_dmaproc(func, drive, rq)) /* use standard DMA stuff */
return 0;
ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */
return 1;
case ide_dma_check:
if (drive->type != ATA_DISK)
return ide_dmaproc(ide_dma_off_quietly, drive, rq);
......@@ -205,8 +229,12 @@ void __init ide_init_ns87415(struct ata_channel *hwif)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base)
if (hwif->dma_base) {
hwif->udma_stop = ns87415_udma_stop;
hwif->udma_read = ns87415_udma_read;
hwif->udma_write = ns87415_udma_write;
hwif->udma = ns87415_dmaproc;
}
#endif
hwif->selectproc = &ns87415_selectproc;
......
......@@ -916,7 +916,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on :
((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
ide_dma_off_quietly);
}
......@@ -929,7 +929,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && hwif->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -951,7 +951,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -977,20 +977,107 @@ int pdc202xx_quirkproc (ide_drive_t *drive)
return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
}
static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
{
u8 clock = 0;
u8 hardware48hack = 0;
struct ata_channel *ch = drive->channel;
struct pci_dev *dev = ch->pci_dev;
unsigned long high_16 = pci_resource_start(dev, 4);
unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
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:
break;
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265:
case PCI_DEVICE_ID_PROMISE_20262:
hardware48hack = 1;
clock = IN_BYTE(high_16 + 0x11);
default:
break;
}
if ((drive->addressing) && (hardware48hack)) {
unsigned long word_count = 0;
outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + 0x11);
word_count = (rq->nr_sectors << 8);
word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
outl(word_count, atapi_reg);
}
/* Note that this is done *after* the cmd has been issued to the drive,
* as per the BM-IDE spec. The Promise Ultra33 doesn't work correctly
* when we do this part before issuing the drive cmd.
*/
outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */
return 0;
}
int pdc202xx_udma_stop(struct ata_device *drive)
{
u8 newchip = 0;
u8 clock = 0;
u8 hardware48hack = 0;
struct ata_channel *ch = drive->channel;
struct pci_dev *dev = ch->pci_dev;
unsigned long high_16 = pci_resource_start(dev, 4);
unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
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:
hardware48hack = 1;
clock = IN_BYTE(high_16 + 0x11);
default:
break;
}
if ((drive->addressing) && (hardware48hack)) {
outl(0, atapi_reg); /* zero out extra */
clock = IN_BYTE(high_16 + 0x11);
OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11);
}
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
}
/*
* pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
*/
int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
byte dma_stat = 0;
byte sc1d = 0;
byte newchip = 0;
byte clock = 0;
byte hardware48hack = 0;
u8 dma_stat = 0;
u8 sc1d = 0;
u8 newchip = 0;
u8 clock = 0;
u8 hardware48hack = 0;
struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev;
unsigned long high_16 = pci_resource_start(dev, 4);
unsigned long atapi_reg = high_16 + (hwif->unit ? 0x24 : 0x00);
unsigned long dma_base = hwif->dma_base;
switch (dev->device) {
......@@ -1013,29 +1100,6 @@ int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct req
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
case ide_dma_begin:
/* Note that this is done *after* the cmd has
* been issued to the drive, as per the BM-IDE spec.
* The Promise Ultra33 doesn't work correctly when
* we do this part before issuing the drive cmd.
*/
if ((drive->addressing) && (hardware48hack)) {
struct request *rq = HWGROUP(drive)->rq;
unsigned long word_count = 0;
outb(clock|(hwif->unit ? 0x08 : 0x02), high_16 + 0x11);
word_count = (rq->nr_sectors << 8);
word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
outl(word_count, atapi_reg);
}
break;
case ide_dma_end:
if ((drive->addressing) && (hardware48hack)) {
outl(0, atapi_reg); /* zero out extra */
clock = IN_BYTE(high_16 + 0x11);
OUT_BYTE(clock & ~(hwif->unit ? 0x08:0x02), high_16 + 0x11);
}
break;
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = IN_BYTE(dma_base+2);
if (newchip)
......@@ -1268,6 +1332,8 @@ void __init ide_init_pdc202xx(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->udma_start = pdc202xx_udma_start;
hwif->udma_stop = pdc202xx_udma_stop;
hwif->udma = pdc202xx_dmaproc;
hwif->highmem = 1;
if (!noautodma)
......
......@@ -431,14 +431,14 @@ static int config_chipset_for_dma (ide_drive_t *drive)
ide_dma_off_quietly);
}
static int config_drive_xfer_rate (ide_drive_t *drive)
static int config_drive_xfer_rate(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
ide_dma_action_t dma_func = ide_dma_on;
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -460,7 +460,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
......@@ -480,45 +480,54 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
return drive->channel->udma(dma_func, drive, NULL);
}
static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
static int svwks_udma_stop(struct ata_device *drive)
{
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
case ide_dma_end:
{
struct ata_channel *hwif = drive->channel;
unsigned long dma_base = hwif->dma_base;
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
if(inb(dma_base+0x02)&1)
{
if(inb(dma_base+0x02)&1)
{
#if 0
int i;
printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
for(i=0;i<10;i++)
{
if(!(inb(dma_base+0x02)&1))
{
printk(KERN_ERR "OSB4 now finished.\n");
break;
}
udelay(5);
}
int i;
printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
for(i=0;i<10;i++)
{
if(!(inb(dma_base+0x02)&1))
{
printk(KERN_ERR "OSB4 now finished.\n");
break;
}
udelay(5);
}
#endif
printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
#if 0
/* Panic might sys_sync -> death by corrupt disk */
panic("OSB4: continuing might cause disk corruption.\n");
/* Panic might sys_sync -> death by corrupt disk */
panic("OSB4: continuing might cause disk corruption.\n");
#else
printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
while(1)
cpu_relax();
printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
while(1)
cpu_relax();
#endif
}
/* and drop through */
}
}
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
}
static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
default:
break;
}
......@@ -645,6 +654,7 @@ void __init ide_init_svwks(struct ata_channel *hwif)
if (!noautodma)
hwif->autodma = 1;
#endif
hwif->udma_stop = svwks_udma_stop;
hwif->udma = svwks_dmaproc;
hwif->highmem = 1;
} else {
......
......@@ -685,7 +685,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
......@@ -707,7 +707,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if ((ide_dmaproc(ide_dma_good_drive, drive, NULL)) &&
} else if ((udma_white_list(drive)) &&
(id->eide_dma_time > 150)) {
/* Consult the list of known "good" drives */
dma_func = config_chipset_for_dma(drive, 0);
......
......@@ -114,7 +114,7 @@ static int config_for_dma(ide_drive_t *drive)
* Check to see if the drive and
* chipset is capable of DMA mode
*/
static int sl82c105_check_drive(ide_drive_t *drive)
static int sl82c105_check_drive(ide_drive_t *drive, struct request *rq)
{
ide_dma_action_t dma_func = ide_dma_off_quietly;
......@@ -129,7 +129,7 @@ static int sl82c105_check_drive(ide_drive_t *drive)
break;
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive)) {
if (udma_black_list(drive)) {
dma_func = ide_dma_off;
break;
}
......@@ -140,23 +140,23 @@ static int sl82c105_check_drive(ide_drive_t *drive)
break;
}
if (ide_dmaproc(ide_dma_good_drive, drive)) {
if (udma_white_list(drive)) {
dma_func = ide_dma_on;
break;
}
} while (0);
return drive->channel->dmaproc(dma_func, drive);
return drive->channel->udma(dma_func, drive, rq);
}
/*
* Our own dmaproc, only to intercept ide_dma_check
*/
static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
static int sl82c105_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
switch (func) {
case ide_dma_check:
return sl82c105_check_drive(drive);
return sl82c105_check_drive(drive, rq);
case ide_dma_on:
if (config_for_dma(drive))
func = ide_dma_off;
......@@ -168,7 +168,7 @@ static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
default:
break;
}
return ide_dmaproc(func, drive);
return ide_dmaproc(func, drive, rq);
}
/*
......@@ -183,8 +183,8 @@ static void tune_sl82c105(ide_drive_t *drive, byte pio)
* We support 32-bit I/O on this interface, and it
* doesn't have problems with interrupts.
*/
drive->io_32bit = 1;
drive->unmask = 1;
drive->channel->io_32bit = 1;
drive->channel->unmask = 1;
}
/*
......@@ -252,10 +252,10 @@ void __init dma_init_sl82c105(struct ata_channel *hwif, unsigned long dma_base)
}
outb(dma_state, dma_base + 2);
hwif->dmaproc = NULL;
hwif->udma = NULL;
ide_setup_dma(hwif, dma_base, 8);
if (hwif->dmaproc)
hwif->dmaproc = sl82c105_dmaproc;
if (hwif->udma)
hwif->udma = sl82c105_dmaproc;
}
/*
......
......@@ -95,7 +95,7 @@ static void tcq_invalidate_queue(struct ata_device *drive)
del_timer(&hwgroup->timer);
if (test_bit(IDE_DMA, &hwgroup->flags))
drive->channel->udma(ide_dma_end, drive, hwgroup->rq);
udma_stop(drive);
blk_queue_invalidate_tags(q);
......@@ -328,7 +328,7 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq,
/*
* transfer was in progress, stop DMA engine
*/
dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
dma_stat = udma_stop(drive);
/*
* must be end of I/O, check status and complete as necessary
......@@ -531,7 +531,7 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
return ide_stopped;
set_irq(drive, ide_dmaq_intr);
if (!ch->udma(ide_dma_begin, drive, rq))
if (!udma_start(drive, rq))
return ide_started;
return ide_stopped;
......
......@@ -173,36 +173,73 @@ static void trm290_selectproc (ide_drive_t *drive)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
static int trm290_udma_start(struct ata_device *drive, struct request *__rq)
{
/* Nothing to be done here. */
return 0;
}
static int trm290_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
unsigned int count, reading = 2, writing = 0;
switch (func) {
case ide_dma_write:
reading = 0;
writing = 1;
drive->waiting_for_dma = 0;
udma_destroy_table(ch); /* purge DMA mappings */
return (inw(ch->dma_base + 2) != 0x00ff);
}
static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
unsigned int count, writing;
if (!reading) {
reading = 0;
writing = 1;
#ifdef TRM290_NO_DMA_WRITES
break; /* always use PIO for writes */
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
case ide_dma_read:
if (!(count = udma_new_table(ch, rq)))
break; /* try PIO instead of DMA */
trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
case ide_dma_begin:
return 0;
case ide_dma_end:
drive->waiting_for_dma = 0;
udma_destroy_table(ch); /* purge DMA mappings */
return (inw(ch->dma_base + 2) != 0x00ff);
} else {
reading = 2;
writing = 0;
}
if (!(count = udma_new_table(ch, rq))) {
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1; /* try PIO instead of DMA */
}
trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
}
static int trm290_udma_read(struct ata_device *drive, struct request *rq)
{
return do_udma(1, drive, rq);
}
static int trm290_udma_write(struct ata_device *drive, struct request *rq)
{
return do_udma(0, drive, rq);
}
static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
switch (func) {
case ide_dma_test_irq:
return (inw(ch->dma_base + 2) == 0x00ff);
default:
......@@ -263,6 +300,10 @@ void __init ide_init_trm290(struct ata_channel *hwif)
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->unit ? 0x0080 : 0x0000), 3);
#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->udma_start = trm290_udma_start;
hwif->udma_stop = trm290_udma_stop;
hwif->udma_read = trm290_udma_read;
hwif->udma_write = trm290_udma_write;
hwif->udma = trm290_dmaproc;
#endif
......
......@@ -328,7 +328,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
printk ("ide-scsi: %s: DMA complete\n", drive->name);
#endif /* IDESCSI_DEBUG_LOG */
pc->actually_transferred=pc->request_transfer;
(void) drive->channel->udma(ide_dma_end, drive, NULL);
udma_stop(drive);
}
status = GET_STAT(); /* Clear the interrupt */
......@@ -429,8 +429,12 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
pc->current_position=pc->buffer;
bcount = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */
if (drive->using_dma && rq->bio)
dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
if (drive->using_dma && rq->bio) {
if (test_bit (PC_WRITING, &pc->flags))
dma_ok = !udma_write(drive, rq);
else
dma_ok = !udma_read(drive, rq);
}
SELECT_DRIVE(drive->channel, drive);
if (IDE_CONTROL_REG)
......@@ -441,7 +445,7 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
if (dma_ok) {
set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
(void) drive->channel->udma(ide_dma_begin, drive, NULL);
udma_start(drive, rq);
}
if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
ide_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
......
......@@ -374,15 +374,10 @@ struct ata_device {
} ide_drive_t;
typedef enum {
ide_dma_read, ide_dma_write,
ide_dma_begin, ide_dma_end,
ide_dma_check,
ide_dma_on, ide_dma_off,
ide_dma_off_quietly,
ide_dma_test_irq,
ide_dma_bad_drive,
ide_dma_good_drive,
ide_dma_retune,
ide_dma_lostirq,
ide_dma_timeout
} ide_dma_action_t;
......@@ -436,7 +431,19 @@ struct ata_channel {
void (*atapi_read)(struct ata_device *, void *, unsigned int);
void (*atapi_write)(struct ata_device *, void *, unsigned int);
int (*udma)(ide_dma_action_t, struct ata_device *, struct request *); /* dma read/write/abort routine */
int (*udma)(ide_dma_action_t, struct ata_device *, struct request *);
int (*udma_start) (struct ata_device *, struct request *rq);
int (*udma_stop) (struct ata_device *);
int (*udma_read) (struct ata_device *, struct request *rq);
int (*udma_write) (struct ata_device *, struct request *rq);
int (*udma_irq_status) (struct ata_device *);
void (*udma_timeout) (struct ata_device *);
void (*udma_lost_irq) (struct ata_device *);
unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */
dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */
struct scatterlist *sg_table; /* Scatter-gather list used to build the above */
......@@ -873,13 +880,25 @@ extern int udma_new_table(struct ata_channel *, struct request *);
extern void udma_destroy_table(struct ata_channel *);
extern void udma_print(struct ata_device *);
extern void udma_enable(struct ata_device *, int, int);
extern int udma_black_list(struct ata_device *);
extern int udma_white_list(struct ata_device *);
extern void udma_timeout(struct ata_device *);
extern void udma_lost_irq(struct ata_device *);
extern int udma_start(struct ata_device *, struct request *rq);
extern int udma_stop(struct ata_device *);
extern int udma_read(struct ata_device *, struct request *rq);
extern int udma_write(struct ata_device *, struct request *rq);
extern int udma_irq_status(struct ata_device *);
extern int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq);
extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
extern int udma_tcq_enable(struct ata_device *, int);
extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
extern int check_drive_lists(struct ata_device *, int good_bad);
extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
extern void ide_release_dma(struct ata_channel *);
extern void ide_setup_dma(struct ata_channel *, unsigned long, unsigned int) __init;
extern int ata_start_dma(struct ata_device *, struct request *rq);
......
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