diff options
Diffstat (limited to 'drivers/ata/pata_winbond.c')
-rw-r--r-- | drivers/ata/pata_winbond.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 7116a9e7a8b2..99c92eda217b 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c | |||
@@ -92,29 +92,33 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | 94 | ||
95 | static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) | 95 | static unsigned int winbond_data_xfer(struct ata_device *dev, |
96 | unsigned char *buf, unsigned int buflen, int rw) | ||
96 | { | 97 | { |
97 | struct ata_port *ap = adev->link->ap; | 98 | struct ata_port *ap = dev->link->ap; |
98 | int slop = buflen & 3; | 99 | int slop = buflen & 3; |
99 | 100 | ||
100 | if (ata_id_has_dword_io(adev->id)) { | 101 | if (ata_id_has_dword_io(dev->id)) { |
101 | if (write_data) | 102 | if (rw == READ) |
102 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
103 | else | ||
104 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 103 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
104 | else | ||
105 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
105 | 106 | ||
106 | if (unlikely(slop)) { | 107 | if (unlikely(slop)) { |
107 | __le32 pad = 0; | 108 | u32 pad; |
108 | if (write_data) { | 109 | if (rw == READ) { |
109 | memcpy(&pad, buf + buflen - slop, slop); | ||
110 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
111 | } else { | ||
112 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | 110 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); |
113 | memcpy(buf + buflen - slop, &pad, slop); | 111 | memcpy(buf + buflen - slop, &pad, slop); |
112 | } else { | ||
113 | memcpy(&pad, buf + buflen - slop, slop); | ||
114 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
114 | } | 115 | } |
116 | buflen += 4 - slop; | ||
115 | } | 117 | } |
116 | } else | 118 | } else |
117 | ata_data_xfer(adev, buf, buflen, write_data); | 119 | buflen = ata_data_xfer(dev, buf, buflen, rw); |
120 | |||
121 | return buflen; | ||
118 | } | 122 | } |
119 | 123 | ||
120 | static struct scsi_host_template winbond_sht = { | 124 | static struct scsi_host_template winbond_sht = { |
@@ -191,7 +195,7 @@ static __init int winbond_init_one(unsigned long port) | |||
191 | reg = winbond_readcfg(port, 0x81); | 195 | reg = winbond_readcfg(port, 0x81); |
192 | 196 | ||
193 | if (!(reg & 0x03)) /* Disabled */ | 197 | if (!(reg & 0x03)) /* Disabled */ |
194 | return 0; | 198 | return -ENODEV; |
195 | 199 | ||
196 | for (i = 0; i < 2 ; i ++) { | 200 | for (i = 0; i < 2 ; i ++) { |
197 | unsigned long cmd_port = 0x1F0 - (0x80 * i); | 201 | unsigned long cmd_port = 0x1F0 - (0x80 * i); |