Commit 8b4e98ea authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.19 IDE 78

 - Move ide_fixstring() from ide.c to probe.c, since this is the place, where it's
   most used.

 - Remove GET_STAT() - it's not used any longer.

 - Remove last parameter of ide_error. Rename it to ata_error().

 - Don't use ide_fixstring in qd65xx.c host chip driver. The model name is
   already fixed in probe.c.

 - Invent ata_irq_enable() for the handling of the trice nIEN bit of the
   control register.  Consistently use ch->intrproc method every time we toggle
   this bit.  This simply wasn't the case before!

 - Disable interrupts on a previous channel only when we share them indeed.

 - Eliminate simple drive command handling function drive_cmd.

 - Simplify the ioctl handler. Move it to ioctl, since that's the only place
   where it's actually used.
parent 78a6728c
...@@ -707,7 +707,7 @@ static ide_startstop_t etrax_dma_intr(struct ata_device *drive, struct request * ...@@ -707,7 +707,7 @@ static ide_startstop_t etrax_dma_intr(struct ata_device *drive, struct request *
} }
printk("%s: bad DMA status\n", drive->name); printk("%s: bad DMA status\n", drive->name);
} }
return ide_error(drive, "dma_intr", drive->status); return ata_error(drive, __FUNCTION__);
} }
/* /*
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
/* /*
* Common low leved device access code. This is the lowest layer of hardware * Common low leved device access code. This is the lowest layer of hardware
* access. * access.
*
* This is the place where register set access portability will be handled in
* the future.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -23,11 +26,9 @@ ...@@ -23,11 +26,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/cdrom.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
...@@ -92,4 +93,53 @@ int ata_status(struct ata_device *drive, u8 good, u8 bad) ...@@ -92,4 +93,53 @@ int ata_status(struct ata_device *drive, u8 good, u8 bad)
EXPORT_SYMBOL(ata_status); EXPORT_SYMBOL(ata_status);
/*
* Handle the nIEN - negated Interrupt ENable of the drive.
* This is controlling whatever the drive will acnowlenge commands
* with interrupts or not.
*/
int ata_irq_enable(struct ata_device *drive, int on)
{
struct ata_channel *ch = drive->channel;
if (!ch->io_ports[IDE_CONTROL_OFFSET])
return 0;
if (on)
OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
else {
if (!ch->intrproc)
OUT_BYTE(0x02, ch->io_ports[IDE_CONTROL_OFFSET]);
else
ch->intrproc(drive);
}
return 1;
}
EXPORT_SYMBOL(ata_irq_enable);
/*
* Perform a reset operation on the currently selected drive.
*/
void ata_reset(struct ata_channel *ch)
{
unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
if (!ch->io_ports[IDE_CONTROL_OFFSET])
return;
printk("%s: reset\n", ch->name);
OUT_BYTE(0x04, ch->io_ports[IDE_CONTROL_OFFSET]);
udelay(10);
OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
do {
mdelay(50);
stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
} while ((stat & BUSY_STAT) && time_before(jiffies, timeout));
}
EXPORT_SYMBOL(ata_reset);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -264,7 +264,7 @@ static int do_udma(unsigned int reading, struct ata_device *drive, struct reques ...@@ -264,7 +264,7 @@ static int do_udma(unsigned int reading, struct ata_device *drive, struct reques
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ 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); OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
......
...@@ -813,31 +813,26 @@ static void hpt3xx_intrproc(struct ata_device *drive) ...@@ -813,31 +813,26 @@ static void hpt3xx_intrproc(struct ata_device *drive)
if (drive->quirk_list) { if (drive->quirk_list) {
/* drives in the quirk_list may not like intr setups/cleanups */ /* drives in the quirk_list may not like intr setups/cleanups */
} else { } else {
OUT_BYTE((drive)->ctl|2, drive->channel->io_ports[IDE_CONTROL_OFFSET]); OUT_BYTE(0x02, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
} }
} }
static void hpt3xx_maskproc(struct ata_device *drive) static void hpt3xx_maskproc(struct ata_device *drive)
{ {
struct pci_dev *dev = drive->channel->pci_dev; struct pci_dev *dev = drive->channel->pci_dev;
const int mask = 0; struct ata_channel *ch = drive->channel;
if (drive->quirk_list) { if (drive->quirk_list) {
if (hpt_min_rev(dev, 3)) { if (hpt_min_rev(dev, 3)) {
u8 reg5a; u8 reg5a;
pci_read_config_byte(dev, 0x5a, &reg5a); pci_read_config_byte(dev, 0x5a, &reg5a);
if (((reg5a & 0x10) >> 4) != mask) if ((reg5a & 0x10) >> 4)
pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); pci_write_config_byte(dev, 0x5a, reg5a & ~0x10);
} else { } else
if (mask) { enable_irq(drive->channel->irq);
disable_irq(drive->channel->irq);
} else {
enable_irq(drive->channel->irq);
}
}
} else { } else {
if (IDE_CONTROL_REG) if (ch->io_ports[IDE_CONTROL_OFFSET])
OUT_BYTE(mask ? (drive->ctl | 2) : (drive->ctl & ~2), IDE_CONTROL_REG); OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
} }
} }
......
...@@ -123,16 +123,16 @@ ...@@ -123,16 +123,16 @@
static void ht6560b_selectproc(struct ata_device *drive) static void ht6560b_selectproc(struct ata_device *drive)
{ {
unsigned long flags; unsigned long flags;
static byte current_select = 0; static u8 current_select = 0;
static byte current_timing = 0; static u8 current_timing = 0;
byte select, timing; u8 select, timing;
__save_flags (flags); /* local CPU only */ __save_flags (flags); /* local CPU only */
__cli(); /* local CPU only */ __cli(); /* local CPU only */
select = HT_CONFIG(drive); select = HT_CONFIG(drive);
timing = HT_TIMING(drive); timing = HT_TIMING(drive);
if (select != current_select || timing != current_timing) { if (select != current_select || timing != current_timing) {
current_select = select; current_select = select;
current_timing = timing; current_timing = timing;
...@@ -147,7 +147,7 @@ static void ht6560b_selectproc(struct ata_device *drive) ...@@ -147,7 +147,7 @@ static void ht6560b_selectproc(struct ata_device *drive)
* Set timing for this drive: * Set timing for this drive:
*/ */
outb(timing, IDE_SELECT_REG); outb(timing, IDE_SELECT_REG);
(void) inb(IDE_STATUS_REG); ata_status(drive, 0, 0);
#ifdef DEBUG #ifdef DEBUG
printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing); printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing);
#endif #endif
...@@ -160,13 +160,13 @@ static void ht6560b_selectproc(struct ata_device *drive) ...@@ -160,13 +160,13 @@ static void ht6560b_selectproc(struct ata_device *drive)
*/ */
static int __init try_to_init_ht6560b(void) static int __init try_to_init_ht6560b(void)
{ {
byte orig_value; u8 orig_value;
int i; int i;
/* Autodetect ht6560b */ /* Autodetect ht6560b */
if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff) if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff)
return 0; return 0;
for (i=3;i>0;i--) { for (i=3;i>0;i--) {
outb(0x00, HT_CONFIG_PORT); outb(0x00, HT_CONFIG_PORT);
if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) { if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) {
...@@ -183,9 +183,9 @@ static int __init try_to_init_ht6560b(void) ...@@ -183,9 +183,9 @@ static int __init try_to_init_ht6560b(void)
* Ht6560b autodetected * Ht6560b autodetected
*/ */
outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ outb(HT_TIMING_DEFAULT, 0x1f6); /* SELECT */
(void) inb(0x1f7); /* IDE_STATUS_REG */ (void) inb(0x1f7); /* STATUS */
printk("\nht6560b " HT6560B_VERSION printk("\nht6560b " HT6560B_VERSION
": chipset detected and initialized" ": chipset detected and initialized"
#ifdef DEBUG #ifdef DEBUG
...@@ -228,19 +228,19 @@ static byte ht_pio2timings(struct ata_device *drive, byte pio) ...@@ -228,19 +228,19 @@ static byte ht_pio2timings(struct ata_device *drive, byte pio)
if (recovery_cycles < 2) recovery_cycles = 2; if (recovery_cycles < 2) recovery_cycles = 2;
if (active_cycles > 15) active_cycles = 15; if (active_cycles > 15) active_cycles = 15;
if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */ if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */
#ifdef DEBUG #ifdef DEBUG
printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n",
drive->name, pio - XFER_PIO_0, recovery_cycles, recovery_time, active_cycles, active_time); drive->name, pio - XFER_PIO_0, recovery_cycles, recovery_time, active_cycles, active_time);
#endif #endif
return (byte)((recovery_cycles << 4) | active_cycles); return (byte)((recovery_cycles << 4) | active_cycles);
} else { } else {
#ifdef DEBUG #ifdef DEBUG
printk("ht6560b: drive %s setting pio=0\n", drive->name); printk("ht6560b: drive %s setting pio=0\n", drive->name);
#endif #endif
return HT_TIMING_DEFAULT; /* default setting */ return HT_TIMING_DEFAULT; /* default setting */
} }
} }
...@@ -252,10 +252,10 @@ static void ht_set_prefetch(struct ata_device *drive, byte state) ...@@ -252,10 +252,10 @@ static void ht_set_prefetch(struct ata_device *drive, byte state)
{ {
unsigned long flags; unsigned long flags;
int t = HT_PREFETCH_MODE << 8; int t = HT_PREFETCH_MODE << 8;
save_flags (flags); /* all CPUs */ save_flags (flags); /* all CPUs */
cli(); /* all CPUs */ cli(); /* all CPUs */
/* /*
* Prefetch mode and unmask irq seems to conflict * Prefetch mode and unmask irq seems to conflict
*/ */
...@@ -267,9 +267,9 @@ static void ht_set_prefetch(struct ata_device *drive, byte state) ...@@ -267,9 +267,9 @@ static void ht_set_prefetch(struct ata_device *drive, byte state)
drive->drive_data &= ~t; /* disable prefetch mode */ drive->drive_data &= ~t; /* disable prefetch mode */
drive->channel->no_unmask = 0; drive->channel->no_unmask = 0;
} }
restore_flags (flags); /* all CPUs */ restore_flags (flags); /* all CPUs */
#ifdef DEBUG #ifdef DEBUG
printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis")); printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
#endif #endif
...@@ -279,24 +279,24 @@ static void tune_ht6560b(struct ata_device *drive, byte pio) ...@@ -279,24 +279,24 @@ static void tune_ht6560b(struct ata_device *drive, byte pio)
{ {
unsigned long flags; unsigned long flags;
byte timing; byte timing;
switch (pio) { switch (pio) {
case 8: /* set prefetch off */ case 8: /* set prefetch off */
case 9: /* set prefetch on */ case 9: /* set prefetch on */
ht_set_prefetch(drive, pio & 1); ht_set_prefetch(drive, pio & 1);
return; return;
} }
timing = ht_pio2timings(drive, pio); timing = ht_pio2timings(drive, pio);
save_flags (flags); /* all CPUs */ save_flags (flags); /* all CPUs */
cli(); /* all CPUs */ cli(); /* all CPUs */
drive->drive_data &= 0xff00; drive->drive_data &= 0xff00;
drive->drive_data |= timing; drive->drive_data |= timing;
restore_flags (flags); /* all CPUs */ restore_flags (flags); /* all CPUs */
#ifdef DEBUG #ifdef DEBUG
printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing); printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
#endif #endif
...@@ -305,7 +305,7 @@ static void tune_ht6560b(struct ata_device *drive, byte pio) ...@@ -305,7 +305,7 @@ static void tune_ht6560b(struct ata_device *drive, byte pio)
void __init init_ht6560b (void) void __init init_ht6560b (void)
{ {
int t; int t;
if (check_region(HT_CONFIG_PORT,1)) { if (check_region(HT_CONFIG_PORT,1)) {
printk(KERN_ERR "ht6560b: PORT %#x ALREADY IN USE\n", HT_CONFIG_PORT); printk(KERN_ERR "ht6560b: PORT %#x ALREADY IN USE\n", HT_CONFIG_PORT);
} else { } else {
......
...@@ -476,7 +476,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request * ...@@ -476,7 +476,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat); drive->name, dma_stat);
} }
return ide_error(drive, rq, "dma_intr", drive->status); return ata_error(drive, rq, __FUNCTION__);
} }
static int static int
......
...@@ -594,7 +594,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr ...@@ -594,7 +594,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
pc = (struct packet_command *) rq->special; pc = (struct packet_command *) rq->special;
pc->stat = 1; pc->stat = 1;
cdrom_end_request(drive, rq, 1); cdrom_end_request(drive, rq, 1);
*startstop = ide_error(drive, rq, "request sense failure", drive->status); *startstop = ata_error(drive, rq, "request sense failure");
return 1; return 1;
} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) { } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
...@@ -673,7 +673,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr ...@@ -673,7 +673,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
} else if ((err & ~ABRT_ERR) != 0) { } else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler /* Go to the default handler
for other errors. */ for other errors. */
*startstop = ide_error(drive, rq, __FUNCTION__, drive->status); *startstop = ata_error(drive, rq, __FUNCTION__);
return 1; return 1;
} else if ((++rq->errors > ERROR_MAX)) { } else if ((++rq->errors > ERROR_MAX)) {
/* We've racked up too many retries. Abort. */ /* We've racked up too many retries. Abort. */
...@@ -751,9 +751,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive, ...@@ -751,9 +751,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG); OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG); OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG);
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
if (info->dma) if (info->dma)
udma_start(drive, rq); udma_start(drive, rq);
...@@ -918,7 +916,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request ...@@ -918,7 +916,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
} else } else
return ide_error (drive, rq, "dma error", stat); return ata_error(drive, rq, "dma error");
} }
/* Read the interrupt reason and the transfer length. */ /* Read the interrupt reason and the transfer length. */
...@@ -1498,7 +1496,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request ...@@ -1498,7 +1496,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
*/ */
if (dma) { if (dma) {
if (dma_error) if (dma_error)
return ide_error(drive, rq, "dma error", stat); return ata_error(drive, rq, "dma error");
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
......
...@@ -257,14 +257,15 @@ static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request ...@@ -257,14 +257,15 @@ static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request
args.taskfile.sector_number = block; /* low lba */ args.taskfile.sector_number = block; /* low lba */
args.taskfile.low_cylinder = (block >>= 8); /* mid lba */ args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
args.taskfile.high_cylinder = (block >>= 8); /* hi lba */ args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
args.taskfile.device_head = drive->select.all;
args.hobfile.sector_number = (block >>= 8); /* low lba */ args.hobfile.sector_number = (block >>= 8); /* low lba */
args.hobfile.low_cylinder = (block >>= 8); /* mid lba */ args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
args.hobfile.high_cylinder = (block >>= 8); /* hi lba */ args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
args.hobfile.device_head = drive->select.all;
args.hobfile.control = 0x80;
args.taskfile.device_head = drive->select.all;
args.hobfile.device_head = args.taskfile.device_head;
args.hobfile.control = (drive->ctl|0x80);
args.taskfile.command = get_command(drive, rq_data_dir(rq)); args.taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
...@@ -727,7 +728,7 @@ static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req) ...@@ -727,7 +728,7 @@ static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
args.hobfile.high_cylinder = (addr_req >>= 8); args.hobfile.high_cylinder = (addr_req >>= 8);
args.hobfile.device_head = 0x40; args.hobfile.device_head = 0x40;
args.hobfile.control = (drive->ctl | 0x80); args.hobfile.control = 0x80;
args.handler = task_no_data_intr; args.handler = task_no_data_intr;
/* submit command request */ /* submit command request */
......
...@@ -1064,8 +1064,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1064,8 +1064,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
} }
#endif #endif
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */
OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
......
...@@ -434,7 +434,7 @@ pmac_ide_do_setfeature(struct ata_device *drive, u8 command) ...@@ -434,7 +434,7 @@ pmac_ide_do_setfeature(struct ata_device *drive, u8 command)
goto out; goto out;
} }
udelay(10); udelay(10);
OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); ata_irq_enale(drive, 0);
OUT_BYTE(command, IDE_NSECTOR_REG); OUT_BYTE(command, IDE_NSECTOR_REG);
OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
...@@ -443,7 +443,7 @@ pmac_ide_do_setfeature(struct ata_device *drive, u8 command) ...@@ -443,7 +443,7 @@ pmac_ide_do_setfeature(struct ata_device *drive, u8 command)
ide__sti(); /* local CPU only -- for jiffies */ ide__sti(); /* local CPU only -- for jiffies */
result = wait_for_ready(drive); result = wait_for_ready(drive);
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); ata_irq_enable(drive, 1);
if (result) if (result)
printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n"); printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
out: out:
...@@ -1330,7 +1330,7 @@ pmac_ide_check_dma(struct ata_device *drive) ...@@ -1330,7 +1330,7 @@ pmac_ide_check_dma(struct ata_device *drive)
/* Normal MultiWord DMA modes. */ /* Normal MultiWord DMA modes. */
drive->using_dma = pmac_ide_mdma_enable(drive, idx); drive->using_dma = pmac_ide_mdma_enable(drive, idx);
} }
OUT_BYTE(0, IDE_CONTROL_REG); ata_irq_enable(drive, 1);
/* Apply settings to controller */ /* Apply settings to controller */
pmac_ide_selectproc(drive); pmac_ide_selectproc(drive);
} }
......
...@@ -2263,8 +2263,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, ...@@ -2263,8 +2263,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
} }
#endif #endif
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
OUT_BYTE (dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ OUT_BYTE (dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */
OUT_BYTE (bcount.b.high, IDE_BCOUNTH_REG); OUT_BYTE (bcount.b.high, IDE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low, IDE_BCOUNTL_REG); OUT_BYTE (bcount.b.low, IDE_BCOUNTL_REG);
......
...@@ -169,12 +169,12 @@ int drive_is_ready(struct ata_device *drive) ...@@ -169,12 +169,12 @@ int drive_is_ready(struct ata_device *drive)
if (drive->waiting_for_dma) if (drive->waiting_for_dma)
return udma_irq_status(drive); return udma_irq_status(drive);
#if 0 /*
/* need to guarantee 400ns since last command was issued */ * Need to guarantee 400ns since last command was issued?
udelay(1); */
#endif
/* FIXME: promote this to the general status read method perhaps */ /* FIXME: promote this to the general status read method perhaps.
*/
#ifdef CONFIG_IDEPCI_SHARE_IRQ #ifdef CONFIG_IDEPCI_SHARE_IRQ
/* /*
* We do a passive status test under shared PCI interrupts on * We do a passive status test under shared PCI interrupts on
...@@ -182,16 +182,16 @@ int drive_is_ready(struct ata_device *drive) ...@@ -182,16 +182,16 @@ int drive_is_ready(struct ata_device *drive)
* an interrupt with another pci card/device. We make no assumptions * an interrupt with another pci card/device. We make no assumptions
* about possible isa-pnp and pci-pnp issues yet. * about possible isa-pnp and pci-pnp issues yet.
*/ */
if (IDE_CONTROL_REG) if (drive->channel->io_ports[IDE_CONTROL_OFFSET])
drive->status = GET_ALTSTAT(); drive->status = GET_ALTSTAT();
else else
#endif #endif
ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ!! */ ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ! */
if (drive->status & BUSY_STAT) if (drive->status & BUSY_STAT)
return 0; /* drive busy: definitely not interrupting */ return 0; /* drive busy: definitely not interrupting */
return 1; /* drive ready: *might* be interrupting */ return 1; /* drive ready: *might* be interrupting */
} }
/* /*
...@@ -246,7 +246,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -246,7 +246,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
if (!ok || !rq->nr_sectors) { if (!ok || !rq->nr_sectors) {
if (drive->status & (ERR_STAT | DRQ_STAT)) { if (drive->status & (ERR_STAT | DRQ_STAT)) {
startstop = ide_error(drive, rq, __FUNCTION__, drive->status); startstop = ata_error(drive, rq, __FUNCTION__);
return startstop; return startstop;
} }
...@@ -316,24 +316,9 @@ ide_startstop_t ata_taskfile(struct ata_device *drive, ...@@ -316,24 +316,9 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF; u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
#if 0
printk("ata_taskfile ... %p\n", args->handler);
printk(" sector feature %02x\n", args->taskfile.feature);
printk(" sector count %02x\n", args->taskfile.sector_count);
printk(" drive/head %02x\n", args->taskfile.device_head);
printk(" command %02x\n", args->taskfile.command);
if (rq)
printk(" rq->nr_sectors %2li\n", rq->nr_sectors);
else
printk(" rq-> = null\n");
#endif
/* (ks/hs): Moved to start, do not use for multiple out commands */ /* (ks/hs): Moved to start, do not use for multiple out commands */
if (args->handler != task_mulout_intr) { if (args->handler != task_mulout_intr) {
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
ata_mask(drive); ata_mask(drive);
} }
...@@ -412,7 +397,7 @@ ide_startstop_t ata_taskfile(struct ata_device *drive, ...@@ -412,7 +397,7 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq) ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
{ {
if (!ata_status(drive, READY_STAT, BAD_STAT)) if (!ata_status(drive, READY_STAT, BAD_STAT))
return ide_error(drive, rq, "recal_intr", drive->status); return ata_error(drive, rq, __FUNCTION__);
return ide_stopped; return ide_stopped;
} }
...@@ -429,7 +414,7 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq) ...@@ -429,7 +414,7 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
if (!ata_status(drive, READY_STAT, BAD_STAT)) { if (!ata_status(drive, READY_STAT, BAD_STAT)) {
/* Keep quiet for NOP because it is expected to fail. */ /* Keep quiet for NOP because it is expected to fail. */
if (args && args->taskfile.command != WIN_NOP) if (args && args->taskfile.command != WIN_NOP)
return ide_error(drive, rq, "task_no_data_intr", drive->status); return ata_error(drive, rq, __FUNCTION__);
} }
if (args) if (args)
...@@ -443,12 +428,12 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq) ...@@ -443,12 +428,12 @@ ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
*/ */
static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{ {
char *pBuf = NULL; char *buf = NULL;
unsigned long flags; unsigned long flags;
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
if (drive->status & (ERR_STAT|DRQ_STAT)) if (drive->status & (ERR_STAT|DRQ_STAT))
return ide_error(drive, rq, __FUNCTION__, drive->status); return ata_error(drive, rq, __FUNCTION__);
if (!(drive->status & BUSY_STAT)) { if (!(drive->status & BUSY_STAT)) {
DTF("task_in_intr to Soon wait for next interrupt\n"); DTF("task_in_intr to Soon wait for next interrupt\n");
...@@ -458,11 +443,11 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq ...@@ -458,11 +443,11 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
} }
} }
DTF("stat: %02x\n", drive->status); DTF("stat: %02x\n", drive->status);
pBuf = ide_map_rq(rq, &flags); buf = ide_map_rq(rq, &flags);
DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); DTF("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
ata_read(drive, pBuf, SECTOR_WORDS); ata_read(drive, buf, SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, buf, &flags);
/* First segment of the request is complete. note that this does not /* First segment of the request is complete. note that this does not
* necessarily mean that the entire request is done!! this is only true * necessarily mean that the entire request is done!! this is only true
...@@ -512,22 +497,22 @@ static ide_startstop_t pre_task_out_intr(struct ata_device *drive, struct reques ...@@ -512,22 +497,22 @@ static ide_startstop_t pre_task_out_intr(struct ata_device *drive, struct reques
*/ */
static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
{ {
char *pBuf = NULL; char *buf = NULL;
unsigned long flags; unsigned long flags;
if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
return ide_error(drive, rq, __FUNCTION__, drive->status); return ata_error(drive, rq, __FUNCTION__);
if (!rq->current_nr_sectors) if (!rq->current_nr_sectors)
if (!ide_end_request(drive, rq, 1)) if (!ide_end_request(drive, rq, 1))
return ide_stopped; return ide_stopped;
if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) { if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
pBuf = ide_map_rq(rq, &flags); buf = ide_map_rq(rq, &flags);
DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); DTF("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
ata_write(drive, pBuf, SECTOR_WORDS); ata_write(drive, buf, SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, buf, &flags);
rq->errors = 0; rq->errors = 0;
rq->current_nr_sectors--; rq->current_nr_sectors--;
} }
...@@ -542,14 +527,14 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -542,14 +527,14 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
*/ */
static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
{ {
char *pBuf = NULL; char *buf = NULL;
unsigned int msect, nsect; unsigned int msect, nsect;
unsigned long flags; unsigned long flags;
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
if (drive->status & (ERR_STAT|DRQ_STAT)) { if (drive->status & (ERR_STAT|DRQ_STAT))
return ide_error(drive, rq, __FUNCTION__, drive->status); return ata_error(drive, rq, __FUNCTION__);
}
/* no data yet, so wait for another interrupt */ /* no data yet, so wait for another interrupt */
ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
...@@ -563,12 +548,12 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request ...@@ -563,12 +548,12 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
if (nsect > msect) if (nsect > msect)
nsect = msect; nsect = msect;
pBuf = ide_map_rq(rq, &flags); buf = ide_map_rq(rq, &flags);
DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n", DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
pBuf, nsect, rq->current_nr_sectors); buf, nsect, rq->current_nr_sectors);
ata_read(drive, pBuf, nsect * SECTOR_WORDS); ata_read(drive, buf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, buf, &flags);
rq->errors = 0; rq->errors = 0;
rq->current_nr_sectors -= nsect; rq->current_nr_sectors -= nsect;
msect -= nsect; msect -= nsect;
......
...@@ -378,42 +378,6 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi) ...@@ -378,42 +378,6 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
for (unit = 0; unit < MAX_DRIVES; ++unit) for (unit = 0; unit < MAX_DRIVES; ++unit)
check_crc_errors(&ch->drives[unit]); check_crc_errors(&ch->drives[unit]);
#if OK_TO_RESET_CONTROLLER
if (!IDE_CONTROL_REG) {
__restore_flags(flags);
return ide_stopped;
}
/*
* Note that we also set nIEN while resetting the device,
* to mask unwanted interrupts from the interface during the reset.
* However, due to the design of PC hardware, this will cause an
* immediate interrupt due to the edge transition it produces.
* This single interrupt gives us a "fast poll" for drives that
* recover from reset very quickly, saving us the first 50ms wait time.
*/
OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */
udelay(10); /* more than enough time */
if (drive->quirk_list == 2) {
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear SRST and nIEN */
} else {
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
}
udelay(10); /* more than enough time */
ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler(drive, reset_pollfunc, HZ/20, NULL);
/*
* Some weird controller like resetting themselves to a strange
* state when the disks are reset this way. At least, the Winbond
* 553 documentation says that
*/
if (ch->resetproc != NULL)
ch->resetproc(drive);
/* FIXME: we should handle mulit mode setting here as well ! */
#endif
__restore_flags (flags); /* local CPU only */ __restore_flags (flags); /* local CPU only */
return ide_started; return ide_started;
...@@ -421,8 +385,8 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi) ...@@ -421,8 +385,8 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
static inline u32 read_24(struct ata_device *drive) static inline u32 read_24(struct ata_device *drive)
{ {
return (IN_BYTE(IDE_HCYL_REG)<<16) | return (IN_BYTE(IDE_HCYL_REG) << 16) |
(IN_BYTE(IDE_LCYL_REG)<<8) | (IN_BYTE(IDE_LCYL_REG) << 8) |
IN_BYTE(IDE_SECTOR_REG); IN_BYTE(IDE_SECTOR_REG);
} }
...@@ -457,11 +421,9 @@ void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 err) ...@@ -457,11 +421,9 @@ void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 err)
(drive->id->cfs_enable_2 & 0x0400) && (drive->id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
/* The following command goes to the hob file! */ /* The following command goes to the hob file! */
OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG);
args->hobfile.feature = IN_BYTE(IDE_FEATURE_REG); args->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
args->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG); args->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
args->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG); args->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
args->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG); args->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG); args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
...@@ -547,13 +509,13 @@ u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *ms ...@@ -547,13 +509,13 @@ u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *ms
__u64 sectors = 0; __u64 sectors = 0;
u32 low = 0, high = 0; u32 low = 0, high = 0;
low = read_24(drive); low = read_24(drive);
OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG); OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
high = read_24(drive); high = read_24(drive);
sectors = ((__u64)high << 24) | low; sectors = ((__u64)high << 24) | low;
printk(", LBAsect=%lld, high=%d, low=%d", (long long) sectors, high, low); printk(", LBAsect=%lld, high=%d, low=%d", (long long) sectors, high, low);
} else { } else {
byte cur = IN_BYTE(IDE_SELECT_REG); u8 cur = IN_BYTE(IDE_SELECT_REG);
if (cur & 0x40) { /* using LBA? */ if (cur & 0x40) { /* using LBA? */
printk(", LBAsect=%ld", (unsigned long) printk(", LBAsect=%ld", (unsigned long)
((cur&0xf)<<24) ((cur&0xf)<<24)
...@@ -632,9 +594,10 @@ static int do_recalibrate(struct ata_device *drive) ...@@ -632,9 +594,10 @@ static int do_recalibrate(struct ata_device *drive)
/* /*
* Take action based on the error returned by the drive. * Take action based on the error returned by the drive.
*/ */
ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const char *msg, byte stat) ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg)
{ {
byte err; u8 err;
u8 stat = drive->status;
err = ide_dump_status(drive, rq, msg, stat); err = ide_dump_status(drive, rq, msg, stat);
if (!drive || !rq) if (!drive || !rq)
...@@ -645,18 +608,18 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch ...@@ -645,18 +608,18 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch
ide_end_drive_cmd(drive, rq, err); ide_end_drive_cmd(drive, rq, err);
return ide_stopped; return ide_stopped;
} }
/* other bits are useless when BUSY */
if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */ if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr))
rq->errors |= ERROR_RESET; rq->errors |= ERROR_RESET; /* FIXME: What's that?! */
} else { else {
if (drive->type == ATA_DISK && (stat & ERR_STAT)) { if (drive->type == ATA_DISK && (stat & ERR_STAT)) {
/* err has different meaning on cdrom and tape */ /* err has different meaning on cdrom and tape */
if (err == ABRT_ERR) { if (err == ABRT_ERR) {
if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY) if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
return ide_stopped; /* some newer drives don't support WIN_SPECIFY */ return ide_stopped; /* some newer drives don't support WIN_SPECIFY */
} else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) { } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR))
drive->crc_count++; /* UDMA crc error -- just retry the operation */ drive->crc_count++; /* UDMA crc error -- just retry the operation */
} else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
rq->errors = ERROR_MAX; rq->errors = ERROR_MAX;
else if (err & TRK0_ERR) /* help it find track zero */ else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL; rq->errors |= ERROR_RECAL;
...@@ -665,7 +628,8 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch ...@@ -665,7 +628,8 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
try_to_flush_leftover_data(drive); try_to_flush_leftover_data(drive);
} }
if (!ata_status(drive, 0, BUSY_STAT|DRQ_STAT))
if (!ata_status(drive, 0, BUSY_STAT | DRQ_STAT))
OUT_BYTE(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); /* force an abort */ OUT_BYTE(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); /* force an abort */
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
...@@ -680,6 +644,7 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch ...@@ -680,6 +644,7 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
return do_recalibrate(drive); return do_recalibrate(drive);
} }
return ide_stopped; return ide_stopped;
} }
...@@ -689,10 +654,11 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch ...@@ -689,10 +654,11 @@ ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const ch
static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq)
{ {
u8 *args = rq->buffer; u8 *args = rq->buffer;
int retries = 10;
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
if (!ata_status(drive, 0, DRQ_STAT) && args && args[3]) { if (!ata_status(drive, 0, DRQ_STAT) && args && args[3]) {
int retries = 10;
ata_read(drive, &args[4], args[3] * SECTOR_WORDS); ata_read(drive, &args[4], args[3] * SECTOR_WORDS);
while (!ata_status(drive, 0, BUSY_STAT) && retries--) while (!ata_status(drive, 0, BUSY_STAT) && retries--)
...@@ -700,7 +666,7 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request * ...@@ -700,7 +666,7 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *
} }
if (!ata_status(drive, READY_STAT, BAD_STAT)) if (!ata_status(drive, READY_STAT, BAD_STAT))
return ide_error(drive, rq, "drive_cmd", drive->status); /* already calls ide_end_drive_cmd */ return ata_error(drive, rq, __FUNCTION__); /* already calls ide_end_drive_cmd */
ide_end_drive_cmd(drive, rq, GET_ERR()); ide_end_drive_cmd(drive, rq, GET_ERR());
return ide_stopped; return ide_stopped;
...@@ -712,8 +678,7 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request * ...@@ -712,8 +678,7 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *
static void drive_cmd(struct ata_device *drive, u8 cmd, u8 nsect) static void drive_cmd(struct ata_device *drive, u8 cmd, u8 nsect)
{ {
ide_set_handler(drive, drive_cmd_intr, WAIT_CMD, NULL); ide_set_handler(drive, drive_cmd_intr, WAIT_CMD, NULL);
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
ata_mask(drive); ata_mask(drive);
OUT_BYTE(nsect, IDE_NSECTOR_REG); OUT_BYTE(nsect, IDE_NSECTOR_REG);
OUT_BYTE(cmd, IDE_COMMAND_REG); OUT_BYTE(cmd, IDE_COMMAND_REG);
...@@ -723,7 +688,7 @@ static void drive_cmd(struct ata_device *drive, u8 cmd, u8 nsect) ...@@ -723,7 +688,7 @@ static void drive_cmd(struct ata_device *drive, u8 cmd, u8 nsect)
/* /*
* Busy-wait for the drive status to be not "busy". Check then the status for * Busy-wait for the drive status to be not "busy". Check then the status for
* all of the "good" bits and none of the "bad" bits, and if all is okay it * all of the "good" bits and none of the "bad" bits, and if all is okay it
* returns 0. All other cases return 1 after invoking ide_error() -- caller * returns 0. All other cases return 1 after invoking error handler -- caller
* should just return. * should just return.
* *
* This routine should get fixed to not hog the cpu during extra long waits.. * This routine should get fixed to not hog the cpu during extra long waits..
...@@ -744,12 +709,13 @@ int ide_wait_stat(ide_startstop_t *startstop, ...@@ -744,12 +709,13 @@ int ide_wait_stat(ide_startstop_t *startstop,
return 1; return 1;
} }
udelay(1); /* spec allows drive 400ns to assert "BUSY" */ /* spec allows drive 400ns to assert "BUSY" */
udelay(1);
if (!ata_status(drive, 0, BUSY_STAT)) { if (!ata_status(drive, 0, BUSY_STAT)) {
timeout += jiffies; timeout += jiffies;
while (!ata_status(drive, 0, BUSY_STAT)) { while (!ata_status(drive, 0, BUSY_STAT)) {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
*startstop = ide_error(drive, rq, "status timeout", drive->status); *startstop = ata_error(drive, rq, "status timeout");
return 1; return 1;
} }
} }
...@@ -766,7 +732,7 @@ int ide_wait_stat(ide_startstop_t *startstop, ...@@ -766,7 +732,7 @@ int ide_wait_stat(ide_startstop_t *startstop,
if (ata_status(drive, good, bad)) if (ata_status(drive, good, bad))
return 0; return 0;
} }
*startstop = ide_error(drive, rq, "status error", drive->status); *startstop = ata_error(drive, rq, "status error");
return 1; return 1;
} }
...@@ -1134,15 +1100,15 @@ static void do_request(struct ata_channel *channel) ...@@ -1134,15 +1100,15 @@ static void do_request(struct ata_channel *channel)
ch = drive->channel; ch = drive->channel;
if (channel->sharing_irq && ch != channel && ch->io_ports[IDE_CONTROL_OFFSET]) { /* Disable intrerrupts from the drive on the previous channel.
/* set nIEN for previous channel */ *
/* FIXME: check this! It appears to act on the current channel! */ * FIXME: This should be only done if we are indeed sharing the same
* interrupt line with it.
if (ch->intrproc) *
ch->intrproc(drive); * FIXME: check this! It appears to act on the current channel!
else */
OUT_BYTE((drive)->ctl|2, ch->io_ports[IDE_CONTROL_OFFSET]); if (ch != channel && channel->sharing_irq && ch->irq == channel->irq)
} ata_irq_enable(drive, 0);
/* Remember the last drive we where acting on. /* Remember the last drive we where acting on.
*/ */
...@@ -1279,7 +1245,7 @@ void ide_timer_expiry(unsigned long data) ...@@ -1279,7 +1245,7 @@ void ide_timer_expiry(unsigned long data)
startstop = ide_stopped; startstop = ide_stopped;
dma_timeout_retry(drive, drive->rq); dma_timeout_retry(drive, drive->rq);
} else } else
startstop = ide_error(drive, drive->rq, "irq timeout", drive->status); startstop = ata_error(drive, drive->rq, "irq timeout");
} }
enable_irq(ch->irq); enable_irq(ch->irq);
...@@ -1571,33 +1537,6 @@ static int ide_check_media_change(kdev_t i_rdev) ...@@ -1571,33 +1537,6 @@ static int ide_check_media_change(kdev_t i_rdev)
return res; return res;
} }
void ide_fixstring (byte *s, const int bytecount, const int byteswap)
{
byte *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */
if (byteswap) {
/* convert from big-endian to host byte order */
for (p = end ; p != s;) {
unsigned short *pp = (unsigned short *) (p -= 2);
*pp = ntohs(*pp);
}
}
/* strip leading blanks */
while (s != end && *s == ' ')
++s;
/* compress internal blanks and strip trailing blanks */
while (s != end && *s) {
if (*s++ != ' ' || (s != end && *s && *s != ' '))
*p++ = *(s-1);
}
/* wipe out trailing garbage */
while (p != end)
*p++ = '\0';
}
struct block_device_operations ide_fops[] = {{ struct block_device_operations ide_fops[] = {{
owner: THIS_MODULE, owner: THIS_MODULE,
open: ide_open, open: ide_open,
...@@ -1616,8 +1555,8 @@ EXPORT_SYMBOL(do_ide_request); ...@@ -1616,8 +1555,8 @@ EXPORT_SYMBOL(do_ide_request);
EXPORT_SYMBOL(ide_set_handler); EXPORT_SYMBOL(ide_set_handler);
EXPORT_SYMBOL(ide_dump_status); EXPORT_SYMBOL(ide_dump_status);
EXPORT_SYMBOL(ide_error); EXPORT_SYMBOL(ata_error);
EXPORT_SYMBOL(ide_fixstring);
EXPORT_SYMBOL(ide_wait_stat); EXPORT_SYMBOL(ide_wait_stat);
EXPORT_SYMBOL(restart_request); EXPORT_SYMBOL(restart_request);
EXPORT_SYMBOL(ide_end_drive_cmd); EXPORT_SYMBOL(ide_end_drive_cmd);
......
...@@ -205,9 +205,8 @@ static void init_hwif_data(struct ata_channel *ch, unsigned int index) ...@@ -205,9 +205,8 @@ static void init_hwif_data(struct ata_channel *ch, unsigned int index)
struct ata_device *drive = &ch->drives[unit]; struct ata_device *drive = &ch->drives[unit];
drive->type = ATA_DISK; drive->type = ATA_DISK;
drive->select.all = (unit<<4)|0xa0; drive->select.all = (unit << 4) | 0xa0;
drive->channel = ch; drive->channel = ch;
drive->ctl = 0x08;
drive->ready_stat = READY_STAT; drive->ready_stat = READY_STAT;
drive->bad_wstat = BAD_W_STAT; drive->bad_wstat = BAD_W_STAT;
sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit); sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit);
......
...@@ -141,10 +141,6 @@ static void __init ide_init_ns87415(struct ata_channel *hwif) ...@@ -141,10 +141,6 @@ static void __init ide_init_ns87415(struct ata_channel *hwif)
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
unsigned int ctrl, using_inta; unsigned int ctrl, using_inta;
byte progif; byte progif;
#ifdef __sparc_v9__
int timeout;
byte stat;
#endif
/* Set a good latency timer and cache line size value. */ /* Set a good latency timer and cache line size value. */
(void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
...@@ -197,16 +193,7 @@ static void __init ide_init_ns87415(struct ata_channel *hwif) ...@@ -197,16 +193,7 @@ static void __init ide_init_ns87415(struct ata_channel *hwif)
* XXX: Reset the device, if we don't it will not respond * XXX: Reset the device, if we don't it will not respond
* to select properly during first probe. * to select properly during first probe.
*/ */
timeout = 10000; ata_reset(struct ata_channel *hwif);
outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10);
outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do {
udelay(50);
stat = inb(hwif->io_ports[IDE_STATUS_OFFSET]);
if (stat == 0xff)
break;
} while ((stat & BUSY_STAT) && --timeout);
#endif #endif
} }
......
...@@ -41,6 +41,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq) ...@@ -41,6 +41,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
{ {
u8 dma_stat; u8 dma_stat;
dma_stat = udma_stop(drive); dma_stat = udma_stop(drive);
if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
if (!dma_stat) { if (!dma_stat) {
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
...@@ -49,7 +50,8 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq) ...@@ -49,7 +50,8 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat); drive->name, dma_stat);
} }
return ide_error(drive, rq, "dma_intr", drive->status);
return ata_error(drive, rq, __FUNCTION__);
} }
/* /*
...@@ -118,7 +120,7 @@ static int build_sglist(struct ata_channel *ch, struct request *rq) ...@@ -118,7 +120,7 @@ static int build_sglist(struct ata_channel *ch, struct request *rq)
static int dma_timer_expiry(struct ata_device *drive, struct request *rq) static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
{ {
/* FIXME: What's that? */ /* FIXME: What's that? */
u8 dma_stat = inb(drive->channel->dma_base+2); u8 dma_stat = inb(drive->channel->dma_base + 2);
#ifdef DEBUG #ifdef DEBUG
printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat); printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat);
...@@ -130,10 +132,11 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *rq) ...@@ -130,10 +132,11 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
if (dma_stat & 2) { /* ERROR */ if (dma_stat & 2) { /* ERROR */
ata_status(drive, 0, 0); ata_status(drive, 0, 0);
return ide_error(drive, rq, "dma_timer_expiry", drive->status); return ata_error(drive, rq, __FUNCTION__);
} }
if (dma_stat & 1) /* DMAing */ if (dma_stat & 1) /* DMAing */
return WAIT_CMD; return WAIT_CMD;
return 0; return 0;
} }
......
...@@ -686,9 +686,11 @@ static int pdc202xx_dmaproc(struct ata_device *drive) ...@@ -686,9 +686,11 @@ static int pdc202xx_dmaproc(struct ata_device *drive)
void pdc202xx_new_reset(struct ata_device *drive) void pdc202xx_new_reset(struct ata_device *drive)
{ {
set_reg_and_wait(0x04,IDE_CONTROL_REG, 1000); ata_reset(drive->channel);
set_reg_and_wait(0x00,IDE_CONTROL_REG, 1000); mdelay(1000);
printk("PDC202XX: %s channel reset.\n", ata_irq_enable(drive, 1);
mdelay(1000);
printk(KERN_INFO "PDC202XX: %s channel reset.\n",
drive->channel->unit ? "Secondary" : "Primary"); drive->channel->unit ? "Secondary" : "Primary");
} }
......
...@@ -243,9 +243,8 @@ int __init setup_pdc4030(struct ata_channel *hwif) ...@@ -243,9 +243,8 @@ int __init setup_pdc4030(struct ata_channel *hwif)
if (inb(IDE_NSECTOR_REG) == 0xFF || inb(IDE_SECTOR_REG) == 0xFF) { if (inb(IDE_NSECTOR_REG) == 0xFF || inb(IDE_SECTOR_REG) == 0xFF) {
return 0; return 0;
} }
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
outb(0x08, IDE_CONTROL_REG); if (pdc4030_cmd(drive, PROMISE_GET_CONFIG)) {
if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
return 0; return 0;
} }
if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) { if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
...@@ -379,7 +378,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -379,7 +378,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
char *to; char *to;
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) if (!ata_status(drive, DATA_READY, BAD_R_STAT))
return ide_error(drive, rq, "promise_read_intr", drive->status); return ata_error(drive, rq, __FUNCTION__);
read_again: read_again:
do { do {
...@@ -438,7 +437,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -438,7 +437,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
} }
printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left " printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
"!DRQ !BUSY\n", drive->name); "!DRQ !BUSY\n", drive->name);
return ide_error(drive, rq, "promise read intr", drive->status); return ata_error(drive, rq, "promise read intr");
} }
return ide_stopped; return ide_stopped;
} }
...@@ -463,7 +462,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc ...@@ -463,7 +462,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc
ch->poll_timeout = 0; ch->poll_timeout = 0;
printk(KERN_ERR "%s: completion timeout - still busy!\n", printk(KERN_ERR "%s: completion timeout - still busy!\n",
drive->name); drive->name);
return ide_error(drive, rq, "busy timeout", drive->status); return ata_error(drive, rq, "busy timeout");
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
...@@ -540,9 +539,9 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r ...@@ -540,9 +539,9 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
return ide_started; /* continue polling... */ return ide_started; /* continue polling... */
} }
ch->poll_timeout = 0; ch->poll_timeout = 0;
printk(KERN_ERR "%s: write timed out!\n",drive->name); printk(KERN_ERR "%s: write timed out!\n", drive->name);
ata_status(drive, 0, 0); ata_status(drive, 0, 0);
return ide_error(drive, rq, "write timeout", drive->status); return ata_error(drive, rq, "write timeout");
} }
/* /*
...@@ -616,11 +615,11 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -616,11 +615,11 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "pdc4030 bad flags"); blk_dump_rq_flags(rq, "pdc4030 bad flags");
ide_end_request(drive, rq, 0); ide_end_request(drive, rq, 0);
return ide_stopped; return ide_stopped;
} }
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1); /* clear nIEN */
outb(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
ata_mask(drive); ata_mask(drive);
outb(taskfile->feature, IDE_FEATURE_REG); outb(taskfile->feature, IDE_FEATURE_REG);
......
...@@ -267,6 +267,34 @@ void ata_fix_driveid(struct hd_driveid *id) ...@@ -267,6 +267,34 @@ void ata_fix_driveid(struct hd_driveid *id)
#endif #endif
} }
void ide_fixstring(char *s, const int bytecount, const int byteswap)
{
char *p = s;
char *end = &s[bytecount & ~1]; /* bytecount must be even */
if (byteswap) {
/* convert from big-endian to host byte order */
for (p = end ; p != s;) {
unsigned short *pp = (unsigned short *) (p -= 2);
*pp = ntohs(*pp);
}
}
/* strip leading blanks */
while (s != end && *s == ' ')
++s;
/* compress internal blanks and strip trailing blanks */
while (s != end && *s) {
if (*s++ != ' ' || (s != end && *s && *s != ' '))
*p++ = *(s-1);
}
/* wipe out trailing garbage */
while (p != end)
*p++ = '\0';
}
/* /*
* All hosts that use the 80c ribbon must use this! * All hosts that use the 80c ribbon must use this!
*/ */
...@@ -280,7 +308,7 @@ byte eighty_ninty_three(struct ata_device *drive) ...@@ -280,7 +308,7 @@ byte eighty_ninty_three(struct ata_device *drive)
} }
/* /*
* Similar to ide_wait_stat(), except it never calls ide_error internally. * Similar to ide_wait_stat(), except it never calls ata_error internally.
* This is a kludge to handle the new ide_config_drive_speed() function, * This is a kludge to handle the new ide_config_drive_speed() function,
* and should not otherwise be used anywhere. Eventually, the tuneproc's * and should not otherwise be used anywhere. Eventually, the tuneproc's
* should be updated to return ide_startstop_t, in which case we can get * should be updated to return ide_startstop_t, in which case we can get
...@@ -292,13 +320,13 @@ byte eighty_ninty_three(struct ata_device *drive) ...@@ -292,13 +320,13 @@ byte eighty_ninty_three(struct ata_device *drive)
*/ */
int ide_config_drive_speed(struct ata_device *drive, byte speed) int ide_config_drive_speed(struct ata_device *drive, byte speed)
{ {
struct ata_channel *hwif = drive->channel; struct ata_channel *ch = drive->channel;
int i; int i;
int error = 1; int error = 1;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__) #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
outb(inb(hwif->dma_base + 2) & ~(1 << (5 + unit)), hwif->dma_base + 2); outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
#endif #endif
/* /*
...@@ -309,18 +337,17 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -309,18 +337,17 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
/* /*
* Select the drive, and issue the SETFEATURES command * Select the drive, and issue the SETFEATURES command
*/ */
disable_irq(hwif->irq); /* disable_irq_nosync ?? */ disable_irq(ch->irq); /* disable_irq_nosync ?? */
udelay(1); udelay(1);
ata_select(drive, 0); ata_select(drive, 0);
ata_mask(drive); ata_mask(drive);
udelay(1); udelay(1);
if (IDE_CONTROL_REG) ata_irq_enable(drive, 0);
OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
OUT_BYTE(speed, IDE_NSECTOR_REG); OUT_BYTE(speed, IDE_NSECTOR_REG);
OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) if (drive->quirk_list == 2)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); ata_irq_enable(drive, 1);
udelay(1); udelay(1);
/* /*
...@@ -355,7 +382,7 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -355,7 +382,7 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
ata_mask(drive); ata_mask(drive);
enable_irq(hwif->irq); enable_irq(ch->irq);
if (error) { if (error) {
ide_dump_status(drive, NULL, "set_drive_speed_status", drive->status); ide_dump_status(drive, NULL, "set_drive_speed_status", drive->status);
...@@ -368,9 +395,9 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -368,9 +395,9 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__) #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
if (speed > XFER_PIO_4) { if (speed > XFER_PIO_4) {
outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); outb(inb(ch->dma_base + 2)|(1 << (5 + unit)), ch->dma_base + 2);
} else { } else {
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
} }
#endif #endif
...@@ -391,6 +418,7 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -391,6 +418,7 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
default: break; default: break;
} }
return error; return error;
} }
...@@ -446,9 +474,9 @@ static inline void do_identify(struct ata_device *drive, u8 cmd) ...@@ -446,9 +474,9 @@ static inline void do_identify(struct ata_device *drive, u8 cmd)
|| (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */ || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
bswap ^= 1; /* Vertos drives may still be weird */ bswap ^= 1; /* Vertos drives may still be weird */
} }
ide_fixstring (id->model, sizeof(id->model), bswap); ide_fixstring(id->model, sizeof(id->model), bswap);
ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);
if (strstr(id->model, "E X A B Y T E N E S T")) if (strstr(id->model, "E X A B Y T E N E S T"))
goto err_misc; goto err_misc;
...@@ -566,36 +594,40 @@ static inline void do_identify(struct ata_device *drive, u8 cmd) ...@@ -566,36 +594,40 @@ static inline void do_identify(struct ata_device *drive, u8 cmd)
*/ */
static int identify(struct ata_device *drive, u8 cmd) static int identify(struct ata_device *drive, u8 cmd)
{ {
int rc; struct ata_channel *ch = drive->channel;
int rc = 1;
int autoprobe = 0; int autoprobe = 0;
unsigned long cookie = 0; unsigned long cookie = 0;
ide_ioreg_t hd_status; ide_ioreg_t hd_status;
unsigned long timeout; unsigned long timeout;
u8 s;
u8 a;
if (IDE_CONTROL_REG && !drive->channel->irq) { /* FIXME: perhaps we should be just using allways the status register,
autoprobe = 1; * since it should simplify the code significantly.
cookie = probe_irq_on(); */
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ if (ch->io_ports[IDE_CONTROL_OFFSET]) {
} u8 s;
u8 a;
if (!drive->channel->irq) {
autoprobe = 1;
cookie = probe_irq_on();
ata_irq_enable(drive, 1); /* enable device irq */
}
rc = 1;
if (IDE_CONTROL_REG) {
/* take a deep breath */ /* take a deep breath */
mdelay(50); mdelay(50);
a = IN_BYTE(IDE_ALTSTATUS_REG); a = IN_BYTE(ch->io_ports[IDE_ALTSTATUS_OFFSET]);
s = IN_BYTE(IDE_STATUS_REG); s = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
if ((a ^ s) & ~INDEX_STAT) { if ((a ^ s) & ~INDEX_STAT) {
printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a); printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a);
hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */ hd_status = ch->io_ports[IDE_STATUS_OFFSET]; /* ancient Seagate drives, broken interfaces */
} else { } else {
hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */ hd_status = ch->io_ports[IDE_ALTSTATUS_OFFSET]; /* use non-intrusive polling */
} }
} else { } else {
mdelay(50); mdelay(50);
hd_status = IDE_STATUS_REG; hd_status = ch->io_ports[IDE_STATUS_OFFSET];
} }
/* set features register for atapi identify command to be sure of reply */ /* set features register for atapi identify command to be sure of reply */
...@@ -637,8 +669,8 @@ static int identify(struct ata_device *drive, u8 cmd) ...@@ -637,8 +669,8 @@ static int identify(struct ata_device *drive, u8 cmd)
if (autoprobe) { if (autoprobe) {
int irq; int irq;
OUT_BYTE(drive->ctl | 0x02, IDE_CONTROL_REG); /* mask device irq */ ata_irq_enable(drive, 0); /* mask device irq */
ata_status(drive, 0, 0); /* clear drive IRQ */ ata_status(drive, 0, 0); /* clear drive IRQ */
udelay(5); udelay(5);
irq = probe_irq_off(cookie); irq = probe_irq_off(cookie);
if (!drive->channel->irq) { if (!drive->channel->irq) {
...@@ -855,19 +887,8 @@ static void channel_probe(struct ata_channel *ch) ...@@ -855,19 +887,8 @@ static void channel_probe(struct ata_channel *ch)
device_register(&ch->dev); device_register(&ch->dev);
if (ch->reset && ch->io_ports[IDE_CONTROL_OFFSET]) { if (ch->reset)
unsigned long timeout = jiffies + WAIT_WORSTCASE; ata_reset(ch);
u8 stat;
printk("%s: reset\n", ch->name);
OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
udelay(10);
OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
do {
mdelay(50);
stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
} while ((stat & BUSY_STAT) && time_before(jiffies, timeout));
}
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
...@@ -969,14 +990,19 @@ static int init_irq(struct ata_channel *ch) ...@@ -969,14 +990,19 @@ static int init_irq(struct ata_channel *ch)
* Allocate the irq, if not already obtained for another channel * Allocate the irq, if not already obtained for another channel
*/ */
if (!match || match->irq != ch->irq) { if (!match || match->irq != ch->irq) {
struct ata_device tmp;
#ifdef CONFIG_IDEPCI_SHARE_IRQ #ifdef CONFIG_IDEPCI_SHARE_IRQ
int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_SHIRQ : SA_INTERRUPT; int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_SHIRQ : SA_INTERRUPT;
#else #else
int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
#endif #endif
if (ch->io_ports[IDE_CONTROL_OFFSET]) /* Enable interrupts triggered by the drive. We use a shallow
OUT_BYTE(0x08, ch->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */ * device structure, just to use the generic function very
* early.
*/
tmp.channel = ch;
ata_irq_enable(&tmp, 1);
if (request_irq(ch->irq, &ata_irq_request, sa, ch->name, ch)) { if (request_irq(ch->irq, &ata_irq_request, sa, ch->name, ch)) {
if (!match) { if (!match) {
...@@ -1240,5 +1266,6 @@ int ideprobe_init(void) ...@@ -1240,5 +1266,6 @@ int ideprobe_init(void)
} }
EXPORT_SYMBOL(ata_fix_driveid); EXPORT_SYMBOL(ata_fix_driveid);
EXPORT_SYMBOL(ide_fixstring);
EXPORT_SYMBOL(eighty_ninty_three); EXPORT_SYMBOL(eighty_ninty_three);
EXPORT_SYMBOL(ide_config_drive_speed); EXPORT_SYMBOL(ide_config_drive_speed);
...@@ -173,9 +173,7 @@ static int qd_find_disk_type(struct ata_device *drive, ...@@ -173,9 +173,7 @@ static int qd_find_disk_type(struct ata_device *drive,
if (!*drive->id->model) return 0; if (!*drive->id->model) return 0;
strncpy(model,drive->id->model,40); strncpy(model,drive->id->model, 40);
ide_fixstring(model,40,1); /* byte-swap */
for (p = qd65xx_timing ; p->offset != -1 ; p++) { for (p = qd65xx_timing ; p->offset != -1 ; p++) {
if (!strncmp(p->model, model+p->offset, 4)) { if (!strncmp(p->model, model+p->offset, 4)) {
printk(KERN_DEBUG "%s: listed !\n", drive->name); printk(KERN_DEBUG "%s: listed !\n", drive->name);
......
...@@ -55,17 +55,6 @@ ...@@ -55,17 +55,6 @@
static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq); static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq);
static ide_startstop_t service(struct ata_device *drive, struct request *rq); static ide_startstop_t service(struct ata_device *drive, struct request *rq);
static inline void drive_ctl_nien(struct ata_device *drive, int set)
{
#ifdef IDE_TCQ_NIEN
if (IDE_CONTROL_REG) {
int mask = set ? 0x02 : 0x00;
OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG);
}
#endif
}
static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq) static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
{ {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
...@@ -136,11 +125,10 @@ static void tcq_invalidate_queue(struct ata_device *drive) ...@@ -136,11 +125,10 @@ static void tcq_invalidate_queue(struct ata_device *drive)
rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS); rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
_elv_add_request(q, rq, 0, 0); _elv_add_request(q, rq, 0, 0);
/*
* make sure that nIEN is cleared
*/
out: out:
drive_ctl_nien(drive, 0); #ifdef IDE_TCQ_NIEN
ata_irq_enable(drive, 1);
#endif
/* /*
* start doing stuff again * start doing stuff again
...@@ -250,8 +238,9 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq) ...@@ -250,8 +238,9 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
if (drive != drive->channel->drive) if (drive != drive->channel->drive)
ata_select(drive, 10); ata_select(drive, 10);
drive_ctl_nien(drive, 1); #ifdef IDE_TCQ_NIEN
ata_irq_enable(drive, 0);
#endif
/* /*
* send SERVICE, wait 400ns, wait for BUSY_STAT to clear * send SERVICE, wait 400ns, wait for BUSY_STAT to clear
*/ */
...@@ -265,7 +254,9 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq) ...@@ -265,7 +254,9 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
return ide_stopped; return ide_stopped;
} }
drive_ctl_nien(drive, 0); #ifdef IDE_TCQ_NIEN
ata_irq_enable(drive, 1);
#endif
/* /*
* FIXME, invalidate queue * FIXME, invalidate queue
...@@ -559,7 +550,9 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ...@@ -559,7 +550,9 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
* set nIEN, tag start operation will enable again when * set nIEN, tag start operation will enable again when
* it is safe * it is safe
*/ */
drive_ctl_nien(drive, 1); #ifdef IDE_TCQ_NIEN
ata_irq_enable(drive, 0);
#endif
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG); OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
...@@ -569,7 +562,9 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq) ...@@ -569,7 +562,9 @@ ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
return ide_stopped; return ide_stopped;
} }
drive_ctl_nien(drive, 0); #ifdef IDE_TCQ_NIEN
ata_irq_enable(drive, 1);
#endif
if (stat & ERR_STAT) { if (stat & ERR_STAT) {
ide_dump_status(drive, rq, "tcq_start", stat); ide_dump_status(drive, rq, "tcq_start", stat);
......
...@@ -222,7 +222,7 @@ static int do_udma(unsigned int reading, struct ata_device *drive, struct reques ...@@ -222,7 +222,7 @@ static int do_udma(unsigned int reading, struct ata_device *drive, struct reques
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0; return 0;
......
...@@ -411,8 +411,7 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request ...@@ -411,8 +411,7 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
} }
ata_select(drive, 10); ata_select(drive, 10);
if (IDE_CONTROL_REG) ata_irq_enable(drive, 1);
OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
OUT_BYTE (dma_ok,IDE_FEATURE_REG); OUT_BYTE (dma_ok,IDE_FEATURE_REG);
OUT_BYTE (bcount >> 8,IDE_BCOUNTH_REG); OUT_BYTE (bcount >> 8,IDE_BCOUNTH_REG);
OUT_BYTE (bcount & 0xff,IDE_BCOUNTL_REG); OUT_BYTE (bcount & 0xff,IDE_BCOUNTL_REG);
......
...@@ -38,11 +38,6 @@ ...@@ -38,11 +38,6 @@
# define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */ # define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */
#endif #endif
/* Right now this is only needed by a promise controlled.
*/
#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
# define OK_TO_RESET_CONTROLLER 0 /* 0 for use with AH2372A/B interface */
#endif
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ #ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
# define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ # define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif #endif
...@@ -73,21 +68,22 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -73,21 +68,22 @@ typedef unsigned char byte; /* used everywhere */
*/ */
enum { enum {
IDE_DATA_OFFSET = 0, IDE_DATA_OFFSET = 0,
IDE_ERROR_OFFSET = 1, IDE_ERROR_OFFSET = 1,
IDE_NSECTOR_OFFSET = 2, IDE_FEATURE_OFFSET = 1,
IDE_SECTOR_OFFSET = 3, IDE_NSECTOR_OFFSET = 2,
IDE_LCYL_OFFSET = 4, IDE_SECTOR_OFFSET = 3,
IDE_HCYL_OFFSET = 5, IDE_LCYL_OFFSET = 4,
IDE_SELECT_OFFSET = 6, IDE_HCYL_OFFSET = 5,
IDE_STATUS_OFFSET = 7, IDE_SELECT_OFFSET = 6,
IDE_CONTROL_OFFSET = 8, IDE_STATUS_OFFSET = 7,
IDE_IRQ_OFFSET = 9, IDE_COMMAND_OFFSET = 7,
IDE_NR_PORTS = 10 IDE_CONTROL_OFFSET = 8,
IDE_ALTSTATUS_OFFSET = 8,
IDE_IRQ_OFFSET = 9,
IDE_NR_PORTS = 10
}; };
#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET
#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
#define IDE_DATA_REG (drive->channel->io_ports[IDE_DATA_OFFSET]) #define IDE_DATA_REG (drive->channel->io_ports[IDE_DATA_OFFSET])
#define IDE_ERROR_REG (drive->channel->io_ports[IDE_ERROR_OFFSET]) #define IDE_ERROR_REG (drive->channel->io_ports[IDE_ERROR_OFFSET])
...@@ -96,20 +92,16 @@ enum { ...@@ -96,20 +92,16 @@ enum {
#define IDE_LCYL_REG (drive->channel->io_ports[IDE_LCYL_OFFSET]) #define IDE_LCYL_REG (drive->channel->io_ports[IDE_LCYL_OFFSET])
#define IDE_HCYL_REG (drive->channel->io_ports[IDE_HCYL_OFFSET]) #define IDE_HCYL_REG (drive->channel->io_ports[IDE_HCYL_OFFSET])
#define IDE_SELECT_REG (drive->channel->io_ports[IDE_SELECT_OFFSET]) #define IDE_SELECT_REG (drive->channel->io_ports[IDE_SELECT_OFFSET])
#define IDE_STATUS_REG (drive->channel->io_ports[IDE_STATUS_OFFSET]) #define IDE_COMMAND_REG (drive->channel->io_ports[IDE_STATUS_OFFSET])
#define IDE_CONTROL_REG (drive->channel->io_ports[IDE_CONTROL_OFFSET])
#define IDE_IRQ_REG (drive->channel->io_ports[IDE_IRQ_OFFSET]) #define IDE_IRQ_REG (drive->channel->io_ports[IDE_IRQ_OFFSET])
#define IDE_FEATURE_REG IDE_ERROR_REG #define IDE_FEATURE_REG IDE_ERROR_REG
#define IDE_COMMAND_REG IDE_STATUS_REG
#define IDE_ALTSTATUS_REG IDE_CONTROL_REG
#define IDE_IREASON_REG IDE_NSECTOR_REG #define IDE_IREASON_REG IDE_NSECTOR_REG
#define IDE_BCOUNTL_REG IDE_LCYL_REG #define IDE_BCOUNTL_REG IDE_LCYL_REG
#define IDE_BCOUNTH_REG IDE_HCYL_REG #define IDE_BCOUNTH_REG IDE_HCYL_REG
#define GET_ERR() IN_BYTE(IDE_ERROR_REG) #define GET_ERR() IN_BYTE(IDE_ERROR_REG)
#define GET_STAT() IN_BYTE(IDE_STATUS_REG) #define GET_ALTSTAT() IN_BYTE(drive->channel->io_ports[IDE_CONTROL_OFFSET])
#define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_REG)
#define GET_FEAT() IN_BYTE(IDE_NSECTOR_REG) #define GET_FEAT() IN_BYTE(IDE_NSECTOR_REG)
#define BAD_R_STAT (BUSY_STAT | ERR_STAT) #define BAD_R_STAT (BUSY_STAT | ERR_STAT)
...@@ -346,8 +338,6 @@ struct ata_device { ...@@ -346,8 +338,6 @@ struct ata_device {
byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
select_t select; /* basic drive/head select reg value */ select_t select; /* basic drive/head select reg value */
u8 ctl; /* "normal" value for IDE_CONTROL_REG */
u8 status; /* last retrived status value for device */ u8 status; /* last retrived status value for device */
byte ready_stat; /* min status value for drive ready */ byte ready_stat; /* min status value for drive ready */
...@@ -653,25 +643,10 @@ extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler, ...@@ -653,25 +643,10 @@ extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
*/ */
extern u8 ide_dump_status(struct ata_device *, struct request *rq, const char *, u8); extern u8 ide_dump_status(struct ata_device *, struct request *rq, const char *, u8);
extern ide_startstop_t ide_error(struct ata_device *, struct request *rq, extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *);
const char *, byte);
/* extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
* ide_fixstring() cleans up and (optionally) byte-swaps a text string,
* removing leading/trailing blanks and compressing internal blanks.
* It is primarily used to tidy up the model name/number fields as
* returned by the WIN_[P]IDENTIFY commands.
*/
void ide_fixstring(byte *s, const int bytecount, const int byteswap);
/*
* This routine busy-waits for the drive status to be not "busy".
* It then checks the status for all of the "good" bits and none
* of the "bad" bits, and if all is okay it returns 0. All other
* cases return 1 after doing "*startstop = ide_error()", and the
* caller should return the updated value of "startstop" in this case.
* "startstop" is unchanged when the function returns 0;
*/
extern int ide_wait_stat(ide_startstop_t *, extern int ide_wait_stat(ide_startstop_t *,
struct ata_device *, struct request *rq, struct ata_device *, struct request *rq,
byte, byte, unsigned long); byte, byte, unsigned long);
...@@ -896,5 +871,7 @@ extern int drive_is_ready(struct ata_device *drive); ...@@ -896,5 +871,7 @@ extern int drive_is_ready(struct ata_device *drive);
extern void ata_select(struct ata_device *, unsigned long); extern void ata_select(struct ata_device *, unsigned long);
extern void ata_mask(struct ata_device *); extern void ata_mask(struct ata_device *);
extern int ata_status(struct ata_device *, u8, u8); extern int ata_status(struct ata_device *, u8, u8);
extern int ata_irq_enable(struct ata_device *, int);
extern void ata_reset(struct ata_channel *);
#endif #endif
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