diff options
Diffstat (limited to 'drivers/ide/pci/ns87415.c')
-rw-r--r-- | drivers/ide/pci/ns87415.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index c13e299077ec..fec4955f449b 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c | |||
@@ -63,6 +63,48 @@ static u8 superio_ide_inb (unsigned long port) | |||
63 | return inb(port); | 63 | return inb(port); |
64 | } | 64 | } |
65 | 65 | ||
66 | static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
67 | { | ||
68 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | ||
69 | struct ide_taskfile *tf = &task->tf; | ||
70 | |||
71 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
72 | u16 data = inw(io_ports->data_addr); | ||
73 | |||
74 | tf->data = data & 0xff; | ||
75 | tf->hob_data = (data >> 8) & 0xff; | ||
76 | } | ||
77 | |||
78 | /* be sure we're looking at the low order bits */ | ||
79 | outb(drive->ctl & ~0x80, io_ports->ctl_addr); | ||
80 | |||
81 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
82 | tf->nsect = inb(io_ports->nsect_addr); | ||
83 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
84 | tf->lbal = inb(io_ports->lbal_addr); | ||
85 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
86 | tf->lbam = inb(io_ports->lbam_addr); | ||
87 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
88 | tf->lbah = inb(io_ports->lbah_addr); | ||
89 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
90 | tf->device = superio_ide_inb(io_ports->device_addr); | ||
91 | |||
92 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
93 | outb(drive->ctl | 0x80, io_ports->ctl_addr); | ||
94 | |||
95 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
96 | tf->hob_feature = inb(io_ports->feature_addr); | ||
97 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
98 | tf->hob_nsect = inb(io_ports->nsect_addr); | ||
99 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
100 | tf->hob_lbal = inb(io_ports->lbal_addr); | ||
101 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
102 | tf->hob_lbam = inb(io_ports->lbam_addr); | ||
103 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
104 | tf->hob_lbah = inb(io_ports->lbah_addr); | ||
105 | } | ||
106 | } | ||
107 | |||
66 | static void __devinit superio_ide_init_iops (struct hwif_s *hwif) | 108 | static void __devinit superio_ide_init_iops (struct hwif_s *hwif) |
67 | { | 109 | { |
68 | struct pci_dev *pdev = to_pci_dev(hwif->dev); | 110 | struct pci_dev *pdev = to_pci_dev(hwif->dev); |
@@ -80,6 +122,8 @@ static void __devinit superio_ide_init_iops (struct hwif_s *hwif) | |||
80 | tmp = superio_ide_inb(superio_ide_dma_status[port]); | 122 | tmp = superio_ide_inb(superio_ide_dma_status[port]); |
81 | outb(tmp | 0x66, superio_ide_dma_status[port]); | 123 | outb(tmp | 0x66, superio_ide_dma_status[port]); |
82 | 124 | ||
125 | hwif->tf_read = superio_tf_read; | ||
126 | |||
83 | /* We need to override inb to workaround a SuperIO errata */ | 127 | /* We need to override inb to workaround a SuperIO errata */ |
84 | hwif->INB = superio_ide_inb; | 128 | hwif->INB = superio_ide_inb; |
85 | } | 129 | } |