mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
ide: IORDY handling fixes
Add ide_pio_need_iordy() helper and convert host drivers to use it. This fixes it8172, it8213, pdc202xx_old, piix, slc90e66 and siimage host drivers to handle IORDY correctly. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
parent
6dae44f9a5
commit
c9ef59ff01
10 changed files with 22 additions and 16 deletions
|
@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||||
timing = ide_timing_find_mode(XFER_PIO_0 + pio);
|
timing = ide_timing_find_mode(XFER_PIO_0 + pio);
|
||||||
BUG_ON(!timing);
|
BUG_ON(!timing);
|
||||||
|
|
||||||
if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
!(ata_id_is_cfa(drive->id) && pio > 4))
|
|
||||||
use_iordy = 1;
|
use_iordy = 1;
|
||||||
|
|
||||||
apply_timings(chipselect, pio, timing, use_iordy);
|
apply_timings(chipselect, pio, timing, use_iordy);
|
||||||
|
|
|
@ -107,6 +107,12 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
|
EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
|
||||||
|
|
||||||
|
int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
|
||||||
|
{
|
||||||
|
return ata_id_pio_need_iordy(drive->id, pio);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ide_pio_need_iordy);
|
||||||
|
|
||||||
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
|
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
|
||||||
{
|
{
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
|
|
|
@ -66,7 +66,7 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||||
if (drive->media == ide_disk)
|
if (drive->media == ide_disk)
|
||||||
/* enable prefetch */
|
/* enable prefetch */
|
||||||
drive_enables |= 0x0004 << (drive->dn * 4);
|
drive_enables |= 0x0004 << (drive->dn * 4);
|
||||||
if (ata_id_has_iordy(drive->id))
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
/* enable IORDY sample-point */
|
/* enable IORDY sample-point */
|
||||||
drive_enables |= 0x0002 << (drive->dn * 4);
|
drive_enables |= 0x0002 << (drive->dn * 4);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||||
control |= 1; /* Programmable timing on */
|
control |= 1; /* Programmable timing on */
|
||||||
if (drive->media != ide_disk)
|
if (drive->media != ide_disk)
|
||||||
control |= 4; /* ATAPI */
|
control |= 4; /* ATAPI */
|
||||||
if (pio > 2)
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
control |= 2; /* IORDY */
|
control |= 2; /* IORDY */
|
||||||
if (is_slave) {
|
if (is_slave) {
|
||||||
master_data |= 0x4000;
|
master_data |= 0x4000;
|
||||||
|
|
|
@ -73,7 +73,7 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
|
||||||
* Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
|
* Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
|
||||||
*/
|
*/
|
||||||
AP &= ~0x3f;
|
AP &= ~0x3f;
|
||||||
if (ata_id_iordy_disable(drive->id))
|
if (ide_pio_need_iordy(drive, speed - XFER_PIO_0))
|
||||||
AP |= 0x20; /* set IORDY_EN bit */
|
AP |= 0x20; /* set IORDY_EN bit */
|
||||||
if (drive->media == ide_disk)
|
if (drive->media == ide_disk)
|
||||||
AP |= 0x10; /* set Prefetch_EN bit */
|
AP |= 0x10; /* set Prefetch_EN bit */
|
||||||
|
|
|
@ -98,7 +98,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||||
control |= 1; /* Programmable timing on */
|
control |= 1; /* Programmable timing on */
|
||||||
if (drive->media == ide_disk)
|
if (drive->media == ide_disk)
|
||||||
control |= 4; /* Prefetch, post write */
|
control |= 4; /* Prefetch, post write */
|
||||||
if (pio > 2)
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
control |= 2; /* IORDY */
|
control |= 2; /* IORDY */
|
||||||
if (is_slave) {
|
if (is_slave) {
|
||||||
master_data |= 0x4000;
|
master_data |= 0x4000;
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
* smarter code in libata.
|
* smarter code in libata.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - IORDY fixes
|
|
||||||
* - VDMA support
|
* - VDMA support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -234,8 +233,7 @@ static u8 sil_sata_udma_filter(ide_drive_t *drive)
|
||||||
* @pio: PIO mode number
|
* @pio: PIO mode number
|
||||||
*
|
*
|
||||||
* Load the timing settings for this device mode into the
|
* Load the timing settings for this device mode into the
|
||||||
* controller. If we are in PIO mode 3 or 4 turn on IORDY
|
* controller.
|
||||||
* monitoring (bit 9). The TF timing is bits 31:16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
|
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
|
||||||
|
@ -276,13 +274,16 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
|
||||||
/* now set up IORDY */
|
/* now set up IORDY */
|
||||||
speedp = sil_ioread16(dev, tfaddr - 2);
|
speedp = sil_ioread16(dev, tfaddr - 2);
|
||||||
speedp &= ~0x200;
|
speedp &= ~0x200;
|
||||||
if (pio > 2)
|
|
||||||
speedp |= 0x200;
|
|
||||||
sil_iowrite16(dev, speedp, tfaddr - 2);
|
|
||||||
|
|
||||||
mode = sil_ioread8(dev, base + addr_mask);
|
mode = sil_ioread8(dev, base + addr_mask);
|
||||||
mode &= ~(unit ? 0x30 : 0x03);
|
mode &= ~(unit ? 0x30 : 0x03);
|
||||||
mode |= unit ? 0x10 : 0x01;
|
|
||||||
|
if (ide_pio_need_iordy(drive, pio)) {
|
||||||
|
speedp |= 0x200;
|
||||||
|
mode |= unit ? 0x10 : 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
sil_iowrite16(dev, speedp, tfaddr - 2);
|
||||||
sil_iowrite8(dev, mode, base + addr_mask);
|
sil_iowrite8(dev, mode, base + addr_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
|
||||||
if (cmd_off == 0)
|
if (cmd_off == 0)
|
||||||
cmd_off = 1;
|
cmd_off = 1;
|
||||||
|
|
||||||
if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
!(pio > 4 && ata_id_is_cfa(drive->id)))
|
|
||||||
iordy = 0x40;
|
iordy = 0x40;
|
||||||
|
|
||||||
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
|
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
|
||||||
|
|
|
@ -44,7 +44,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||||
control |= 1; /* Programmable timing on */
|
control |= 1; /* Programmable timing on */
|
||||||
if (drive->media == ide_disk)
|
if (drive->media == ide_disk)
|
||||||
control |= 4; /* Prefetch, post write */
|
control |= 4; /* Prefetch, post write */
|
||||||
if (pio > 2)
|
if (ide_pio_need_iordy(drive, pio))
|
||||||
control |= 2; /* IORDY */
|
control |= 2; /* IORDY */
|
||||||
if (is_slave) {
|
if (is_slave) {
|
||||||
master_data |= 0x4000;
|
master_data |= 0x4000;
|
||||||
|
|
|
@ -1514,6 +1514,7 @@ int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int);
|
||||||
int ide_scan_pio_blacklist(char *);
|
int ide_scan_pio_blacklist(char *);
|
||||||
const char *ide_xfer_verbose(u8);
|
const char *ide_xfer_verbose(u8);
|
||||||
u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
|
u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
|
||||||
|
int ide_pio_need_iordy(ide_drive_t *, const u8);
|
||||||
int ide_set_pio_mode(ide_drive_t *, u8);
|
int ide_set_pio_mode(ide_drive_t *, u8);
|
||||||
int ide_set_dma_mode(ide_drive_t *, u8);
|
int ide_set_dma_mode(ide_drive_t *, u8);
|
||||||
void ide_set_pio(ide_drive_t *, u8);
|
void ide_set_pio(ide_drive_t *, u8);
|
||||||
|
|
Loading…
Reference in a new issue