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)
struct pci_dev *dev = ch->pci_dev;
u8 jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......@@ -647,7 +646,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
......@@ -157,7 +157,6 @@ static int hpt34x_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......@@ -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 */
outb(cmd, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
if (drive->type == ATA_DISK) {
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)
do_udma_start(drive);
}
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......@@ -913,7 +912,6 @@ static int hpt374_udma_stop(struct ata_device *drive)
if ((bwsr_stat & bwsr_mask) == bwsr_mask)
pci_write_config_byte(dev, mscreg, msc_stat|0x30);
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
......@@ -440,7 +440,6 @@ static int icside_dma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
drive->waiting_for_dma = 0;
disable_dma(ch->hw.dma);
icside_destroy_dmatable(drive);
......@@ -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_mode(ch->hw.dma, dma_mode);
drive->waiting_for_dma = 1;
return 0;
}
......
......@@ -93,74 +93,61 @@ static int lba_capacity_is_ok(struct hd_driveid *id)
/*
* 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;
struct ata_channel *ch = drive->channel;
unsigned int msect;
int ret;
spin_lock_irqsave(ch->lock, flags);
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);
return ata_error(drive, rq, __FUNCTION__);
}
if (!(drive->status & BUSY_STAT))
goto cont;
}
msect = drive->mult_count;
do {
unsigned int nsect;
/* no data yet, so wait for another interrupt */
ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
if (drive->mult_count) {
nsect = rq->current_nr_sectors;
/* Don't try to transfer more sectors at once then one
* multi sector command can swallow.
*/
if (nsect > msect)
nsect = msect;
ret = ide_started;
} 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;
char *buf;
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);
}
/* Segment of the request is complete. note that this does not
* necessarily mean that the entire request is done!! this is
* only true if ata_end_request() returns 0.
/* First segment of the request is complete. note that this does not
* necessarily mean that the entire request is done!! this is only true
* if ata_end_request() returns 0.
*/
rq->errors = 0;
rq->current_nr_sectors -= nsect;
--rq->current_nr_sectors;
if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) {
// printk("Request Ended stat: %02x\n", drive->status);
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped;
}
}
msect -= nsect;
} while (msect > 0);
cont:
/* still data left to transfer */
ata_set_handler(drive, pio_in_intr, WAIT_CMD, NULL);
ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
ret = ide_started;
}
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
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)
{
unsigned long flags;
......@@ -552,10 +610,10 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
} else if (drive->using_dma) {
args.cmd = WIN_READDMA_EXT;
} else if (drive->mult_count) {
args.XXX_handler = pio_in_intr;
args.XXX_handler = task_mulin_intr;
args.cmd = WIN_MULTREAD_EXT;
} else {
args.XXX_handler = pio_in_intr;
args.XXX_handler = task_in_intr;
args.cmd = WIN_READ_EXT;
}
} else {
......@@ -564,10 +622,11 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
} else if (drive->using_dma) {
args.cmd = WIN_READDMA;
} 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;
} else {
args.XXX_handler = pio_in_intr;
args.XXX_handler = task_in_intr;
args.cmd = WIN_READ;
}
}
......@@ -614,19 +673,6 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
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)
{
MOD_INC_USE_COUNT;
......@@ -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
* already succeeded once, and the door_lock is irrelevant at
* this time.
* already succeeded once, and the door_lock is irrelevant at this
* time.
*/
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;
}
}
......@@ -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)
{
u8 cmd;
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
if (drive->id->cfs_enable_2 & 0x2400)
cmd = WIN_FLUSH_CACHE_EXT;
args.cmd = WIN_FLUSH_CACHE_EXT;
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)
{
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 (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;
}
}
......@@ -710,7 +769,7 @@ static int set_multcount(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = arg;
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 */
drive->mult_count = arg;
......@@ -739,7 +798,7 @@ static int write_cache(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.cmd = WIN_SETFEATURES;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
drive->wcache = arg;
......@@ -748,7 +807,11 @@ static int write_cache(struct ata_device *drive, int arg)
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)
......@@ -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.sector_count = arg;
args.cmd = WIN_SETFEATURES;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
drive->acoustic = arg;
......@@ -879,7 +942,7 @@ static unsigned long native_max_address(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
......@@ -901,9 +964,10 @@ static u64 native_max_address_ext(struct ata_device *drive)
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
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 (!(drive->status & ERR_STAT)) {
......@@ -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.cmd = WIN_SET_MAX;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
/* if OK, read new maximum address value */
if (!(drive->status & ERR_STAT)) {
......@@ -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.device_head = 0x40;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
......@@ -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))
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_multcount(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val;
}
......@@ -1316,11 +1376,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_nowerr(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val;
}
......@@ -1340,11 +1396,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 1)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = write_cache(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val;
}
......@@ -1363,11 +1415,7 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
if (arg < 0 || arg > 254)
return -EINVAL;
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
val = set_acoustic(drive, arg);
spin_unlock_irq(drive->channel->lock);
return val;
}
......
......@@ -1378,7 +1378,6 @@ static int pmac_udma_stop(struct ata_device *drive)
ata4 = (pmac_ide[ix].kind == controller_kl_ata4 ||
pmac_ide[ix].kind == controller_kl_ata4_80);
drive->waiting_for_dma = 0;
dstat = in_le32(&dma->status);
out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
pmac_ide_destroy_dmatable(drive->channel, ix);
......@@ -1418,7 +1417,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
((reading) ? 0x00800000UL : 0));
(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
}
drive->waiting_for_dma = 1;
if (drive->type != ATA_DISK)
return ide_started;
......@@ -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
* when the disk interrupt occurs.
*
* FIXME: The following *trick* is broken:
*
* The trick here is to increment drive->waiting_for_dma, and return as
* if no interrupt occured. If the counter reach a certain timeout
* 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)
*/
if (!(in_le32(&dma->status) & ACTIVE))
return 1;
if (!drive->waiting_for_dma)
if (!test_bit(IDE_DMA, drive->channel->active))
printk(KERN_WARNING "ide%d, ide_dma_test_irq \
called while not waiting\n", ix);
/* If dbdma didn't execute the STOP command yet, the
* active bit is still set */
drive->waiting_for_dma++;
if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
printk(KERN_WARNING "ide%d, timeout waiting \
set_bit(IDE_DMA, drive->channel->active);
// if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
// printk(KERN_WARNING "ide%d, timeout waiting \
for dbdma command stop\n", ix);
return 1;
}
......
......@@ -148,7 +148,7 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
*/
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);
/*
......@@ -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.
*/
static ide_startstop_t special_intr(struct ata_device *drive,
struct request *rq)
{
ide_startstop_t ata_special_intr(struct ata_device *drive, struct
request *rq) {
struct ata_taskfile *ar = rq->special;
ide_startstop_t ret = ide_stopped;
......@@ -293,18 +292,16 @@ static ide_startstop_t special_intr(struct ata_device *drive,
return ret;
}
int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar,
char *buffer)
int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar)
{
struct request req;
ar->command_type = IDE_DRIVE_TASK_NO_DATA;
ar->XXX_handler = special_intr;
ar->XXX_handler = ata_special_intr;
memset(&req, 0, sizeof(req));
req.flags = REQ_SPECIAL;
req.special = ar;
req.buffer = buffer;
return ide_do_drive_cmd(drive, &req, ide_wait);
}
......@@ -313,4 +310,5 @@ EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(ata_special_intr);
EXPORT_SYMBOL(ide_raw_taskfile);
......@@ -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
* 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.
*
* Channel lock should be held.
*/
static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq)
{
unsigned long flags;
struct ata_channel *ch = drive->channel;
int ret = ide_stopped;
spin_lock_irqsave(ch->lock, flags);
ata_select(drive, 10);
if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) {
......@@ -287,7 +287,6 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req
ret = ide_stopped;
}
spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
......@@ -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.
* 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.
*
* Channel lock should be held.
*/
static ide_startstop_t reset_pollfunc(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, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) {
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 *
ret = ide_stopped;
}
ch->poll_timeout = 0; /* done polling */
spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped;
}
......@@ -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)
{
int i;
int first = 1;
printk(" [ ");
for (i = 0; i < nr; i++, msgs++)
if ((bits & msgs->mask) == msgs->match)
printk("%s ", msgs->msg);
if ((bits & msgs->mask) == msgs->match) {
if (!first)
printk(",");
printk("%s", msgs->msg);
first = 0;
}
printk("] ");
}
......@@ -560,7 +563,7 @@ static int do_recalibrate(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = drive->sect;
args.cmd = WIN_RESTORE;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
printk(KERN_INFO "%s: done!\n", drive->name);
}
......@@ -1030,12 +1033,12 @@ void ide_timer_expiry(unsigned long data)
if (ch->poll_timeout) {
ret = handler(drive, drive->rq);
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
if (test_bit(IDE_DMA, ch->active))
udma_irq_lost(drive);
(void) ide_ack_intr(ch);
printk("%s: lost interrupt\n", drive->name);
ret = handler(drive, drive->rq);
} else if (drive->waiting_for_dma) {
} else if (test_bit(IDE_DMA, ch->active)) {
struct request *rq = drive->rq;
/*
......
......@@ -47,6 +47,7 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
u8 *argbuf = vals;
int argsize = 4;
struct ata_taskfile args;
struct request req;
/* Second phase.
*/
......@@ -77,7 +78,17 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
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[1] = args.taskfile.feature;
......
......@@ -91,7 +91,6 @@ static int ns87415_udma_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
dma_stat = inb(ch->dma_base+2);
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(inb(dma_base)|6, dma_base); /* from ERRATA: clear the INTR & ERROR bits */
......
......@@ -167,7 +167,6 @@ int ata_start_dma(struct ata_device *drive, struct request *rq)
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
return 0;
}
......@@ -436,7 +435,6 @@ int udma_pci_stop(struct ata_device *drive)
unsigned long dma_base = ch->dma_base;
u8 dma_stat;
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
......@@ -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 */
}
int pdc202xx_udma_stop(struct ata_device *drive)
static int pdc202xx_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
u32 high_16 = pci_resource_start(ch->pci_dev, 4);
......@@ -585,7 +585,6 @@ int pdc202xx_udma_stop(struct ata_device *drive)
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 */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......@@ -604,7 +603,7 @@ static void pdc202xx_bug(struct ata_device *drive)
#endif
void pdc202xx_new_reset(struct ata_device *drive)
static void pdc202xx_new_reset(struct ata_device *drive)
{
ata_reset(drive->channel);
mdelay(1000);
......
......@@ -331,7 +331,6 @@ static int svwks_udma_stop(struct ata_device *drive)
#endif
}
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
......
......@@ -441,7 +441,7 @@ static int check_autopoll(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = 0x01;
args.cmd = WIN_NOP;
ide_raw_taskfile(drive, &args, NULL);
ide_raw_taskfile(drive, &args);
if (args.taskfile.feature & ABRT_ERR)
return 1;
......@@ -469,7 +469,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE;
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);
return 1;
}
......@@ -481,7 +481,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI;
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);
return 1;
}
......@@ -493,7 +493,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI;
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);
return 1;
}
......
......@@ -185,8 +185,8 @@ static int trm290_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
drive->waiting_for_dma = 0;
udma_destroy_table(ch); /* purge DMA mappings */
return (inw(ch->dma_base + 2) != 0x00ff);
}
......@@ -224,7 +224,6 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type == ATA_DISK) {
......
......@@ -298,7 +298,6 @@ struct ata_device {
unsigned using_tcq : 1; /* disk is using queueing */
unsigned dsc_overlap : 1; /* flag: DSC overlap */
unsigned waiting_for_dma: 1; /* dma currently in progress */
unsigned busy : 1; /* currently doing revalidate_disk() */
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,
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 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)
static inline int udma_stop(struct ata_device *drive)
{
clear_bit(IDE_DMA, drive->channel->active);
return drive->channel->udma_stop(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)
{
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)
......
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