[ide] unify PIO code

Use PIO code from ide-taskfile.c in ide-disk.c so:
* drive status is checked after PIO read
* request is failed if invalid data phase
  is detected during PIO write
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent cce7fdab
...@@ -122,72 +122,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id) ...@@ -122,72 +122,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
#ifndef CONFIG_IDE_TASKFILE_IO #ifndef CONFIG_IDE_TASKFILE_IO
/*
* read_intr() is the handler for disk read/multread interrupts
*/
static ide_startstop_t read_intr (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct request *rq = hwif->hwgroup->rq;
u8 stat;
/* new way for dealing with premature shared PCI interrupts */
if (!OK_STAT(stat=hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return task_error(drive, rq, __FUNCTION__, stat);
}
/* no data yet, so wait for another interrupt */
ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
return ide_started;
}
if (drive->mult_count)
ide_pio_multi(drive, 0);
else
ide_pio_sector(drive, 0);
rq->errors = 0;
if (!hwif->nleft) {
ide_end_request(drive, 1, hwif->nsect);
return ide_stopped;
}
ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
return ide_started;
}
/*
* write_intr() is the handler for disk write/multwrite interrupts
*/
static ide_startstop_t write_intr (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
struct request *rq = hwgroup->rq;
u8 stat;
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),
DRIVE_READY, drive->bad_wstat)) {
printk("%s: write_intr error1: nr_sectors=%u, stat=0x%02x\n",
drive->name, hwif->nleft, stat);
} else {
if ((hwif->nleft == 0) ^ ((stat & DRQ_STAT) != 0)) {
rq->errors = 0;
if (!hwif->nleft) {
ide_end_request(drive, 1, hwif->nsect);
return ide_stopped;
}
if (drive->mult_count)
ide_pio_multi(drive, 1);
else
ide_pio_sector(drive, 1);
ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
return ide_started;
}
/* the original code did this here (?) */
return ide_stopped;
}
return task_error(drive, rq, __FUNCTION__, stat);
}
/* /*
* __ide_do_rw_disk() issues READ and WRITE commands to a disk, * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors. * using LBA if supported, or CHS otherwise, to address sectors.
...@@ -309,11 +243,9 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector ...@@ -309,11 +243,9 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
command = lba48 ? WIN_READ_EXT : WIN_READ; command = lba48 ? WIN_READ_EXT : WIN_READ;
} }
ide_execute_command(drive, command, &read_intr, WAIT_CMD, NULL); ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, NULL);
return ide_started; return ide_started;
} else { } else {
ide_startstop_t startstop;
if (drive->mult_count) { if (drive->mult_count) {
hwif->data_phase = TASKFILE_MULTI_OUT; hwif->data_phase = TASKFILE_MULTI_OUT;
command = lba48 ? WIN_MULTWRITE_EXT : WIN_MULTWRITE; command = lba48 ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
...@@ -324,21 +256,7 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector ...@@ -324,21 +256,7 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
hwif->OUTB(command, IDE_COMMAND_REG); hwif->OUTB(command, IDE_COMMAND_REG);
if (ide_wait_stat(&startstop, drive, DATA_READY, pre_task_out_intr(drive, rq);
drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %s\n",
drive->name,
drive->mult_count ? "MULTWRITE" : "WRITE");
return startstop;
}
if (!drive->unmask)
local_irq_disable();
ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
if (drive->mult_count) {
ide_pio_multi(drive, 1);
} else {
ide_pio_sector(drive, 1);
}
return ide_started; return ide_started;
} }
} }
......
...@@ -273,7 +273,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) ...@@ -273,7 +273,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat; return stat;
} }
void ide_pio_sector(ide_drive_t *drive, unsigned int write) static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table; struct scatterlist *sg = hwif->sg_table;
...@@ -310,9 +310,7 @@ void ide_pio_sector(ide_drive_t *drive, unsigned int write) ...@@ -310,9 +310,7 @@ void ide_pio_sector(ide_drive_t *drive, unsigned int write)
#endif #endif
} }
EXPORT_SYMBOL_GPL(ide_pio_sector); static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
void ide_pio_multi(ide_drive_t *drive, unsigned int write)
{ {
unsigned int nsect; unsigned int nsect;
...@@ -321,8 +319,6 @@ void ide_pio_multi(ide_drive_t *drive, unsigned int write) ...@@ -321,8 +319,6 @@ void ide_pio_multi(ide_drive_t *drive, unsigned int write)
ide_pio_sector(drive, write); ide_pio_sector(drive, write);
} }
EXPORT_SYMBOL_GPL(ide_pio_multi);
static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq, static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
unsigned int write) unsigned int write)
{ {
...@@ -340,7 +336,7 @@ static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq, ...@@ -340,7 +336,7 @@ static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
} }
} }
ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
const char *s, u8 stat) const char *s, u8 stat)
{ {
if (rq->bio) { if (rq->bio) {
...@@ -371,8 +367,6 @@ ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, ...@@ -371,8 +367,6 @@ ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
return drive->driver->error(drive, s, stat); return drive->driver->error(drive, s, stat);
} }
EXPORT_SYMBOL_GPL(task_error);
static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
{ {
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
...@@ -396,6 +390,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) ...@@ -396,6 +390,7 @@ ide_startstop_t task_in_intr (ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
u8 stat = hwif->INB(IDE_STATUS_REG); u8 stat = hwif->INB(IDE_STATUS_REG);
/* new way for dealing with premature shared PCI interrupts */
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
if (stat & (ERR_STAT | DRQ_STAT)) if (stat & (ERR_STAT | DRQ_STAT))
return task_error(drive, rq, __FUNCTION__, stat); return task_error(drive, rq, __FUNCTION__, stat);
......
...@@ -1354,11 +1354,6 @@ extern void atapi_output_bytes(ide_drive_t *, void *, u32); ...@@ -1354,11 +1354,6 @@ extern void atapi_output_bytes(ide_drive_t *, void *, u32);
extern void taskfile_input_data(ide_drive_t *, void *, u32); extern void taskfile_input_data(ide_drive_t *, void *, u32);
extern void taskfile_output_data(ide_drive_t *, void *, u32); extern void taskfile_output_data(ide_drive_t *, void *, u32);
void ide_pio_sector(ide_drive_t *, unsigned int);
void ide_pio_multi(ide_drive_t *, unsigned int);
ide_startstop_t task_error(ide_drive_t *, struct request *, const char *, u8);
extern int drive_is_ready(ide_drive_t *); extern int drive_is_ready(ide_drive_t *);
extern int wait_for_ready(ide_drive_t *, int /* timeout */); extern int wait_for_ready(ide_drive_t *, int /* timeout */);
......
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