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;
} }
......
...@@ -93,74 +93,61 @@ static int lba_capacity_is_ok(struct hd_driveid *id) ...@@ -93,74 +93,61 @@ static int lba_capacity_is_ok(struct hd_driveid *id)
/* /*
* Handler for command with PIO data-in phase. * Handler for command with PIO data-in phase.
*/ */
static ide_startstop_t pio_in_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags; unsigned long flags;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
unsigned int msect; int ret;
spin_lock_irqsave(ch->lock, flags); spin_lock_irqsave(ch->lock, 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)) {
spin_unlock_irqrestore(ch->lock, flags); spin_unlock_irqrestore(ch->lock, flags);
return ata_error(drive, rq, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
} }
if (!(drive->status & BUSY_STAT)) /* no data yet, so wait for another interrupt */
goto cont; ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
}
msect = drive->mult_count;
do {
unsigned int nsect;
if (drive->mult_count) { ret = ide_started;
nsect = rq->current_nr_sectors; } else {
/* Don't try to transfer more sectors at once then one
* multi sector command can swallow.
*/
if (nsect > msect)
nsect = msect;
} else {
nsect = rq->current_nr_sectors;
nsect = 1;
}
// printk("Read: rq->current_nr_sectors: %d %d %d\n", msect, nsect, (int) rq->current_nr_sectors); // printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
{ {
unsigned long flags; unsigned long flags;
char *buf; char *buf;
buf = ide_map_rq(rq, &flags); buf = ide_map_rq(rq, &flags);
ata_read(drive, buf, nsect * SECTOR_WORDS); ata_read(drive, buf, SECTOR_WORDS);
ide_unmap_rq(rq, buf, &flags); ide_unmap_rq(rq, buf, &flags);
} }
/* 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 * necessarily mean that the entire request is done!! this is only true
* only true if ata_end_request() returns 0. * if ata_end_request() returns 0.
*/ */
rq->errors = 0; rq->errors = 0;
rq->current_nr_sectors -= nsect; --rq->current_nr_sectors;
if (rq->current_nr_sectors <= 0) { if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) { if (!__ata_end_request(drive, rq, 1, 0)) {
// printk("Request Ended stat: %02x\n", drive->status);
spin_unlock_irqrestore(ch->lock, flags); spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped; return ide_stopped;
} }
} }
msect -= nsect;
} while (msect > 0);
cont: /* still data left to transfer */
/* still data left to transfer */ ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
ata_set_handler(drive, pio_in_intr, WAIT_CMD, NULL);
ret = ide_started;
}
spin_unlock_irqrestore(ch->lock, flags); spin_unlock_irqrestore(ch->lock, flags);
return ide_started; return ret;
} }
/* /*
...@@ -203,6 +190,77 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -203,6 +190,77 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
return ret; return ret;
} }
/*
* Handler for command with Read Multiple
*/
static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
{
unsigned long flags;
struct ata_channel *ch = drive->channel;
int ret;
spin_lock_irqsave(ch->lock, flags);
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
if (drive->status & (ERR_STAT | DRQ_STAT)) {
spin_unlock_irqrestore(ch->lock, flags);
return ata_error(drive, rq, __FUNCTION__);
}
/* no data yet, so wait for another interrupt */
ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
ret = ide_started;
} else {
unsigned int msect;
/* (ks/hs): Fixed Multi-Sector transfer */
msect = drive->mult_count;
do {
unsigned int nsect;
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
#if 0
printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
buf, nsect, rq->current_nr_sectors);
#endif
{
unsigned long flags;
char *buf;
buf = ide_map_rq(rq, &flags);
ata_read(drive, buf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, buf, &flags);
}
rq->errors = 0;
rq->current_nr_sectors -= nsect;
/* FIXME: this seems buggy */
if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) {
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped;
}
}
msect -= nsect;
} while (msect);
/* more data left */
ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
ret = ide_started;
}
spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq) static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
{ {
unsigned long flags; unsigned long flags;
...@@ -552,10 +610,10 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -552,10 +610,10 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
} else if (drive->using_dma) { } else if (drive->using_dma) {
args.cmd = WIN_READDMA_EXT; args.cmd = WIN_READDMA_EXT;
} else if (drive->mult_count) { } else if (drive->mult_count) {
args.XXX_handler = pio_in_intr; args.XXX_handler = task_mulin_intr;
args.cmd = WIN_MULTREAD_EXT; args.cmd = WIN_MULTREAD_EXT;
} else { } else {
args.XXX_handler = pio_in_intr; args.XXX_handler = task_in_intr;
args.cmd = WIN_READ_EXT; args.cmd = WIN_READ_EXT;
} }
} else { } else {
...@@ -564,10 +622,11 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -564,10 +622,11 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
} else if (drive->using_dma) { } else if (drive->using_dma) {
args.cmd = WIN_READDMA; args.cmd = WIN_READDMA;
} else if (drive->mult_count) { } else if (drive->mult_count) {
args.XXX_handler = pio_in_intr; /* FIXME : Shouldn't this be task_mulin_intr?! */
args.XXX_handler = task_in_intr;
args.cmd = WIN_MULTREAD; args.cmd = WIN_MULTREAD;
} else { } else {
args.XXX_handler = pio_in_intr; args.XXX_handler = task_in_intr;
args.cmd = WIN_READ; args.cmd = WIN_READ;
} }
} }
...@@ -614,19 +673,6 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -614,19 +673,6 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
return __do_request(drive, &args, rq); return __do_request(drive, &args, rq);
} }
/*
* Small helper function used to execute simple commands.
*/
static int simple_taskfile(struct ata_device *drive, u8 cmd)
{
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.cmd = cmd;
return ide_raw_taskfile(drive, &args, NULL);
}
static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_device *drive) static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_device *drive)
{ {
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
...@@ -635,11 +681,15 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic ...@@ -635,11 +681,15 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic
/* /*
* Ignore the return code from door_lock, since the open() has * Ignore the return code from door_lock, since the open() has
* already succeeded once, and the door_lock is irrelevant at * already succeeded once, and the door_lock is irrelevant at this
* this time. * time.
*/ */
if (drive->doorlocking) { if (drive->doorlocking) {
if (simple_taskfile(drive, WIN_DOORLOCK)) struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.cmd = WIN_DOORLOCK;
if (ide_raw_taskfile(drive, &args))
drive->doorlocking = 0; drive->doorlocking = 0;
} }
} }
...@@ -649,21 +699,30 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic ...@@ -649,21 +699,30 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic
static int flush_cache(struct ata_device *drive) static int flush_cache(struct ata_device *drive)
{ {
u8 cmd; struct ata_taskfile args;
memset(&args, 0, sizeof(args));
if (drive->id->cfs_enable_2 & 0x2400) if (drive->id->cfs_enable_2 & 0x2400)
cmd = WIN_FLUSH_CACHE_EXT; args.cmd = WIN_FLUSH_CACHE_EXT;
else else
cmd = WIN_FLUSH_CACHE; args.cmd = WIN_FLUSH_CACHE;
return simple_taskfile(drive, cmd); return ide_raw_taskfile(drive, &args);
} }
static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive) static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive)
{ {
if (drive->removable && !drive->usage) { if (drive->removable && !drive->usage) {
/* XXX I don't think this is up to the lowlevel drivers.. --hch */
invalidate_bdev(inode->i_bdev, 0);
if (drive->doorlocking) { if (drive->doorlocking) {
if (simple_taskfile(drive, WIN_DOORUNLOCK)) struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.cmd = WIN_DOORUNLOCK;
if (ide_raw_taskfile(drive, &args))
drive->doorlocking = 0; drive->doorlocking = 0;
} }
} }
...@@ -710,7 +769,7 @@ static int set_multcount(struct ata_device *drive, int arg) ...@@ -710,7 +769,7 @@ static int set_multcount(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.sector_count = arg; args.taskfile.sector_count = arg;
args.cmd = WIN_SETMULT; args.cmd = WIN_SETMULT;
if (!ide_raw_taskfile(drive, &args, NULL)) { if (!ide_raw_taskfile(drive, &args)) {
/* all went well track this setting as valid */ /* all went well track this setting as valid */
drive->mult_count = arg; drive->mult_count = arg;
...@@ -739,7 +798,7 @@ static int write_cache(struct ata_device *drive, int arg) ...@@ -739,7 +798,7 @@ static int write_cache(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.cmd = WIN_SETFEATURES; args.cmd = WIN_SETFEATURES;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
drive->wcache = arg; drive->wcache = arg;
...@@ -748,7 +807,11 @@ static int write_cache(struct ata_device *drive, int arg) ...@@ -748,7 +807,11 @@ static int write_cache(struct ata_device *drive, int arg)
static int idedisk_standby(struct ata_device *drive) static int idedisk_standby(struct ata_device *drive)
{ {
return simple_taskfile(drive, WIN_STANDBYNOW1); struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.cmd = WIN_STANDBYNOW1;
return ide_raw_taskfile(drive, &args);
} }
static int set_acoustic(struct ata_device *drive, int arg) static int set_acoustic(struct ata_device *drive, int arg)
...@@ -759,7 +822,7 @@ static int set_acoustic(struct ata_device *drive, int arg) ...@@ -759,7 +822,7 @@ static int set_acoustic(struct ata_device *drive, int arg)
args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM; args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
args.taskfile.sector_count = arg; args.taskfile.sector_count = arg;
args.cmd = WIN_SETFEATURES; args.cmd = WIN_SETFEATURES;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
drive->acoustic = arg; drive->acoustic = arg;
...@@ -879,7 +942,7 @@ static unsigned long native_max_address(struct ata_device *drive) ...@@ -879,7 +942,7 @@ static unsigned long native_max_address(struct ata_device *drive)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40; args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX; args.cmd = WIN_READ_NATIVE_MAX;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
/* if OK, compute maximum address value */ /* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) { if (!(drive->status & ERR_STAT)) {
...@@ -901,9 +964,10 @@ static u64 native_max_address_ext(struct ata_device *drive) ...@@ -901,9 +964,10 @@ static u64 native_max_address_ext(struct ata_device *drive)
/* Create IDE/ATA command request structure */ /* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40; args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX_EXT; args.cmd = WIN_READ_NATIVE_MAX_EXT;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
/* if OK, compute maximum address value */ /* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) { if (!(drive->status & ERR_STAT)) {
...@@ -941,7 +1005,7 @@ static sector_t set_max_address(struct ata_device *drive, sector_t addr_req) ...@@ -941,7 +1005,7 @@ static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40; args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.cmd = WIN_SET_MAX; args.cmd = WIN_SET_MAX;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
/* if OK, read new maximum address value */ /* if OK, read new maximum address value */
if (!(drive->status & ERR_STAT)) { if (!(drive->status & ERR_STAT)) {
...@@ -974,7 +1038,7 @@ static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req) ...@@ -974,7 +1038,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;
ide_raw_taskfile(drive, &args, NULL); ide_raw_taskfile(drive, &args);
/* if OK, compute maximum address value */ /* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) { if (!(drive->status & ERR_STAT)) {
...@@ -1292,11 +1356,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f ...@@ -1292,11 +1356,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > (id ? id->max_multsect : 0)) if (arg < 0 || arg > (id ? id->max_multsect : 0))
return -EINVAL; return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_multcount(drive, arg); val = set_multcount(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val; return val;
} }
...@@ -1316,11 +1376,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f ...@@ -1316,11 +1376,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
return -EINVAL; return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_nowerr(drive, arg); val = set_nowerr(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val; return val;
} }
...@@ -1340,11 +1396,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f ...@@ -1340,11 +1396,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 1) if (arg < 0 || arg > 1)
return -EINVAL; return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = write_cache(drive, arg); val = write_cache(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val; return val;
} }
...@@ -1363,11 +1415,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f ...@@ -1363,11 +1415,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 254) if (arg < 0 || arg > 254)
return -EINVAL; return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_acoustic(drive, arg); val = set_acoustic(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val; return val;
} }
......
...@@ -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