aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-iops.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-28 17:44:36 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-28 17:44:36 -0400
commit9567b349f7e7dd7e2483db99ee8e4a6fe0caca38 (patch)
tree29abab829b52a451567f8da4280d101fafa44527 /drivers/ide/ide-iops.c
parent92d3ab27e8fd23d1a9dc3b69d17b2afb83e5c6f5 (diff)
ide: merge ->atapi_*put_bytes and ->ata_*put_data methods
* Merge ->atapi_{in,out}put_bytes and ->ata_{in,out}put_data methods into new ->{in,out}put_data methods which take number of bytes to transfer as an argument and always do padding. While at it: * Use 'hwif' or 'drive->hwif' instead of 'HWIF(drive)'. There should be no functional changes caused by this patch (all users of ->ata_{in,out}put_data methods were using multiply-of-4 word counts). Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r--drivers/ide/ide-iops.c68
1 files changed, 25 insertions, 43 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 7ec7fa2aef96..fbbbb30ae964 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -191,36 +191,47 @@ static void ata_vlb_sync(ide_drive_t *drive, unsigned long port)
191 191
192/* 192/*
193 * This is used for most PIO data transfers *from* the IDE interface 193 * This is used for most PIO data transfers *from* the IDE interface
194 *
195 * These routines will round up any request for an odd number of bytes,
196 * so if an odd len is specified, be sure that there's at least one
197 * extra byte allocated for the buffer.
194 */ 198 */
195static void ata_input_data(ide_drive_t *drive, struct request *rq, 199static void ata_input_data(ide_drive_t *drive, struct request *rq,
196 void *buffer, u32 wcount) 200 void *buf, unsigned int len)
197{ 201{
198 ide_hwif_t *hwif = drive->hwif; 202 ide_hwif_t *hwif = drive->hwif;
199 struct ide_io_ports *io_ports = &hwif->io_ports; 203 struct ide_io_ports *io_ports = &hwif->io_ports;
204 unsigned long data_addr = io_ports->data_addr;
200 u8 io_32bit = drive->io_32bit; 205 u8 io_32bit = drive->io_32bit;
201 206
207 len++;
208
202 if (io_32bit) { 209 if (io_32bit) {
203 if (io_32bit & 2) { 210 if (io_32bit & 2) {
204 unsigned long flags; 211 unsigned long flags;
205 212
206 local_irq_save(flags); 213 local_irq_save(flags);
207 ata_vlb_sync(drive, io_ports->nsect_addr); 214 ata_vlb_sync(drive, io_ports->nsect_addr);
208 hwif->INSL(io_ports->data_addr, buffer, wcount); 215 hwif->INSL(data_addr, buf, len / 4);
209 local_irq_restore(flags); 216 local_irq_restore(flags);
210 } else 217 } else
211 hwif->INSL(io_ports->data_addr, buffer, wcount); 218 hwif->INSL(data_addr, buf, len / 4);
219
220 if ((len & 3) >= 2)
221 hwif->INSW(data_addr, (u8 *)buf + (len & ~3), 1);
212 } else 222 } else
213 hwif->INSW(io_ports->data_addr, buffer, wcount << 1); 223 hwif->INSW(data_addr, buf, len / 2);
214} 224}
215 225
216/* 226/*
217 * This is used for most PIO data transfers *to* the IDE interface 227 * This is used for most PIO data transfers *to* the IDE interface
218 */ 228 */
219static void ata_output_data(ide_drive_t *drive, struct request *rq, 229static void ata_output_data(ide_drive_t *drive, struct request *rq,
220 void *buffer, u32 wcount) 230 void *buf, unsigned int len)
221{ 231{
222 ide_hwif_t *hwif = drive->hwif; 232 ide_hwif_t *hwif = drive->hwif;
223 struct ide_io_ports *io_ports = &hwif->io_ports; 233 struct ide_io_ports *io_ports = &hwif->io_ports;
234 unsigned long data_addr = io_ports->data_addr;
224 u8 io_32bit = drive->io_32bit; 235 u8 io_32bit = drive->io_32bit;
225 236
226 if (io_32bit) { 237 if (io_32bit) {
@@ -229,50 +240,21 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq,
229 240
230 local_irq_save(flags); 241 local_irq_save(flags);
231 ata_vlb_sync(drive, io_ports->nsect_addr); 242 ata_vlb_sync(drive, io_ports->nsect_addr);
232 hwif->OUTSL(io_ports->data_addr, buffer, wcount); 243 hwif->OUTSL(data_addr, buf, len / 4);
233 local_irq_restore(flags); 244 local_irq_restore(flags);
234 } else 245 } else
235 hwif->OUTSL(io_ports->data_addr, buffer, wcount); 246 hwif->OUTSL(data_addr, buf, len / 4);
236 } else
237 hwif->OUTSW(io_ports->data_addr, buffer, wcount << 1);
238}
239
240/*
241 * The following routines are mainly used by the ATAPI drivers.
242 *
243 * These routines will round up any request for an odd number of bytes,
244 * so if an odd bytecount is specified, be sure that there's at least one
245 * extra byte allocated for the buffer.
246 */
247
248static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
249{
250 ide_hwif_t *hwif = HWIF(drive);
251 247
252 ++bytecount; 248 if ((len & 3) >= 2)
253 hwif->ata_input_data(drive, NULL, buffer, bytecount / 4); 249 hwif->OUTSW(data_addr, (u8 *)buf + (len & ~3), 1);
254 if ((bytecount & 0x03) >= 2) 250 } else
255 hwif->INSW(hwif->io_ports.data_addr, 251 hwif->OUTSW(data_addr, buf, len / 2);
256 (u8 *)buffer + (bytecount & ~0x03), 1);
257}
258
259static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
260{
261 ide_hwif_t *hwif = HWIF(drive);
262
263 ++bytecount;
264 hwif->ata_output_data(drive, NULL, buffer, bytecount / 4);
265 if ((bytecount & 0x03) >= 2)
266 hwif->OUTSW(hwif->io_ports.data_addr,
267 (u8 *)buffer + (bytecount & ~0x03), 1);
268} 252}
269 253
270void default_hwif_transport(ide_hwif_t *hwif) 254void default_hwif_transport(ide_hwif_t *hwif)
271{ 255{
272 hwif->ata_input_data = ata_input_data; 256 hwif->input_data = ata_input_data;
273 hwif->ata_output_data = ata_output_data; 257 hwif->output_data = ata_output_data;
274 hwif->atapi_input_bytes = atapi_input_bytes;
275 hwif->atapi_output_bytes = atapi_output_bytes;
276} 258}
277 259
278void ide_fix_driveid (struct hd_driveid *id) 260void ide_fix_driveid (struct hd_driveid *id)
@@ -656,7 +638,7 @@ int ide_driveid_update(ide_drive_t *drive)
656 local_irq_restore(flags); 638 local_irq_restore(flags);
657 return 0; 639 return 0;
658 } 640 }
659 hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS); 641 hwif->input_data(drive, NULL, id, SECTOR_SIZE);
660 (void)ide_read_status(drive); /* clear drive IRQ */ 642 (void)ide_read_status(drive); /* clear drive IRQ */
661 local_irq_enable(); 643 local_irq_enable();
662 local_irq_restore(flags); 644 local_irq_restore(flags);