From 92d3ab27e8fd23d1a9dc3b69d17b2afb83e5c6f5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:36 +0200 Subject: falconide/q40ide: add ->atapi_*put_bytes and ->ata_*put_data methods (take 2) * Add ->atapi_{in,out}put_bytes and ->ata_{in,out}put_data methods to falconide and q40ide host drivers (->ata_* methods are implemented on top of ->atapi_* methods so they also do byte-swapping now). * Cleanup atapi_{in,out}put_bytes(). v2: * Add 'struct request *rq' argument to ->ata_{in,out}put_data methods and don't byte-swap disk fs requests (we shouldn't un-swap fs requests because fs itself is stored byte-swapped on the disk) - this is how things were done before the patch (ideally device mapper should be used instead but it would break existing setups and would have some performance impact). Cc: Geert Uytterhoeven Cc: Michael Schmitz Cc: Roman Zippel Cc: Alan Cox Cc: Richard Zidlicky Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 32fd77bb4436..0cbc46bf08a5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -467,8 +467,8 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; - void (*ata_input_data)(ide_drive_t *, void *, u32); - void (*ata_output_data)(ide_drive_t *, void *, u32); + void (*ata_input_data)(ide_drive_t *, struct request *, void *, u32); + void (*ata_output_data)(ide_drive_t *, struct request *, void *, u32); void (*atapi_input_bytes)(ide_drive_t *, void *, u32); void (*atapi_output_bytes)(ide_drive_t *, void *, u32); -- cgit v1.2.3 From 9567b349f7e7dd7e2483db99ee8e4a6fe0caca38 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:36 +0200 Subject: 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 --- drivers/ide/cris/ide-cris.c | 52 ++++++++++---------------------- drivers/ide/ide-cd.c | 14 ++++----- drivers/ide/ide-floppy.c | 18 ++++++----- drivers/ide/ide-io.c | 2 +- drivers/ide/ide-iops.c | 68 ++++++++++++++++-------------------------- drivers/ide/ide-probe.c | 2 +- drivers/ide/ide-tape.c | 13 ++++---- drivers/ide/ide-taskfile.c | 4 +-- drivers/ide/legacy/falconide.c | 36 ++++++++-------------- drivers/ide/legacy/q40ide.c | 36 ++++++++-------------- drivers/scsi/ide-scsi.c | 27 ++++++++--------- include/linux/ide.h | 13 ++++---- 12 files changed, 113 insertions(+), 172 deletions(-) (limited to 'include') diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index aa263df76569..72ff63ed5f2b 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -673,12 +673,8 @@ cris_ide_inb(unsigned long reg) return (unsigned char)cris_ide_inw(reg); } -static void cris_ide_input_data(ide_drive_t *, struct request *, - void *, unsigned int); -static void cris_ide_output_data(ide_drive_t *, struct request *, - void *, unsigned int); -static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); -static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); +static void cris_input_data(ide_drive_t *, struct request *, void *, unsigned); +static void cris_output_data(ide_drive_t *, struct request *, void *, unsigned); static void cris_dma_host_set(ide_drive_t *drive, int on) { @@ -816,10 +812,9 @@ static int __init init_e100_ide(void) ide_init_port_data(hwif, hwif->index); ide_init_port_hw(hwif, &hw); - hwif->ata_input_data = &cris_ide_input_data; - hwif->ata_output_data = &cris_ide_output_data; - hwif->atapi_input_bytes = &cris_atapi_input_bytes; - hwif->atapi_output_bytes = &cris_atapi_output_bytes; + hwif->input_data = cris_input_data; + hwif->output_data = cris_output_data; + hwif->OUTB = &cris_ide_outb; hwif->OUTW = &cris_ide_outw; hwif->OUTBSYNC = &cris_ide_outbsync; @@ -849,17 +844,16 @@ static int __init init_e100_ide(void) static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16))); /* - * The following routines are mainly used by the ATAPI drivers. + * This is used for most PIO data transfers *from* the IDE interface * * These routines will round up any request for an odd number of bytes, * so if an odd bytecount is specified, be sure that there's at least one * extra byte allocated for the buffer. */ -static void -cris_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) +static void cris_input_data(ide_drive_t *drive, struct request *rq, + void *buffer, unsigned int bytecount) { - D(printk("atapi_input_bytes, buffer 0x%x, count %d\n", - buffer, bytecount)); + D(printk("input_data, buffer 0x%x, count %d\n", buffer, bytecount)); if(bytecount & 1) { printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount); @@ -877,11 +871,13 @@ cris_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount LED_DISK_READ(0); } -static void -cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) +/* + * This is used for most PIO data transfers *to* the IDE interface + */ +static void cris_output_data(ide_drive_t *drive, struct request *rq, + void *buffer, unsigned int bytecount) { - D(printk("atapi_output_bytes, buffer 0x%x, count %d\n", - buffer, bytecount)); + D(printk("output_data, buffer 0x%x, count %d\n", buffer, bytecount)); if(bytecount & 1) { printk("odd bytecount %d in atapi_out_bytes!\n", bytecount); @@ -899,24 +895,6 @@ cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun LED_DISK_WRITE(0); } -/* - * This is used for most PIO data transfers *from* the IDE interface - */ -static void cris_ide_input_data(ide_drive_t *drive, struct request *rq, - void *buffer, unsigned int wcount) -{ - cris_atapi_input_bytes(drive, buffer, wcount << 2); -} - -/* - * This is used for most PIO data transfers *to* the IDE interface - */ -static void cris_ide_output_data(ide_drive_t *drive, struct request *, - void *buffer, unsigned int wcount) -{ - cris_atapi_output_bytes(drive, buffer, wcount << 2); -} - /* we only have one DMA channel on the chip for ATA, so we can keep these statically */ static cris_dma_descr_type ata_descrs[MAX_DMA_DESCRS] __attribute__ ((__aligned__(16))); static unsigned int ata_tot_size; diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index b34fd2bde96f..095e50a93869 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -613,7 +613,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, cmd_len = ATAPI_MIN_CDB_BYTES; /* send the command to the device */ - HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len); + hwif->output_data(drive, NULL, rq->cmd, cmd_len); /* start the DMA if need be */ if (info->dma) @@ -629,7 +629,7 @@ static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len) { while (len > 0) { int dum = 0; - xf(drive, &dum, sizeof(dum)); + xf(drive, NULL, &dum, sizeof(dum)); len -= sizeof(dum); } } @@ -639,7 +639,7 @@ static void ide_cd_drain_data(ide_drive_t *drive, int nsects) while (nsects > 0) { static char dum[SECTOR_SIZE]; - drive->hwif->atapi_input_bytes(drive, dum, sizeof(dum)); + drive->hwif->input_data(drive, NULL, dum, sizeof(dum)); nsects--; } } @@ -666,7 +666,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, printk(KERN_ERR "%s: %s: wrong transfer direction!\n", drive->name, __func__); - xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes; + xf = rw ? hwif->output_data : hwif->input_data; ide_cd_pad_transfer(drive, xf, len); } else if (rw == 0 && ireason == 1) { /* @@ -1019,10 +1019,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (ireason == 0) { write = 1; - xferfunc = HWIF(drive)->atapi_output_bytes; + xferfunc = hwif->output_data; } else { write = 0; - xferfunc = HWIF(drive)->atapi_input_bytes; + xferfunc = hwif->input_data; } /* transfer data */ @@ -1061,7 +1061,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (blen > thislen) blen = thislen; - xferfunc(drive, ptr, blen); + xferfunc(drive, NULL, ptr, blen); thislen -= blen; len -= blen; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 489079b8ed03..e2bcd3af45db 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -231,6 +231,7 @@ static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount, int direction) { + ide_hwif_t *hwif = drive->hwif; struct request *rq = pc->rq; struct req_iterator iter; struct bio_vec *bvec; @@ -246,9 +247,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, data = bvec_kmap_irq(bvec, &flags); if (direction) - drive->hwif->atapi_output_bytes(drive, data, count); + hwif->output_data(drive, NULL, data, count); else - drive->hwif->atapi_input_bytes(drive, data, count); + hwif->input_data(drive, NULL, data, count); bvec_kunmap_irq(data, &flags); bcount -= count; @@ -503,12 +504,12 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) } } if (pc->flags & PC_FLAG_WRITING) - xferfunc = hwif->atapi_output_bytes; + xferfunc = hwif->output_data; else - xferfunc = hwif->atapi_input_bytes; + xferfunc = hwif->input_data; if (pc->buf) - xferfunc(drive, pc->cur_pos, bcount); + xferfunc(drive, NULL, pc->cur_pos, bcount); else ide_floppy_io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING)); @@ -548,8 +549,10 @@ static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) /* Set the interrupt routine */ ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); + /* Send the actual packet */ - HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12); + hwif->output_data(drive, NULL, floppy->pc->c, 12); + return ide_started; } @@ -569,7 +572,8 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) idefloppy_floppy_t *floppy = drive->driver_data; /* Send the actual packet */ - HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12); + drive->hwif->output_data(drive, NULL, floppy->pc->c, 12); + /* Timeout for the packet command */ return IDEFLOPPY_WAIT_CMD; } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 60078cf307fb..a17fc6430001 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -422,7 +422,7 @@ static void try_to_flush_leftover_data (ide_drive_t *drive) u32 wcount = (i > 16) ? 16 : i; i -= wcount; - drive->hwif->ata_input_data(drive, NULL, buffer, wcount); + drive->hwif->input_data(drive, NULL, buffer, wcount * 4); } } 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) /* * This is used for most PIO data transfers *from* the IDE interface + * + * These routines will round up any request for an odd number of bytes, + * so if an odd len is specified, be sure that there's at least one + * extra byte allocated for the buffer. */ static void ata_input_data(ide_drive_t *drive, struct request *rq, - void *buffer, u32 wcount) + void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; + unsigned long data_addr = io_ports->data_addr; u8 io_32bit = drive->io_32bit; + len++; + if (io_32bit) { if (io_32bit & 2) { unsigned long flags; local_irq_save(flags); ata_vlb_sync(drive, io_ports->nsect_addr); - hwif->INSL(io_ports->data_addr, buffer, wcount); + hwif->INSL(data_addr, buf, len / 4); local_irq_restore(flags); } else - hwif->INSL(io_ports->data_addr, buffer, wcount); + hwif->INSL(data_addr, buf, len / 4); + + if ((len & 3) >= 2) + hwif->INSW(data_addr, (u8 *)buf + (len & ~3), 1); } else - hwif->INSW(io_ports->data_addr, buffer, wcount << 1); + hwif->INSW(data_addr, buf, len / 2); } /* * This is used for most PIO data transfers *to* the IDE interface */ static void ata_output_data(ide_drive_t *drive, struct request *rq, - void *buffer, u32 wcount) + void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; + unsigned long data_addr = io_ports->data_addr; u8 io_32bit = drive->io_32bit; if (io_32bit) { @@ -229,50 +240,21 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq, local_irq_save(flags); ata_vlb_sync(drive, io_ports->nsect_addr); - hwif->OUTSL(io_ports->data_addr, buffer, wcount); + hwif->OUTSL(data_addr, buf, len / 4); local_irq_restore(flags); } else - hwif->OUTSL(io_ports->data_addr, buffer, wcount); - } else - hwif->OUTSW(io_ports->data_addr, buffer, wcount << 1); -} - -/* - * The following routines are mainly used by the ATAPI drivers. - * - * These routines will round up any request for an odd number of bytes, - * so if an odd bytecount is specified, be sure that there's at least one - * extra byte allocated for the buffer. - */ - -static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) -{ - ide_hwif_t *hwif = HWIF(drive); + hwif->OUTSL(data_addr, buf, len / 4); - ++bytecount; - hwif->ata_input_data(drive, NULL, buffer, bytecount / 4); - if ((bytecount & 0x03) >= 2) - hwif->INSW(hwif->io_ports.data_addr, - (u8 *)buffer + (bytecount & ~0x03), 1); -} - -static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) -{ - ide_hwif_t *hwif = HWIF(drive); - - ++bytecount; - hwif->ata_output_data(drive, NULL, buffer, bytecount / 4); - if ((bytecount & 0x03) >= 2) - hwif->OUTSW(hwif->io_ports.data_addr, - (u8 *)buffer + (bytecount & ~0x03), 1); + if ((len & 3) >= 2) + hwif->OUTSW(data_addr, (u8 *)buf + (len & ~3), 1); + } else + hwif->OUTSW(data_addr, buf, len / 2); } void default_hwif_transport(ide_hwif_t *hwif) { - hwif->ata_input_data = ata_input_data; - hwif->ata_output_data = ata_output_data; - hwif->atapi_input_bytes = atapi_input_bytes; - hwif->atapi_output_bytes = atapi_output_bytes; + hwif->input_data = ata_input_data; + hwif->output_data = ata_output_data; } void ide_fix_driveid (struct hd_driveid *id) @@ -656,7 +638,7 @@ int ide_driveid_update(ide_drive_t *drive) local_irq_restore(flags); return 0; } - hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS); + hwif->input_data(drive, NULL, id, SECTOR_SIZE); (void)ide_read_status(drive); /* clear drive IRQ */ local_irq_enable(); local_irq_restore(flags); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index e06a64605215..8f7d57660643 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -124,7 +124,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) id = drive->id; /* read 512 bytes of id info */ - hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS); + hwif->input_data(drive, NULL, id, SECTOR_SIZE); drive->id_read = 1; local_irq_enable(); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 29870c415110..f4f31238bbef 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -401,7 +401,7 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, count = min( (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); - HWIF(drive)->atapi_input_bytes(drive, bh->b_data + + drive->hwif->input_data(drive, NULL, bh->b_data + atomic_read(&bh->b_count), count); bcount -= count; atomic_add(count, &bh->b_count); @@ -427,7 +427,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, return; } count = min((unsigned int)pc->b_count, (unsigned int)bcount); - HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count); + drive->hwif->output_data(drive, NULL, pc->b_data, count); bcount -= count; pc->b_data += count; pc->b_count -= count; @@ -880,16 +880,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) "data than expected - allowing transfer\n"); } iobuf = &idetape_input_buffers; - xferfunc = hwif->atapi_input_bytes; + xferfunc = hwif->input_data; } else { iobuf = &idetape_output_buffers; - xferfunc = hwif->atapi_output_bytes; + xferfunc = hwif->output_data; } if (pc->bh) iobuf(drive, pc, bcount); else - xferfunc(drive, pc->cur_pos, bcount); + xferfunc(drive, NULL, pc->cur_pos, bcount); /* Update the current position */ pc->xferred += bcount; @@ -979,7 +979,8 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) hwif->dma_ops->dma_start(drive); #endif /* Send the actual packet */ - HWIF(drive)->atapi_output_bytes(drive, pc->c, 12); + hwif->output_data(drive, NULL, pc->c, 12); + return ide_started; } diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 7f6bfd314411..0321884f9d92 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -324,9 +324,9 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq, /* do the actual data transfer */ if (write) - hwif->ata_output_data(drive, rq, buf, SECTOR_WORDS); + hwif->output_data(drive, rq, buf, SECTOR_SIZE); else - hwif->ata_input_data(drive, rq, buf, SECTOR_WORDS); + hwif->input_data(drive, rq, buf, SECTOR_SIZE); kunmap_atomic(buf, KM_BIO_SRC_IRQ); #ifdef CONFIG_HIGHMEM diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 32c044b17d45..83555ca513b5 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -44,34 +44,26 @@ int falconide_intr_lock; EXPORT_SYMBOL(falconide_intr_lock); -static void falconide_atapi_input_bytes(ide_drive_t *drive, void *buf, - unsigned int len) +static void falconide_input_data(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) { - insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); -} - -static void falconide_atapi_output_bytes(ide_drive_t *drive, void *buf, - unsigned int len) -{ - outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); -} + unsigned long data_addr = drive->hwif->io_ports.data_addr; -static void falconide_ata_input_data(ide_drive_t *drive, struct request *rq, - void *buf, unsigned int wcount) -{ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) - return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2); + return insw(data_addr, buf, (len + 1) / 2); - falconide_atapi_input_bytes(drive, buf, wcount * 4); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void falconide_ata_output_data(ide_drive_t *drive, struct request *rq, - void *buf, unsigned int wcount) +static void falconide_output_data(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) { + unsigned long data_addr = drive->hwif->io_ports.data_addr; + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) - return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2); + return outsw(data_adr, buf, (len + 1) / 2); - falconide_atapi_output_bytes(drive, buf, wcount * 4); + outsw_swapw(data_addr, buf, (len + 1) / 2); } static void __init falconide_setup_ports(hw_regs_t *hw) @@ -121,10 +113,8 @@ static int __init falconide_init(void) ide_init_port_hw(hwif, &hw); /* Atari has a byte-swapped IDE interface */ - hwif->atapi_input_bytes = falconide_atapi_input_bytes; - hwif->atapi_output_bytes = falconide_atapi_output_bytes; - hwif->ata_input_data = falconide_ata_input_data; - hwif->ata_output_data = falconide_ata_output_data; + hwif->input_data = falconide_input_data; + hwif->output_data = falconide_output_data; ide_get_lock(NULL, NULL); ide_device_add(idx, NULL); diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index deae3d2ca65e..6f535d00e638 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c @@ -72,34 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, hw->ack_intr = ack_intr; } -static void q40ide_atapi_input_bytes(ide_drive_t *drive, void *buf, - unsigned int len) +static void q40ide_input_data(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) { - insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); -} - -static void q40ide_atapi_output_bytes(ide_drive_t *drive, void *buf, - unsigned int len) -{ - outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); -} + unsigned long data_addr = drive->hwif->io_ports.data_addr; -static void q40ide_ata_input_data(ide_drive_t *drive, struct request *rq, - void *buf, unsigned int wcount) -{ if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) - return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2); + return insw(data_addr, buf, (len + 1) / 2); - q40ide_atapi_input_bytes(drive, buf, wcount * 4); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void q40ide_ata_output_data(ide_drive_t *drive, struct request *rq, - void *buf, unsigned int wcount) +static void q40ide_output_data(ide_drive_t *drive, struct request *rq, + void *buf, unsigned int len) { + unsigned long data_addr = drive->hwif->io_ports.data_addr; + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) - return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2); + return outsw(data_addr, buf, (len + 1) / 2); - q40ide_atapi_output_bytes(drive, buf, wcount * 4); + outsw_swapw(data_addr, buf, (len + 1) / 2); } /* @@ -152,10 +144,8 @@ static int __init q40ide_init(void) ide_init_port_hw(hwif, &hw); /* Q40 has a byte-swapped IDE interface */ - hwif->atapi_input_bytes = q40ide_atapi_input_bytes; - hwif->atapi_output_bytes = q40ide_atapi_output_bytes; - hwif->ata_input_data = q40ide_ata_input_data; - hwif->ata_output_data = q40ide_ata_output_data; + hwif->input_data = q40ide_input_data; + hwif->output_data = q40ide_output_data; idx[i] = hwif->index; } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 32553639aded..1168fb0a713c 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -134,6 +134,7 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount) { + ide_hwif_t *hwif = drive->hwif; int count; char *buf; @@ -145,14 +146,12 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, local_irq_save(flags); buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + pc->sg->offset; - drive->hwif->atapi_input_bytes(drive, - buf + pc->b_count, count); + hwif->input_data(drive, NULL, buf + pc->b_count, count); kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); local_irq_restore(flags); } else { buf = sg_virt(pc->sg); - drive->hwif->atapi_input_bytes(drive, - buf + pc->b_count, count); + hwif->input_data(drive, NULL, buf + pc->b_count, count); } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { @@ -172,6 +171,7 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount) { + ide_hwif_t *hwif = drive->hwif; int count; char *buf; @@ -183,14 +183,12 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, local_irq_save(flags); buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + pc->sg->offset; - drive->hwif->atapi_output_bytes(drive, - buf + pc->b_count, count); + hwif->output_data(drive, NULL, buf + pc->b_count, count); kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); local_irq_restore(flags); } else { buf = sg_virt(pc->sg); - drive->hwif->atapi_output_bytes(drive, - buf + pc->b_count, count); + hwif->output_data(drive, NULL, buf + pc->b_count, count); } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { @@ -431,7 +429,8 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) idescsi_input_buffers(drive, pc, temp); else - drive->hwif->atapi_input_bytes(drive, pc->cur_pos, temp); + hwif->input_data(drive, NULL, + pc->cur_pos, temp); printk(KERN_ERR "ide-scsi: transferred" " %d of %d bytes\n", temp, bcount); @@ -452,15 +451,13 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) if (pc->sg) idescsi_input_buffers(drive, pc, bcount); else - hwif->atapi_input_bytes(drive, pc->cur_pos, - bcount); + hwif->input_data(drive, NULL, pc->cur_pos, bcount); } else { pc->flags |= PC_FLAG_WRITING; if (pc->sg) idescsi_output_buffers(drive, pc, bcount); else - hwif->atapi_output_bytes(drive, pc->cur_pos, - bcount); + hwif->output_data(drive, NULL, pc->cur_pos, bcount); } /* Update the current position */ pc->xferred += bcount; @@ -493,8 +490,10 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) BUG_ON(HWGROUP(drive)->handler != NULL); /* Set the interrupt routine */ ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); + /* Send the actual packet */ - drive->hwif->atapi_output_bytes(drive, scsi->pc->c, 12); + hwif->output_data(drive, NULL, scsi->pc->c, 12); + if (pc->flags & PC_FLAG_DMA_OK) { pc->flags |= PC_FLAG_DMA_IN_PROGRESS; hwif->dma_ops->dma_start(drive); diff --git a/include/linux/ide.h b/include/linux/ide.h index 0cbc46bf08a5..b89b95dcb708 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -467,11 +467,8 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; - void (*ata_input_data)(ide_drive_t *, struct request *, void *, u32); - void (*ata_output_data)(ide_drive_t *, struct request *, void *, u32); - - void (*atapi_input_bytes)(ide_drive_t *, void *, u32); - void (*atapi_output_bytes)(ide_drive_t *, void *, u32); + void (*input_data)(ide_drive_t *, struct request *, void *, unsigned); + void (*output_data)(ide_drive_t *, struct request *, void *, unsigned); void (*ide_dma_clear_irq)(ide_drive_t *drive); @@ -547,7 +544,7 @@ typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); typedef int (ide_expiry_t)(ide_drive_t *); /* used by ide-cd, ide-floppy, etc. */ -typedef void (xfer_func_t)(ide_drive_t *, void *, u32); +typedef void (xfer_func_t)(ide_drive_t *, struct request *rq, void *, unsigned); typedef struct hwgroup_s { /* irq handler, if active */ @@ -1369,7 +1366,7 @@ static inline void ide_atapi_discard_data(ide_drive_t *drive, unsigned bcount) { ide_hwif_t *hwif = drive->hwif; - /* FIXME: use ->atapi_input_bytes */ + /* FIXME: use ->input_data */ while (bcount--) (void)hwif->INB(hwif->io_ports.data_addr); } @@ -1378,7 +1375,7 @@ static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount) { ide_hwif_t *hwif = drive->hwif; - /* FIXME: use ->atapi_output_bytes */ + /* FIXME: use ->output_data */ while (bcount--) hwif->OUTB(0, hwif->io_ports.data_addr); } -- cgit v1.2.3 From c5dd43ec65c1e1e378df043d517d40ed70a32cbe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:37 +0200 Subject: ide: add IDE_HFLAG_MMIO host flag (take 2) * Add IDE_HFLAG_MMIO host flag and set it for hosts which use default_hwif_mmiops(). v2: * Fix kernel panic in pmac host driver (',' should be '|'). Thanks to Kamalesh for reporting it + testing the fix and to Andrew for hinting me about the source of the issue. Cc: Kamalesh Babulal Cc: Andrew Morton Cc: Stephen Rothwell Cc: Andy Whitcroft Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 2 +- drivers/ide/arm/palm_bk3710.c | 1 + drivers/ide/arm/rapide.c | 1 + drivers/ide/legacy/ide_platform.c | 4 +++- drivers/ide/mips/swarm.c | 1 + drivers/ide/pci/sgiioc4.c | 1 + drivers/ide/pci/siimage.c | 1 + drivers/ide/ppc/pmac.c | 1 + include/linux/ide.h | 2 ++ 9 files changed, 12 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 65038ca35e10..061456914ca3 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -483,7 +483,7 @@ static const struct ide_port_info icside_v6_port_info __initdata = { .init_dma = icside_dma_off_init, .port_ops = &icside_v6_no_dma_port_ops, .dma_ops = &icside_v6_dma_ops, - .host_flags = IDE_HFLAG_SERIALIZE, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, .mwdma_mask = ATA_MWDMA2, .swdma_mask = ATA_SWDMA2, }; diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index aaf32541622d..96378ebfb31f 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -342,6 +342,7 @@ static const struct ide_port_ops palm_bk3710_ports_ops = { static const struct ide_port_info __devinitdata palm_bk3710_port_info = { .init_dma = palm_bk3710_init_dma, .port_ops = &palm_bk3710_ports_ops, + .host_flags = IDE_HFLAG_MMIO, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA4, /* (input clk 99MHz) */ .mwdma_mask = ATA_MWDMA2, diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index babc1a5e128d..1747b2358775 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -53,6 +53,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) ide_init_port_hw(hwif, &hw); + hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); idx[0] = hwif->index; diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 8279dc7ca4c0..d3bc3f24e05d 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c @@ -101,8 +101,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) ide_init_port_hw(hwif, &hw); - if (mmio) + if (mmio) { + hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); + } idx[0] = hwif->index; diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 68947626e4aa..712d17bdd470 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -109,6 +109,7 @@ static int __devinit swarm_ide_probe(struct device *dev) base = ioremap(offset, size); /* Setup MMIO ops. */ + hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); hwif->chipset = ide_generic; diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 63e28f4e6d3b..16a0bce17d69 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -573,6 +573,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitdata = { .init_dma = ide_dma_sgiioc4, .port_ops = &sgiioc4_port_ops, .dma_ops = &sgiioc4_dma_ops, + .host_flags = IDE_HFLAG_MMIO, .mwdma_mask = ATA_MWDMA2_ONLY, }; diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index c2040a017f47..076a476c3e3d 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -630,6 +630,7 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) * Fill in the basic HWIF bits */ + hwif->host_flags |= IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); hwif->hwif_data = addr; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 3cac6b2790dd..48aa019127bc 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -941,6 +941,7 @@ static const struct ide_port_info pmac_port_info = { .port_ops = &pmac_ide_port_ops, .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | IDE_HFLAG_POST_SET_MODE | + IDE_HFLAG_MMIO | IDE_HFLAG_UNMASK_IRQS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, diff --git a/include/linux/ide.h b/include/linux/ide.h index b89b95dcb708..8e79875f9872 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1069,6 +1069,8 @@ enum { IDE_HFLAG_NO_DMA = (1 << 14), /* check if host is PCI IDE device before allowing DMA */ IDE_HFLAG_NO_AUTODMA = (1 << 15), + /* host uses MMIO */ + IDE_HFLAG_MMIO = (1 << 16), /* host is CS5510/CS5520 */ IDE_HFLAG_CS5520 = IDE_HFLAG_VDMA, /* no LBA48 */ -- cgit v1.2.3 From 16bb69c14a42e64faef1ec5c724ffaca916347a1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:37 +0200 Subject: ide: remove ->INS{W,L} and ->OUTS{W,L} methods * Use ins{w,l}()/outs{w,l}() and __ide_mm_ins{w,l}()/__ide_mm_outs{w,l}() directly in ata_{in,out}put_data() (by using IDE_HFLAG_MMIO host flag to decide which I/O ops are required). * Remove no longer needed ->INS{W,L} and ->OUTS{W,L} methods (ide-h8300, au1xxx-ide and scc_pata implement their own ->{in,out}put_data methods). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/h8300/ide-h8300.c | 4 -- drivers/ide/ide-iops.c | 114 ++++++++++++++++++------------------------ drivers/ide/mips/au1xxx-ide.c | 3 -- drivers/ide/pci/scc_pata.c | 4 -- include/linux/ide.h | 4 -- 5 files changed, 48 insertions(+), 81 deletions(-) (limited to 'include') diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 90702f79d560..b5d6508d39bb 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -90,11 +90,7 @@ static inline void hwif_setup(ide_hwif_t *hwif) hwif->output_data = h8300_output_data; hwif->OUTW = mm_outw; - hwif->OUTSW = mm_outsw; hwif->INW = mm_inw; - hwif->INSW = mm_insw; - hwif->OUTSL = NULL; - hwif->INSL = NULL; } static int __init h8300_ide_init(void) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fbbbb30ae964..1789fbab2daf 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -42,16 +42,6 @@ static u16 ide_inw (unsigned long port) return (u16) inw(port); } -static void ide_insw (unsigned long port, void *addr, u32 count) -{ - insw(port, addr, count); -} - -static void ide_insl (unsigned long port, void *addr, u32 count) -{ - insl(port, addr, count); -} - static void ide_outb (u8 val, unsigned long port) { outb(val, port); @@ -67,27 +57,13 @@ static void ide_outw (u16 val, unsigned long port) outw(val, port); } -static void ide_outsw (unsigned long port, void *addr, u32 count) -{ - outsw(port, addr, count); -} - -static void ide_outsl (unsigned long port, void *addr, u32 count) -{ - outsl(port, addr, count); -} - void default_hwif_iops (ide_hwif_t *hwif) { hwif->OUTB = ide_outb; hwif->OUTBSYNC = ide_outbsync; hwif->OUTW = ide_outw; - hwif->OUTSW = ide_outsw; - hwif->OUTSL = ide_outsl; hwif->INB = ide_inb; hwif->INW = ide_inw; - hwif->INSW = ide_insw; - hwif->INSL = ide_insl; } /* @@ -104,16 +80,6 @@ static u16 ide_mm_inw (unsigned long port) return (u16) readw((void __iomem *) port); } -static void ide_mm_insw (unsigned long port, void *addr, u32 count) -{ - __ide_mm_insw((void __iomem *) port, addr, count); -} - -static void ide_mm_insl (unsigned long port, void *addr, u32 count) -{ - __ide_mm_insl((void __iomem *) port, addr, count); -} - static void ide_mm_outb (u8 value, unsigned long port) { writeb(value, (void __iomem *) port); @@ -129,16 +95,6 @@ static void ide_mm_outw (u16 value, unsigned long port) writew(value, (void __iomem *) port); } -static void ide_mm_outsw (unsigned long port, void *addr, u32 count) -{ - __ide_mm_outsw((void __iomem *) port, addr, count); -} - -static void ide_mm_outsl (unsigned long port, void *addr, u32 count) -{ - __ide_mm_outsl((void __iomem *) port, addr, count); -} - void default_hwif_mmiops (ide_hwif_t *hwif) { hwif->OUTB = ide_mm_outb; @@ -146,12 +102,8 @@ void default_hwif_mmiops (ide_hwif_t *hwif) this one is controller specific! */ hwif->OUTBSYNC = ide_mm_outbsync; hwif->OUTW = ide_mm_outw; - hwif->OUTSW = ide_mm_outsw; - hwif->OUTSL = ide_mm_outsl; hwif->INB = ide_mm_inb; hwif->INW = ide_mm_inw; - hwif->INSW = ide_mm_insw; - hwif->INSL = ide_mm_insl; } EXPORT_SYMBOL(default_hwif_mmiops); @@ -203,24 +155,39 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq, struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; u8 io_32bit = drive->io_32bit; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; len++; if (io_32bit) { - if (io_32bit & 2) { - unsigned long flags; + unsigned long uninitialized_var(flags); + if (io_32bit & 2) { local_irq_save(flags); ata_vlb_sync(drive, io_ports->nsect_addr); - hwif->INSL(data_addr, buf, len / 4); + } + + if (mmio) + __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); + else + insl(data_addr, buf, len / 4); + + if (io_32bit & 2) local_irq_restore(flags); - } else - hwif->INSL(data_addr, buf, len / 4); - if ((len & 3) >= 2) - hwif->INSW(data_addr, (u8 *)buf + (len & ~3), 1); - } else - hwif->INSW(data_addr, buf, len / 2); + if ((len & 3) >= 2) { + if (mmio) + __ide_mm_insw((void __iomem *)data_addr, + (u8 *)buf + (len & ~3), 1); + else + insw(data_addr, (u8 *)buf + (len & ~3), 1); + } + } else { + if (mmio) + __ide_mm_insw((void __iomem *)data_addr, buf, len / 2); + else + insw(data_addr, buf, len / 2); + } } /* @@ -233,22 +200,37 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq, struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; u8 io_32bit = drive->io_32bit; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { - if (io_32bit & 2) { - unsigned long flags; + unsigned long uninitialized_var(flags); + if (io_32bit & 2) { local_irq_save(flags); ata_vlb_sync(drive, io_ports->nsect_addr); - hwif->OUTSL(data_addr, buf, len / 4); + } + + if (mmio) + __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); + else + outsl(data_addr, buf, len / 4); + + if (io_32bit & 2) local_irq_restore(flags); - } else - hwif->OUTSL(data_addr, buf, len / 4); - if ((len & 3) >= 2) - hwif->OUTSW(data_addr, (u8 *)buf + (len & ~3), 1); - } else - hwif->OUTSW(data_addr, buf, len / 2); + if ((len & 3) >= 2) { + if (mmio) + __ide_mm_outsw((void __iomem *)data_addr, + (u8 *)buf + (len & ~3), 1); + else + outsw(data_addr, (u8 *)buf + (len & ~3), 1); + } + } else { + if (mmio) + __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2); + else + outsw(data_addr, buf, len / 2); + } } void default_hwif_transport(ide_hwif_t *hwif) diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index b28fa794b314..1a6c27b32498 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -609,9 +609,6 @@ static int au_ide_probe(struct device *dev) #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA hwif->input_data = au1xxx_input_data; hwif->output_data = au1xxx_output_data; - - hwif->INSW = auide_insw; - hwif->OUTSW = auide_outsw; #endif hwif->select_data = 0; /* no chipset-specific code */ hwif->config_data = 0; /* no chipset-specific code */ diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index a7a2c58482a2..d11df45a2ae8 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -669,13 +669,9 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) hwif->INB = scc_ide_inb; hwif->INW = scc_ide_inw; - hwif->INSW = scc_ide_insw; - hwif->INSL = scc_ide_insl; hwif->OUTB = scc_ide_outb; hwif->OUTBSYNC = scc_ide_outbsync; hwif->OUTW = scc_ide_outw; - hwif->OUTSW = scc_ide_outsw; - hwif->OUTSL = scc_ide_outsl; hwif->dma_base = dma_base; hwif->config_data = ports->ctl; diff --git a/include/linux/ide.h b/include/linux/ide.h index 8e79875f9872..5ab9773b75fb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -475,13 +475,9 @@ typedef struct hwif_s { void (*OUTB)(u8 addr, unsigned long port); void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); void (*OUTW)(u16 addr, unsigned long port); - void (*OUTSW)(unsigned long port, void *addr, u32 count); - void (*OUTSL)(unsigned long port, void *addr, u32 count); u8 (*INB)(unsigned long port); u16 (*INW)(unsigned long port); - void (*INSW)(unsigned long port, void *addr, u32 count); - void (*INSL)(unsigned long port, void *addr, u32 count); /* dma physical region descriptor table (cpu view) */ unsigned int *dmatable_cpu; -- cgit v1.2.3 From 1fc142589e58b20a67582974b8848595a2c7432e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:39 +0200 Subject: ide: add ide_execute_pkt_cmd() helper Add ide_execute_pkt_cmd() helper for executing PACKET command, then convert ATAPI device drivers to use it. As a nice side-effect this fixes ide-{floppy,tape,scsi} w.r.t. ide_lock taking (ide-cd was OK). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 9 +-------- drivers/ide/ide-floppy.c | 4 +--- drivers/ide/ide-iops.c | 12 +++++++++++- drivers/ide/ide-tape.c | 4 +--- drivers/scsi/ide-scsi.c | 4 +--- include/linux/ide.h | 2 ++ 6 files changed, 17 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 095e50a93869..0881ddc5831e 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -555,14 +555,7 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, ATAPI_WAIT_PC, cdrom_timer_expiry); return ide_started; } else { - unsigned long flags; - - /* packet command */ - spin_lock_irqsave(&ide_lock, flags); - hwif->OUTBSYNC(drive, WIN_PACKETCMD, - hwif->io_ports.command_addr); - ndelay(400); - spin_unlock_irqrestore(&ide_lock, flags); + ide_execute_pkt_cmd(drive); return (*handler) (drive); } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index da79248633a4..0039789b0eb9 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -696,9 +696,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, return ide_started; } else { /* Issue the packet command */ - hwif->OUTBSYNC(drive, WIN_PACKETCMD, - hwif->io_ports.command_addr); - ndelay(400); + ide_execute_pkt_cmd(drive); return (*pkt_xfer_routine) (drive); } } diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 7f2b4edc6369..dfe47d5eb157 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -801,9 +801,19 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, ndelay(400); spin_unlock_irqrestore(&ide_lock, flags); } - EXPORT_SYMBOL(ide_execute_command); +void ide_execute_pkt_cmd(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + unsigned long flags; + + spin_lock_irqsave(&ide_lock, flags); + hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr); + ndelay(400); + spin_unlock_irqrestore(&ide_lock, flags); +} +EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); /* needed below */ static ide_startstop_t do_reset1 (ide_drive_t *, int); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index dc88431a2359..71d07d740add 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1056,9 +1056,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, IDETAPE_WAIT_CMD, NULL); return ide_started; } else { - hwif->OUTBSYNC(drive, WIN_PACKETCMD, - hwif->io_ports.command_addr); - ndelay(400); + ide_execute_pkt_cmd(drive); return idetape_transfer_pc(drive); } } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 8b1c783e259b..7964cc146152 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -574,9 +574,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, return ide_started; } else { /* Issue the packet command */ - hwif->OUTBSYNC(drive, WIN_PACKETCMD, - hwif->io_ports.command_addr); - ndelay(400); + ide_execute_pkt_cmd(drive); return idescsi_transfer_pc(drive); } } diff --git a/include/linux/ide.h b/include/linux/ide.h index 5ab9773b75fb..3927996d2f82 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -822,6 +822,8 @@ extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigne void ide_execute_command(ide_drive_t *, u8, ide_handler_t *, unsigned int, ide_expiry_t *); +void ide_execute_pkt_cmd(ide_drive_t *); + ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); -- cgit v1.2.3 From 089c5c7e0089c3461545be936bcd236cbf16b79a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:39 +0200 Subject: ide: factor out debugging code from ide_tf_load() Factor out debugging code from ide_tf_load() to ide_tf_dump() helper and update ide_tf_load() users accordingly. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 1 + drivers/ide/ide-taskfile.c | 29 +++++++++++++++++------------ include/linux/ide.h | 2 ++ 3 files changed, 20 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c32ca769b963..a6f2186773fa 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1680,6 +1680,7 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) task.tf.lbam = bcount & 0xff; task.tf.lbah = (bcount >> 8) & 0xff; + ide_tf_dump(drive->name, &task.tf); ide_tf_load(drive, &task); } diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0321884f9d92..416ce54af7ad 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -33,26 +33,29 @@ #include #include -void ide_tf_load(ide_drive_t *drive, ide_task_t *task) +void ide_tf_dump(const char *s, struct ide_taskfile *tf) { - ide_hwif_t *hwif = drive->hwif; - struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &task->tf; - u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - - if (task->tf_flags & IDE_TFLAG_FLAGGED) - HIHI = 0xFF; - #ifdef DEBUG printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x " "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", - drive->name, tf->feature, tf->nsect, tf->lbal, + s, tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah, tf->device, tf->command); printk("%s: hob: nsect 0x%02x lbal 0x%02x " "lbam 0x%02x lbah 0x%02x\n", - drive->name, tf->hob_nsect, tf->hob_lbal, + s, tf->hob_nsect, tf->hob_lbal, tf->hob_lbam, tf->hob_lbah); #endif +} + +void ide_tf_load(ide_drive_t *drive, ide_task_t *task) +{ + ide_hwif_t *hwif = drive->hwif; + struct ide_io_ports *io_ports = &hwif->io_ports; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + + if (task->tf_flags & IDE_TFLAG_FLAGGED) + HIHI = 0xFF; ide_set_irq(drive, 1); @@ -149,8 +152,10 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; - if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) + if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { + ide_tf_dump(drive->name, tf); ide_tf_load(drive, task); + } switch (task->data_phase) { case TASKFILE_MULTI_OUT: diff --git a/include/linux/ide.h b/include/linux/ide.h index 3927996d2f82..d7d8bb69db4b 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -960,6 +960,8 @@ typedef struct ide_task_s { void *special; /* valid_t generally */ } ide_task_t; +void ide_tf_dump(const char *, struct ide_taskfile *); + void ide_tf_load(ide_drive_t *, ide_task_t *); void ide_tf_read(ide_drive_t *, ide_task_t *); -- cgit v1.2.3 From 94cd5b62ff9bb07ef065333eb97438f115a75890 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:40 +0200 Subject: ide: add ->tf_load and ->tf_read methods * Add ->tf_load and ->tf_read methods to ide_hwif_t and set the default methods in default_hwif_transport(). * Use ->tf_{load,read} instead o calling ide_tf_{load,read}() directly. * Make ide_tf_{load,read}() static. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 4 ++-- drivers/ide/ide-iops.c | 7 +++++-- drivers/ide/ide-lib.c | 2 +- drivers/ide/ide-taskfile.c | 2 +- include/linux/ide.h | 8 +++++--- 5 files changed, 14 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 5b675a001382..8d7c1a09e1e7 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -330,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) tf->error = err; tf->status = stat; - ide_tf_read(drive, task); + drive->hwif->tf_read(drive, task); if (task->tf_flags & IDE_TFLAG_DYN) kfree(task); @@ -1638,7 +1638,7 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) task.tf.lbah = (bcount >> 8) & 0xff; ide_tf_dump(drive->name, &task.tf); - ide_tf_load(drive, &task); + drive->hwif->tf_load(drive, &task); } EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load); diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index ac9e063bcf93..65275454a209 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -127,7 +127,7 @@ void SELECT_MASK (ide_drive_t *drive, int mask) port_ops->maskproc(drive, mask); } -void ide_tf_load(ide_drive_t *drive, ide_task_t *task) +static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; @@ -172,7 +172,7 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) io_ports->device_addr); } -void ide_tf_read(ide_drive_t *drive, ide_task_t *task) +static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; @@ -323,6 +323,9 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq, void default_hwif_transport(ide_hwif_t *hwif) { + hwif->tf_load = ide_tf_load; + hwif->tf_read = ide_tf_read; + hwif->input_data = ata_input_data; hwif->output_data = ata_output_data; } diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 6f04ea3e93a8..47af80df6872 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -487,7 +487,7 @@ static void ide_dump_sector(ide_drive_t *drive) else task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; - ide_tf_read(drive, &task); + drive->hwif->tf_read(drive, &task); if (lba48 || (tf->device & ATA_LBA)) printk(", LBAsect=%llu", diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 9ec3ecd4a3a5..9a846a0cd5a4 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -109,7 +109,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); - ide_tf_load(drive, task); + hwif->tf_load(drive, task); } switch (task->data_phase) { diff --git a/include/linux/ide.h b/include/linux/ide.h index d7d8bb69db4b..8e95579c3d34 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -427,6 +427,8 @@ struct ide_dma_ops { void (*dma_timeout)(struct ide_drive_s *); }; +struct ide_task_s; + typedef struct hwif_s { struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ struct hwif_s *mate; /* other hwif from same PCI chip */ @@ -467,6 +469,9 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; + void (*tf_load)(ide_drive_t *, struct ide_task_s *); + void (*tf_read)(ide_drive_t *, struct ide_task_s *); + void (*input_data)(ide_drive_t *, struct request *, void *, unsigned); void (*output_data)(ide_drive_t *, struct request *, void *, unsigned); @@ -962,9 +967,6 @@ typedef struct ide_task_s { void ide_tf_dump(const char *, struct ide_taskfile *); -void ide_tf_load(ide_drive_t *, ide_task_t *); -void ide_tf_read(ide_drive_t *, ide_task_t *); - extern void SELECT_DRIVE(ide_drive_t *); extern void SELECT_MASK(ide_drive_t *, int); -- cgit v1.2.3 From 7c0daf2681f140dd9f39cd95966f471b5c904d8a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:41 +0200 Subject: ide: remove ->INW and ->OUTW methods * Remove no longer used ->INW and ->OUTW methods. While at it: * scc_pata.c: scc_ide_{out,in}w() is called only in scc_tf_{load,read}() so inline it there. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cris/ide-cris.c | 2 -- drivers/ide/h8300/ide-h8300.c | 3 --- drivers/ide/ide-iops.c | 24 ------------------------ drivers/ide/pci/scc_pata.c | 19 +++---------------- include/linux/ide.h | 2 -- 5 files changed, 3 insertions(+), 47 deletions(-) (limited to 'include') diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index d628141098c2..38b069c0057f 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -903,10 +903,8 @@ static int __init init_e100_ide(void) hwif->output_data = cris_output_data; hwif->OUTB = &cris_ide_outb; - hwif->OUTW = &cris_ide_outw; hwif->OUTBSYNC = &cris_ide_outbsync; hwif->INB = &cris_ide_inb; - hwif->INW = &cris_ide_inw; hwif->cbl = ATA_CBL_PATA40; idx[h] = hwif->index; diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 6bd143cf0891..ecf53bb0d2aa 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -176,9 +176,6 @@ static inline void hwif_setup(ide_hwif_t *hwif) hwif->input_data = h8300_input_data; hwif->output_data = h8300_output_data; - - hwif->OUTW = mm_outw; - hwif->INW = mm_inw; } static int __init h8300_ide_init(void) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index e981e2943073..daa23b19440e 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -37,11 +37,6 @@ static u8 ide_inb (unsigned long port) return (u8) inb(port); } -static u16 ide_inw (unsigned long port) -{ - return (u16) inw(port); -} - static void ide_outb (u8 val, unsigned long port) { outb(val, port); @@ -52,18 +47,11 @@ static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port) outb(addr, port); } -static void ide_outw (u16 val, unsigned long port) -{ - outw(val, port); -} - void default_hwif_iops (ide_hwif_t *hwif) { hwif->OUTB = ide_outb; hwif->OUTBSYNC = ide_outbsync; - hwif->OUTW = ide_outw; hwif->INB = ide_inb; - hwif->INW = ide_inw; } /* @@ -75,11 +63,6 @@ static u8 ide_mm_inb (unsigned long port) return (u8) readb((void __iomem *) port); } -static u16 ide_mm_inw (unsigned long port) -{ - return (u16) readw((void __iomem *) port); -} - static void ide_mm_outb (u8 value, unsigned long port) { writeb(value, (void __iomem *) port); @@ -90,20 +73,13 @@ static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port) writeb(value, (void __iomem *) port); } -static void ide_mm_outw (u16 value, unsigned long port) -{ - writew(value, (void __iomem *) port); -} - void default_hwif_mmiops (ide_hwif_t *hwif) { hwif->OUTB = ide_mm_outb; /* Most systems will need to override OUTBSYNC, alas however this one is controller specific! */ hwif->OUTBSYNC = ide_mm_outbsync; - hwif->OUTW = ide_mm_outw; hwif->INB = ide_mm_inb; - hwif->INW = ide_mm_inw; } EXPORT_SYMBOL(default_hwif_mmiops); diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index cb635a66030e..a17f73ec577a 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -126,12 +126,6 @@ static u8 scc_ide_inb(unsigned long port) return (u8)data; } -static u16 scc_ide_inw(unsigned long port) -{ - u32 data = in_be32((void*)port); - return (u16)data; -} - static void scc_ide_insw(unsigned long port, void *addr, u32 count) { u16 *ptr = (u16 *)addr; @@ -154,11 +148,6 @@ static void scc_ide_outb(u8 addr, unsigned long port) out_be32((void*)port, addr); } -static void scc_ide_outw(u16 addr, unsigned long port) -{ - out_be32((void*)port, addr); -} - static void scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) { @@ -630,8 +619,8 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) ide_set_irq(drive, 1); if (task->tf_flags & IDE_TFLAG_OUT_DATA) - scc_ide_outw((tf->hob_data << 8) | tf->data, - io_ports->data_addr); + out_be32((void *)io_ports->data_addr, + (tf->hob_data << 8) | tf->data); if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) scc_ide_outb(tf->hob_feature, io_ports->feature_addr); @@ -666,7 +655,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) struct ide_taskfile *tf = &task->tf; if (task->tf_flags & IDE_TFLAG_IN_DATA) { - u16 data = scc_ide_inw(io_ports->data_addr); + u16 data = (u16)in_be32((void *)io_ports->data_addr); tf->data = data & 0xff; tf->hob_data = (data >> 8) & 0xff; @@ -755,10 +744,8 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) hwif->output_data = scc_output_data; hwif->INB = scc_ide_inb; - hwif->INW = scc_ide_inw; hwif->OUTB = scc_ide_outb; hwif->OUTBSYNC = scc_ide_outbsync; - hwif->OUTW = scc_ide_outw; hwif->dma_base = dma_base; hwif->config_data = ports->ctl; diff --git a/include/linux/ide.h b/include/linux/ide.h index 8e95579c3d34..2053d7d86b1d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -479,10 +479,8 @@ typedef struct hwif_s { void (*OUTB)(u8 addr, unsigned long port); void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); - void (*OUTW)(u16 addr, unsigned long port); u8 (*INB)(unsigned long port); - u16 (*INW)(unsigned long port); /* dma physical region descriptor table (cpu view) */ unsigned int *dmatable_cpu; -- cgit v1.2.3 From 9f87abe892f899f19df8d472f937ee955cd6264b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:41 +0200 Subject: ide: add ide_pad_transfer() helper * Add ide_pad_transfer() helper (which uses ->{in,out}put_data methods internally so the transfer is also padded to drive+host requirements) and use it instead of ide_atapi_{write_zeros,discard_data}(). * Remove no longer needed ide_atapi_{write_zeros,discard_data}(). Cc: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-floppy.c | 7 ++----- drivers/ide/ide-io.c | 15 +++++++++++++++ drivers/ide/ide-tape.c | 4 ++-- drivers/scsi/ide-scsi.c | 6 +++--- include/linux/ide.h | 25 ++----------------------- 5 files changed, 24 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0039789b0eb9..f05fbc2bd7a8 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -262,10 +262,7 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, if (bcount) { printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n", drive->name, __func__, bcount); - if (direction) - ide_atapi_write_zeros(drive, bcount); - else - ide_atapi_discard_data(drive, bcount); + ide_pad_transfer(drive, direction, bcount); } } @@ -491,7 +488,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) printk(KERN_ERR "ide-floppy: The floppy wants " "to send us more data than expected " "- discarding data\n"); - ide_atapi_discard_data(drive, bcount); + ide_pad_transfer(drive, 0, bcount); ide_set_handler(drive, &idefloppy_pc_intr, diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 8d7c1a09e1e7..788783da9025 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1642,3 +1642,18 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) } EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load); + +void ide_pad_transfer(ide_drive_t *drive, int write, int len) +{ + ide_hwif_t *hwif = drive->hwif; + u8 buf[4] = { 0 }; + + while (len > 0) { + if (write) + hwif->output_data(drive, NULL, buf, min(4, len)); + else + hwif->input_data(drive, NULL, buf, min(4, len)); + len -= 4; + } +} +EXPORT_SYMBOL_GPL(ide_pad_transfer); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 71d07d740add..54a43b044608 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -395,7 +395,7 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, if (bh == NULL) { printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_input_buffers\n"); - ide_atapi_discard_data(drive, bcount); + ide_pad_transfer(drive, 0, bcount); return; } count = min( @@ -871,7 +871,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) printk(KERN_ERR "ide-tape: The tape wants to " "send us more data than expected " "- discarding data\n"); - ide_atapi_discard_data(drive, bcount); + ide_pad_transfer(drive, 0, bcount); ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); return ide_started; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 7964cc146152..44d8d5163a1a 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -164,7 +164,7 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, if (bcount) { printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); - ide_atapi_discard_data(drive, bcount); + ide_pad_transfer(drive, 0, bcount); } } @@ -201,7 +201,7 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, if (bcount) { printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); - ide_atapi_write_zeros(drive, bcount); + ide_pad_transfer(drive, 1, bcount); } } @@ -438,7 +438,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) } pc->xferred += temp; pc->cur_pos += temp; - ide_atapi_discard_data(drive, bcount - temp); + ide_pad_transfer(drive, 0, bcount - temp); ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); return ide_started; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 2053d7d86b1d..7a5da394b98f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -827,6 +827,8 @@ void ide_execute_command(ide_drive_t *, u8, ide_handler_t *, unsigned int, void ide_execute_pkt_cmd(ide_drive_t *); +void ide_pad_transfer(ide_drive_t *, int, int); + ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); @@ -1359,27 +1361,4 @@ static inline u8 ide_read_error(ide_drive_t *drive) return hwif->INB(hwif->io_ports.error_addr); } - -/* - * Too bad. The drive wants to send us data which we are not ready to accept. - * Just throw it away. - */ -static inline void ide_atapi_discard_data(ide_drive_t *drive, unsigned bcount) -{ - ide_hwif_t *hwif = drive->hwif; - - /* FIXME: use ->input_data */ - while (bcount--) - (void)hwif->INB(hwif->io_ports.data_addr); -} - -static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount) -{ - ide_hwif_t *hwif = drive->hwif; - - /* FIXME: use ->output_data */ - while (bcount--) - hwif->OUTB(0, hwif->io_ports.data_addr); -} - #endif /* _IDE_H */ -- cgit v1.2.3 From 41051a141dcc67f4c5011a2ab2b547e80b9ac509 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:42 +0200 Subject: ide: remove ->dma_vendor{1,3} fields from ide_hwif_t * Use 'hwif->dma_base + {1,3}' instead of hwif->dma_vendor{1,3} in pdc202xx_new host driver. * Remove no longer needed ->dma_vendor{1,3} fields from ide_hwif_t. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 4 ---- drivers/ide/pci/pdc202xx_new.c | 8 ++++---- include/linux/ide.h | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index c352cf27b6e7..767820db7cae 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -858,12 +858,8 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base) if (!hwif->dma_command) hwif->dma_command = hwif->dma_base + 0; - if (!hwif->dma_vendor1) - hwif->dma_vendor1 = hwif->dma_base + 1; if (!hwif->dma_status) hwif->dma_status = hwif->dma_base + 2; - if (!hwif->dma_vendor3) - hwif->dma_vendor3 = hwif->dma_base + 3; if (!hwif->dma_prdtable) hwif->dma_prdtable = hwif->dma_base + 4; diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index ec9bd7b352fc..070df8ab3b21 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -83,8 +83,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) { u8 value; - outb(index, hwif->dma_vendor1); - value = inb(hwif->dma_vendor3); + outb(index, hwif->dma_base + 1); + value = inb(hwif->dma_base + 3); DBG("index[%02X] value[%02X]\n", index, value); return value; @@ -97,8 +97,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index) */ static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value) { - outb(index, hwif->dma_vendor1); - outb(value, hwif->dma_vendor3); + outb(index, hwif->dma_base + 1); + outb(value, hwif->dma_base + 3); DBG("index[%02X] value[%02X]\n", index, value); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 7a5da394b98f..d1d0111e48aa 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -505,9 +505,7 @@ typedef struct hwif_s { unsigned long dma_base; /* base addr for dma ports */ unsigned long dma_command; /* dma command register */ - unsigned long dma_vendor1; /* dma vendor 1 register */ unsigned long dma_status; /* dma status register */ - unsigned long dma_vendor3; /* dma vendor 3 register */ unsigned long dma_prdtable; /* actual prd table address */ unsigned long config_data; /* for use by chipset-specific code */ -- cgit v1.2.3 From 55224bc86a39409d55e47fd45573642ac709bb8f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 28 Apr 2008 23:44:42 +0200 Subject: ide: remove ->dma_prdtable field from ide_hwif_t * Use 'hwif->dma_base + {4,8}' instead of hwif->dma_prdtable in {ide,scc}_dma_setup(). * Remove no longer needed ->dma_prdtable field from ide_hwif_t. While at it: * Use ATA_DMA_TABLE_OFS define. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 7 +++---- drivers/ide/pci/scc_pata.c | 3 +-- include/linux/ide.h | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 767820db7cae..653b1ade13d3 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -464,9 +464,10 @@ int ide_dma_setup(ide_drive_t *drive) /* PRD table */ if (hwif->mmio) - writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable); + writel(hwif->dmatable_dma, + (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); else - outl(hwif->dmatable_dma, hwif->dma_prdtable); + outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); /* specify r/w */ hwif->OUTB(reading, hwif->dma_command); @@ -860,8 +861,6 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base) hwif->dma_command = hwif->dma_base + 0; if (!hwif->dma_status) hwif->dma_status = hwif->dma_base + 2; - if (!hwif->dma_prdtable) - hwif->dma_prdtable = hwif->dma_base + 4; hwif->dma_ops = &sff_dma_ops; } diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 144938188325..910fb00deb71 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -304,7 +304,7 @@ static int scc_dma_setup(ide_drive_t *drive) } /* PRD table */ - out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma); + out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); /* specify r/w */ out_be32((void __iomem *)hwif->dma_command, reading); @@ -838,7 +838,6 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->dma_command = hwif->dma_base; hwif->dma_status = hwif->dma_base + 0x04; - hwif->dma_prdtable = hwif->dma_base + 0x08; /* PTERADD */ out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); diff --git a/include/linux/ide.h b/include/linux/ide.h index d1d0111e48aa..b0135b0c3a04 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -506,7 +506,6 @@ typedef struct hwif_s { unsigned long dma_base; /* base addr for dma ports */ unsigned long dma_command; /* dma command register */ unsigned long dma_status; /* dma status register */ - unsigned long dma_prdtable; /* actual prd table address */ unsigned long config_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */ -- cgit v1.2.3