Commit 68c14a04 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] IDE 93

 - Revert patch number 92. It turned out to be broken behind hope.  Personally I
   attribute this to the recent heat wave over here and apologize for the
   problems this may have caused. Turned out that my note about the change
   beeing dnagerous in the last change log was more then true...

 - Locking issues for ioctl handling.

 - Remove waiting_for_dma bit field. Use IDE_DMA bit flag instead.
   Apply this bit globally and not in the corresponding implementation
   functions.
parent da873d20
...@@ -597,7 +597,6 @@ static int cmd64x_udma_stop(struct ata_device *drive) ...@@ -597,7 +597,6 @@ static int cmd64x_udma_stop(struct ata_device *drive)
struct pci_dev *dev = ch->pci_dev; 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; 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 */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
...@@ -647,7 +646,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive) ...@@ -647,7 +646,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
u8 dma_stat; u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
...@@ -157,7 +157,6 @@ static int hpt34x_udma_stop(struct ata_device *drive) ...@@ -157,7 +157,6 @@ static int hpt34x_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
u8 dma_stat; u8 dma_stat;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
...@@ -184,7 +183,6 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq) ...@@ -184,7 +183,6 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */ outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
outb(cmd, dma_base); /* specify r/w */ outb(cmd, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->type == ATA_DISK) { if (drive->type == ATA_DISK) {
ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
......
...@@ -890,7 +890,6 @@ static int hpt370_udma_stop(struct ata_device *drive) ...@@ -890,7 +890,6 @@ static int hpt370_udma_stop(struct ata_device *drive)
do_udma_start(drive); do_udma_start(drive);
} }
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
...@@ -913,7 +912,6 @@ static int hpt374_udma_stop(struct ata_device *drive) ...@@ -913,7 +912,6 @@ static int hpt374_udma_stop(struct ata_device *drive)
if ((bwsr_stat & bwsr_mask) == bwsr_mask) if ((bwsr_stat & bwsr_mask) == bwsr_mask)
pci_write_config_byte(dev, mscreg, msc_stat|0x30); pci_write_config_byte(dev, mscreg, msc_stat|0x30);
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
...@@ -440,7 +440,6 @@ static int icside_dma_stop(struct ata_device *drive) ...@@ -440,7 +440,6 @@ static int icside_dma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
drive->waiting_for_dma = 0;
disable_dma(ch->hw.dma); disable_dma(ch->hw.dma);
icside_destroy_dmatable(drive); icside_destroy_dmatable(drive);
...@@ -508,8 +507,6 @@ icside_dma_common(struct ata_device *drive, struct request *rq, ...@@ -508,8 +507,6 @@ icside_dma_common(struct ata_device *drive, struct request *rq,
set_dma_sg(ch->hw.dma, ch->sg_table, count); set_dma_sg(ch->hw.dma, ch->sg_table, count);
set_dma_mode(ch->hw.dma, dma_mode); set_dma_mode(ch->hw.dma, dma_mode);
drive->waiting_for_dma = 1;
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -1378,7 +1378,6 @@ static int pmac_udma_stop(struct ata_device *drive) ...@@ -1378,7 +1378,6 @@ static int pmac_udma_stop(struct ata_device *drive)
ata4 = (pmac_ide[ix].kind == controller_kl_ata4 || ata4 = (pmac_ide[ix].kind == controller_kl_ata4 ||
pmac_ide[ix].kind == controller_kl_ata4_80); pmac_ide[ix].kind == controller_kl_ata4_80);
drive->waiting_for_dma = 0;
dstat = in_le32(&dma->status); dstat = in_le32(&dma->status);
out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16)); out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
pmac_ide_destroy_dmatable(drive->channel, ix); pmac_ide_destroy_dmatable(drive->channel, ix);
...@@ -1418,7 +1417,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq) ...@@ -1418,7 +1417,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
((reading) ? 0x00800000UL : 0)); ((reading) ? 0x00800000UL : 0));
(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE)); (void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
} }
drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return ide_started; return ide_started;
...@@ -1466,6 +1465,8 @@ static int pmac_udma_irq_status(struct ata_device *drive) ...@@ -1466,6 +1465,8 @@ static int pmac_udma_irq_status(struct ata_device *drive)
* - The dbdma fifo hasn't yet finished flushing to to system memory * - The dbdma fifo hasn't yet finished flushing to to system memory
* when the disk interrupt occurs. * when the disk interrupt occurs.
* *
* FIXME: The following *trick* is broken:
*
* The trick here is to increment drive->waiting_for_dma, and return as * The trick here is to increment drive->waiting_for_dma, and return as
* if no interrupt occured. If the counter reach a certain timeout * if no interrupt occured. If the counter reach a certain timeout
* value, we then return 1. If we really got the interrupt, it will * value, we then return 1. If we really got the interrupt, it will
...@@ -1480,15 +1481,16 @@ static int pmac_udma_irq_status(struct ata_device *drive) ...@@ -1480,15 +1481,16 @@ static int pmac_udma_irq_status(struct ata_device *drive)
*/ */
if (!(in_le32(&dma->status) & ACTIVE)) if (!(in_le32(&dma->status) & ACTIVE))
return 1; return 1;
if (!drive->waiting_for_dma)
if (!test_bit(IDE_DMA, drive->channel->active))
printk(KERN_WARNING "ide%d, ide_dma_test_irq \ printk(KERN_WARNING "ide%d, ide_dma_test_irq \
called while not waiting\n", ix); called while not waiting\n", ix);
/* If dbdma didn't execute the STOP command yet, the /* If dbdma didn't execute the STOP command yet, the
* active bit is still set */ * active bit is still set */
drive->waiting_for_dma++; set_bit(IDE_DMA, drive->channel->active);
if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { // if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
printk(KERN_WARNING "ide%d, timeout waiting \ // printk(KERN_WARNING "ide%d, timeout waiting \
for dbdma command stop\n", ix); for dbdma command stop\n", ix);
return 1; return 1;
} }
......
...@@ -148,7 +148,7 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount) ...@@ -148,7 +148,7 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
*/ */
int drive_is_ready(struct ata_device *drive) int drive_is_ready(struct ata_device *drive)
{ {
if (drive->waiting_for_dma) if (test_bit(IDE_DMA, drive->channel->active))
return udma_irq_status(drive); return udma_irq_status(drive);
/* /*
...@@ -242,9 +242,8 @@ int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t ...@@ -242,9 +242,8 @@ int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t
/* /*
* Invoked on completion of a special REQ_SPECIAL command. * Invoked on completion of a special REQ_SPECIAL command.
*/ */
static ide_startstop_t special_intr(struct ata_device *drive, ide_startstop_t ata_special_intr(struct ata_device *drive, struct
struct request *rq) request *rq) {
{
struct ata_taskfile *ar = rq->special; struct ata_taskfile *ar = rq->special;
ide_startstop_t ret = ide_stopped; ide_startstop_t ret = ide_stopped;
...@@ -293,18 +292,16 @@ static ide_startstop_t special_intr(struct ata_device *drive, ...@@ -293,18 +292,16 @@ static ide_startstop_t special_intr(struct ata_device *drive,
return ret; return ret;
} }
int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar, int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar)
char *buffer)
{ {
struct request req; struct request req;
ar->command_type = IDE_DRIVE_TASK_NO_DATA; ar->command_type = IDE_DRIVE_TASK_NO_DATA;
ar->XXX_handler = special_intr; ar->XXX_handler = ata_special_intr;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.flags = REQ_SPECIAL; req.flags = REQ_SPECIAL;
req.special = ar; req.special = ar;
req.buffer = buffer;
return ide_do_drive_cmd(drive, &req, ide_wait); return ide_do_drive_cmd(drive, &req, ide_wait);
} }
...@@ -313,4 +310,5 @@ EXPORT_SYMBOL(drive_is_ready); ...@@ -313,4 +310,5 @@ EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ide_do_drive_cmd); EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ata_read); EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write); EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(ata_special_intr);
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
...@@ -262,14 +262,14 @@ static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */ ...@@ -262,14 +262,14 @@ static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
* Poll the interface for completion every 50ms during an ATAPI drive reset * Poll the interface for completion every 50ms during an ATAPI drive reset
* operation. If the drive has not yet responded, and we have not yet hit our * operation. If the drive has not yet responded, and we have not yet hit our
* maximum waiting time, then the timer is restarted for another 50ms. * maximum waiting time, then the timer is restarted for another 50ms.
*
* Channel lock should be held.
*/ */
static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq) static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
int ret = ide_stopped; int ret = ide_stopped;
spin_lock_irqsave(ch->lock, flags);
ata_select(drive, 10); ata_select(drive, 10);
if (!ata_status(drive, 0, BUSY_STAT)) { if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
...@@ -287,7 +287,6 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req ...@@ -287,7 +287,6 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req
ret = ide_stopped; ret = ide_stopped;
} }
spin_unlock_irqrestore(ch->lock, flags);
return ret; return ret;
} }
...@@ -296,14 +295,14 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req ...@@ -296,14 +295,14 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req
* Poll the interface for completion every 50ms during an ata reset operation. * Poll the interface for completion every 50ms during an ata reset operation.
* If the drives have not yet responded, and we have not yet hit our maximum * If the drives have not yet responded, and we have not yet hit our maximum
* waiting time, then the timer is restarted for another 50ms. * waiting time, then the timer is restarted for another 50ms.
*
* Channel lock should be held.
*/ */
static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq) static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq)
{ {
unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
int ret; int ret;
spin_lock_irqsave(ch->lock, flags);
if (!ata_status(drive, 0, BUSY_STAT)) { if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) { if (time_before(jiffies, ch->poll_timeout)) {
ata_set_handler(drive, reset_pollfunc, HZ/20, NULL); ata_set_handler(drive, reset_pollfunc, HZ/20, NULL);
...@@ -347,7 +346,6 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request * ...@@ -347,7 +346,6 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
ret = ide_stopped; ret = ide_stopped;
} }
ch->poll_timeout = 0; /* done polling */ ch->poll_timeout = 0; /* done polling */
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped; return ide_stopped;
} }
...@@ -443,12 +441,17 @@ static struct ata_bit_messages ata_error_msgs[] = { ...@@ -443,12 +441,17 @@ static struct ata_bit_messages ata_error_msgs[] = {
static void dump_bits(struct ata_bit_messages *msgs, int nr, byte bits) static void dump_bits(struct ata_bit_messages *msgs, int nr, byte bits)
{ {
int i; int i;
int first = 1;
printk(" [ "); printk(" [ ");
for (i = 0; i < nr; i++, msgs++) for (i = 0; i < nr; i++, msgs++)
if ((bits & msgs->mask) == msgs->match) if ((bits & msgs->mask) == msgs->match) {
printk("%s ", msgs->msg); if (!first)
printk(",");
printk("%s", msgs->msg);
first = 0;
}
printk("] "); printk("] ");
} }
...@@ -560,7 +563,7 @@ static int do_recalibrate(struct ata_device *drive) ...@@ -560,7 +563,7 @@ static int do_recalibrate(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.sector_count = drive->sect; args.taskfile.sector_count = drive->sect;
args.cmd = WIN_RESTORE; args.cmd = WIN_RESTORE;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
printk(KERN_INFO "%s: done!\n", drive->name); printk(KERN_INFO "%s: done!\n", drive->name);
} }
...@@ -1030,12 +1033,12 @@ void ide_timer_expiry(unsigned long data) ...@@ -1030,12 +1033,12 @@ void ide_timer_expiry(unsigned long data)
if (ch->poll_timeout) { if (ch->poll_timeout) {
ret = handler(drive, drive->rq); ret = handler(drive, drive->rq);
} else if (drive_is_ready(drive)) { } else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma) if (test_bit(IDE_DMA, ch->active))
udma_irq_lost(drive); udma_irq_lost(drive);
(void) ide_ack_intr(ch); (void) ide_ack_intr(ch);
printk("%s: lost interrupt\n", drive->name); printk("%s: lost interrupt\n", drive->name);
ret = handler(drive, drive->rq); ret = handler(drive, drive->rq);
} else if (drive->waiting_for_dma) { } else if (test_bit(IDE_DMA, ch->active)) {
struct request *rq = drive->rq; struct request *rq = drive->rq;
/* /*
......
...@@ -47,6 +47,7 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg) ...@@ -47,6 +47,7 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
u8 *argbuf = vals; u8 *argbuf = vals;
int argsize = 4; int argsize = 4;
struct ata_taskfile args; struct ata_taskfile args;
struct request req;
/* Second phase. /* Second phase.
*/ */
...@@ -77,7 +78,17 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg) ...@@ -77,7 +78,17 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
memset(argbuf + 4, 0, argsize - 4); memset(argbuf + 4, 0, argsize - 4);
} }
err = ide_raw_taskfile(drive, &args, argbuf + 4); /* Issue ATA command and wait for completion.
*/
args.command_type = IDE_DRIVE_TASK_NO_DATA;
args.XXX_handler = ata_special_intr;
memset(&req, 0, sizeof(req));
req.flags = REQ_SPECIAL;
req.special = &args;
req.buffer = argbuf + 4;
err = ide_do_drive_cmd(drive, &req, ide_wait);
argbuf[0] = drive->status; argbuf[0] = drive->status;
argbuf[1] = args.taskfile.feature; argbuf[1] = args.taskfile.feature;
......
...@@ -91,7 +91,6 @@ static int ns87415_udma_stop(struct ata_device *drive) ...@@ -91,7 +91,6 @@ static int ns87415_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
u8 dma_stat; u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(ch->dma_base+2); dma_stat = inb(ch->dma_base+2);
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(inb(dma_base)|6, dma_base); /* from ERRATA: clear the INTR & ERROR bits */ outb(inb(dma_base)|6, dma_base); /* from ERRATA: clear the INTR & ERROR bits */
......
...@@ -167,7 +167,6 @@ int ata_start_dma(struct ata_device *drive, struct request *rq) ...@@ -167,7 +167,6 @@ int ata_start_dma(struct ata_device *drive, struct request *rq)
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */ outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
outb(reading, dma_base); /* specify r/w */ outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
return 0; return 0;
} }
...@@ -436,7 +435,6 @@ int udma_pci_stop(struct ata_device *drive) ...@@ -436,7 +435,6 @@ int udma_pci_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base; unsigned long dma_base = ch->dma_base;
u8 dma_stat; u8 dma_stat;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
...@@ -571,7 +571,7 @@ static void pdc202xx_udma_start(struct ata_device *drive, struct request *rq) ...@@ -571,7 +571,7 @@ static void pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */ outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */
} }
int pdc202xx_udma_stop(struct ata_device *drive) static int pdc202xx_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
u32 high_16 = pci_resource_start(ch->pci_dev, 4); u32 high_16 = pci_resource_start(ch->pci_dev, 4);
...@@ -585,7 +585,6 @@ int pdc202xx_udma_stop(struct ata_device *drive) ...@@ -585,7 +585,6 @@ int pdc202xx_udma_stop(struct ata_device *drive)
OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK); OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK);
} }
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
...@@ -604,7 +603,7 @@ static void pdc202xx_bug(struct ata_device *drive) ...@@ -604,7 +603,7 @@ static void pdc202xx_bug(struct ata_device *drive)
#endif #endif
void pdc202xx_new_reset(struct ata_device *drive) static void pdc202xx_new_reset(struct ata_device *drive)
{ {
ata_reset(drive->channel); ata_reset(drive->channel);
mdelay(1000); mdelay(1000);
......
...@@ -331,7 +331,6 @@ static int svwks_udma_stop(struct ata_device *drive) ...@@ -331,7 +331,6 @@ static int svwks_udma_stop(struct ata_device *drive)
#endif #endif
} }
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
...@@ -441,7 +441,7 @@ static int check_autopoll(struct ata_device *drive) ...@@ -441,7 +441,7 @@ static int check_autopoll(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.feature = 0x01; args.taskfile.feature = 0x01;
args.cmd = WIN_NOP; args.cmd = WIN_NOP;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
if (args.taskfile.feature & ABRT_ERR) if (args.taskfile.feature & ABRT_ERR)
return 1; return 1;
...@@ -469,7 +469,7 @@ static int configure_tcq(struct ata_device *drive) ...@@ -469,7 +469,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE; args.taskfile.feature = SETFEATURES_EN_WCACHE;
args.cmd = WIN_SETFEATURES; args.cmd = WIN_SETFEATURES;
if (ide_raw_taskfile(drive, &args, NULL)) { if (ide_raw_taskfile(drive, &args)) {
printk("%s: failed to enable write cache\n", drive->name); printk("%s: failed to enable write cache\n", drive->name);
return 1; return 1;
} }
...@@ -481,7 +481,7 @@ static int configure_tcq(struct ata_device *drive) ...@@ -481,7 +481,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI; args.taskfile.feature = SETFEATURES_DIS_RI;
args.cmd = WIN_SETFEATURES; args.cmd = WIN_SETFEATURES;
if (ide_raw_taskfile(drive, &args, NULL)) { if (ide_raw_taskfile(drive, &args)) {
printk("%s: disabling release interrupt fail\n", drive->name); printk("%s: disabling release interrupt fail\n", drive->name);
return 1; return 1;
} }
...@@ -493,7 +493,7 @@ static int configure_tcq(struct ata_device *drive) ...@@ -493,7 +493,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI; args.taskfile.feature = SETFEATURES_EN_SI;
args.cmd = WIN_SETFEATURES; args.cmd = WIN_SETFEATURES;
if (ide_raw_taskfile(drive, &args, NULL)) { if (ide_raw_taskfile(drive, &args)) {
printk("%s: enabling service interrupt fail\n", drive->name); printk("%s: enabling service interrupt fail\n", drive->name);
return 1; return 1;
} }
......
...@@ -185,8 +185,8 @@ static int trm290_udma_stop(struct ata_device *drive) ...@@ -185,8 +185,8 @@ static int trm290_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
drive->waiting_for_dma = 0;
udma_destroy_table(ch); /* purge DMA mappings */ udma_destroy_table(ch); /* purge DMA mappings */
return (inw(ch->dma_base + 2) != 0x00ff); return (inw(ch->dma_base + 2) != 0x00ff);
} }
...@@ -224,7 +224,6 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq) ...@@ -224,7 +224,6 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
trm290_prepare_drive(drive, 1); /* select DMA xfer */ trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(ch->dmatable_dma|reading|writing, ch->dma_base); outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */ outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type == ATA_DISK) { if (drive->type == ATA_DISK) {
......
...@@ -298,7 +298,6 @@ struct ata_device { ...@@ -298,7 +298,6 @@ struct ata_device {
unsigned using_tcq : 1; /* disk is using queueing */ unsigned using_tcq : 1; /* disk is using queueing */
unsigned dsc_overlap : 1; /* flag: DSC overlap */ unsigned dsc_overlap : 1; /* flag: DSC overlap */
unsigned waiting_for_dma: 1; /* dma currently in progress */
unsigned busy : 1; /* currently doing revalidate_disk() */ unsigned busy : 1; /* currently doing revalidate_disk() */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
...@@ -681,7 +680,8 @@ static inline void ide_unmap_rq(struct request *rq, char *to, ...@@ -681,7 +680,8 @@ static inline void ide_unmap_rq(struct request *rq, char *to,
bio_kunmap_irq(to, flags); bio_kunmap_irq(to, flags);
} }
extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *); extern ide_startstop_t ata_special_intr(struct ata_device *, struct request *);
extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);
extern void ide_fix_driveid(struct hd_driveid *id); extern void ide_fix_driveid(struct hd_driveid *id);
extern int ide_config_drive_speed(struct ata_device *, byte); extern int ide_config_drive_speed(struct ata_device *, byte);
...@@ -756,6 +756,8 @@ static inline void udma_start(struct ata_device *drive, struct request *rq) ...@@ -756,6 +756,8 @@ static inline void udma_start(struct ata_device *drive, struct request *rq)
static inline int udma_stop(struct ata_device *drive) static inline int udma_stop(struct ata_device *drive)
{ {
clear_bit(IDE_DMA, drive->channel->active);
return drive->channel->udma_stop(drive); return drive->channel->udma_stop(drive);
} }
...@@ -764,7 +766,11 @@ static inline int udma_stop(struct ata_device *drive) ...@@ -764,7 +766,11 @@ static inline int udma_stop(struct ata_device *drive)
*/ */
static inline ide_startstop_t udma_init(struct ata_device *drive, struct request *rq) static inline ide_startstop_t udma_init(struct ata_device *drive, struct request *rq)
{ {
return drive->channel->udma_init(drive, rq); int ret = drive->channel->udma_init(drive, rq);
if (ret == ide_started)
set_bit(IDE_DMA, drive->channel->active);
return ret;
} }
static inline int udma_irq_status(struct ata_device *drive) static inline int udma_irq_status(struct ata_device *drive)
......
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