bk://bart.bkbits.net/ide-dev-2.6
bzolnier@trik.(none)|ChangeSet|20040923212539|44737 bzolnier

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/09/23 23:25:39+02:00 bzolnier@trik.(none) 
#   [ide] fix ide-dma.c build warning
# 
# drivers/ide/ide-dma.c
#   2004/09/23 23:25:19+02:00 bzolnier@trik.(none) +0 -1
#   [ide] fix ide-dma.c build warning
# 
# ChangeSet
#   2004/09/23 22:24:27+02:00 bzolnier@trik.(none) 
#   [ide] remap hwif->sg_table only when needed
#   
#   ->dma_setup() can also fail when DMA is not supported
#   for some reason so remap hwif->sg_table only if it could
#   have been changed
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +3 -1
#   [ide] remap hwif->sg_table only when needed
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +1 -0
#   [ide] remap hwif->sg_table only when needed
# 
# drivers/ide/ide-io.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +1 -2
#   [ide] remap hwif->sg_table only when needed
# 
# drivers/ide/ide-dma.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +3 -1
#   [ide] remap hwif->sg_table only when needed
# 
# drivers/ide/ide-disk.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +6 -2
#   [ide] remap hwif->sg_table only when needed
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/22 17:16:48+02:00 bzolnier@trik.(none) +3 -1
#   [ide] remap hwif->sg_table only when needed
# 
# ChangeSet
#   2004/09/23 22:16:42+02:00 bzolnier@trik.(none) 
#   [ide] kill ide_raw_build_sglist()
#   
#   ide_build_sglist() can be now used for REQ_DRIVE_TASKFILE requests.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/22 17:16:10+02:00 bzolnier@trik.(none) +0 -1
#   [ide] kill ide_raw_build_sglist()
# 
# drivers/ide/ppc/pmac.c
#   2004/09/22 17:16:10+02:00 bzolnier@trik.(none) +2 -5
#   [ide] kill ide_raw_build_sglist()
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/22 17:16:10+02:00 bzolnier@trik.(none) +1 -4
#   [ide] kill ide_raw_build_sglist()
# 
# drivers/ide/ide-dma.c
#   2004/09/22 17:16:10+02:00 bzolnier@trik.(none) +4 -35
#   [ide] kill ide_raw_build_sglist()
# 
# ChangeSet
#   2004/09/23 22:11:13+02:00 bzolnier@trik.(none) 
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
#   
#   Also:
#   - fix sg->length for PIO-multi REQ_DRIVE_TASKFILE requests
#     (I somehow missed multiply by SECTOR_SIZE)
#   - in ide-dma.c use one sg for REQ_DRIVE_TASKFILE requests
#     (no reason for 128 sectors per sg limit)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/22 17:15:59+02:00 bzolnier@trik.(none) +1 -0
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
# 
# drivers/ide/ide-io.c
#   2004/09/22 17:15:59+02:00 bzolnier@trik.(none) +16 -6
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
# 
# drivers/ide/ide-dma.c
#   2004/09/23 22:10:44+02:00 bzolnier@trik.(none) +7 -22
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
# 
# drivers/ide/arm/icside.c
#   2004/09/22 17:15:59+02:00 bzolnier@trik.(none) +4 -8
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/22 17:15:59+02:00 bzolnier@trik.(none) +2 -8
#   [ide] split off ide_map_sg() from ide_init_sg_cmd()
# 
# ChangeSet
#   2004/09/23 22:01:16+02:00 bzolnier@trik.(none) 
#   [ide] pmac: kill pmac_ide_[raw_]build_sglist()
#   
#   Just use ide_dma_[raw_]build_sglist() from ide-dma.c.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/23 22:00:55+02:00 bzolnier@trik.(none) +2 -52
#   [ide] pmac: kill pmac_ide_[raw_]build_sglist()
# 
# ChangeSet
#   2004/09/23 21:55:26+02:00 bzolnier@trik.(none) 
#   [ide] pmac: use more ide_hwif_t fields
#   
#   Use dmatable_dma, sg_table, sg_nents and sg_dma_direction fields
#   of ide_hwif_t and remove their equivalents from pmac_ide_hwif_t.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/23 21:55:00+02:00 bzolnier@trik.(none) +26 -40
#   [ide] pmac: use more ide_hwif_t fields
# 
# ChangeSet
#   2004/09/23 21:37:02+02:00 bzolnier@trik.(none) 
#   Merge trik.(none):/home/bzolnier/bk/ide-2.6
#   into trik.(none):/home/bzolnier/bk/ide-dev-2.6
# 
# drivers/ide/ide-io.c
#   2004/09/23 21:36:57+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/23 21:16:43+02:00 bzolnier@trik.(none) 
#   [ide] cs5530: kill /proc/ide/cs5530
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/cs5530.c
#   2004/09/23 21:16:21+02:00 bzolnier@trik.(none) +0 -58
#   [ide] cs5530: kill /proc/ide/cs5530
# 
# ChangeSet
#   2004/09/23 21:11:35+02:00 bzolnier@trik.(none) 
#   [ide] sc1200: kill /proc/ide/sc1200
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sc1200.c
#   2004/09/22 17:17:10+02:00 bzolnier@trik.(none) +0 -65
#   [ide] sc1200: kill /proc/ide/sc1200
# 
# ChangeSet
#   2004/09/23 21:08:39+02:00 bzolnier@trik.(none) 
#   [ide] pdc202xx_new: kill /proc/ide/pdcnew
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/pdc202xx_new.h
#   2004/09/22 17:15:00+02:00 bzolnier@trik.(none) +0 -2
#   [ide] pdc202xx_new: kill /proc/ide/pdcnew
# 
# drivers/ide/pci/pdc202xx_new.c
#   2004/09/22 17:15:00+02:00 bzolnier@trik.(none) +0 -64
#   [ide] pdc202xx_new: kill /proc/ide/pdcnew
# 
# ChangeSet
#   2004/09/23 21:02:26+02:00 bzolnier@trik.(none) 
#   [ide] triflex: kill /proc/ide/triflex
#   
#   It fixes OOPS on two single channel controllers.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/triflex.c
#   2004/09/22 17:14:16+02:00 bzolnier@trik.(none) +0 -62
#   [ide] triflex: kill /proc/ide/triflex
# 
# ChangeSet
#   2004/09/23 20:54:22+02:00 bzolnier@trik.(none) 
#   Merge trik.(none):/home/bzolnier/bk/ide-2.6
#   into trik.(none):/home/bzolnier/bk/ide-dev-2.6
# 
# include/linux/ide.h
#   2004/09/23 20:54:18+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ppc/pmac.c
#   2004/09/23 20:54:18+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/23 20:54:18+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/arm/icside.c
#   2004/09/23 20:54:18+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# drivers/ide/ide-dma.c
#   2004/09/23 20:54:17+02:00 bzolnier@trik.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/17 14:49:54+02:00 bzolnier@trik.(none) 
#   [ide] kill /proc/ide/ide?/config
#    
#   I first wanted to deprecate it but after discovering that:
#   - writes to PCI config space are non-functional since 2.4.21
#   - reads of full PCI config space are allowed for normal users
#   I think that there we are better off removing it immediately.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-proc.c
#   2004/09/16 23:08:34+02:00 bzolnier@trik.(none) +0 -257
#   [ide] kill /proc/ide/ide?/config
#    
#   I first wanted to deprecate it but after discovering that:
#   - writes to PCI config space are non-functional since 2.4.21
#   - reads of full PCI config space are allowed for normal users
#   I think that there we are better off removing it immediately.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:44:21+02:00 bzolnier@trik.(none) 
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -2
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/scsi/ide-scsi.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +3 -5
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/trm290.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -3
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sl82c105.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +3 -5
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -5
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/pdc202xx_old.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +3 -3
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/hpt366.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +4 -4
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +1 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -2
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-tape.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +1 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-floppy.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +1 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-dma.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +4 -5
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +1 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-cd.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -1
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/arm/icside.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +2 -3
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/16 22:30:30+02:00 bzolnier@trik.(none) +3 -4
#   [ide] convert ide_hwif_t->ide_dma_begin() to ->dma_start()
#   
#   Make ->ide_dma_begin() functions void and rename them to ->dma_start().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:42:26+02:00 bzolnier@trik.(none) 
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +1 -2
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +3 -48
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/trm290.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +2 -52
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +0 -7
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +1 -2
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +4 -11
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-dma.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +3 -43
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +8 -2
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/arm/icside.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +2 -60
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/16 22:30:16+02:00 bzolnier@trik.(none) +12 -65
#   [ide] add ide_hwif_t->dma_exec_cmd()
#   
#   - split off ->dma_exec_cmd() from ->ide_dma_[read,write] functions
#   - choose command to execute by ->dma_exec_cmd() in higher layers
#     and remove ->ide_dma_[read,write]
#   
#   Some real bugs are also fixed:
#   - in Etrax ide.c driver REQ_DRIVE_TASKFILE requests weren't
#     handled properly for drive->addressing == 0
#   - in trm290.c read and write commands were interchanged
#   - in sgiioc4.c commands weren't sent to disk devices
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:40:58+02:00 bzolnier@trik.(none) 
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +2 -3
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/scsi/ide-scsi.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +3 -6
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +3 -16
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/trm290.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +31 -35
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +21 -20
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/ns87415.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +3 -15
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/alim15x3.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +7 -8
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +1 -0
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +11 -2
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-tape.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +2 -6
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-floppy.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +3 -7
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-dma.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +15 -28
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +8 -6
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-cd.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +3 -9
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/arm/icside.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +9 -15
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/16 22:29:51+02:00 bzolnier@trik.(none) +25 -37
#   [ide] add ide_hwif_t->dma_setup()
#   
#   - tag REQ_DRIVE_TASKFILE write requests with REQ_RW
#   - split off ->dma_setup() from ->ide_dma_[read,write] functions
#   - use ->dma_setup() directly in ATAPI drivers and remove media
#     checks from ->ide_dma_[read,write]
#   - ->ide_dma_[read,write,begin] cannot fail now
#   - in Etrax ide.c setup DMA for ATAPI devices before sending
#     command to drive (so setup order is the same as for disks)
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:35:32+02:00 bzolnier@trik.(none) 
#   [ide] unify PIO code
#   
#   Use PIO code from ide-taskfile.c in ide-disk.c so:
#   - drive status is checked after PIO read
#   - request is failed if invalid data phase
#     is detected during PIO write
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:29:44+02:00 bzolnier@trik.(none) +0 -5
#   [ide] unify PIO code
#   
#   Use PIO code from ide-taskfile.c in ide-disk.c so:
#   - drive status is checked after PIO read
#   - request is failed if invalid data phase
#     is detected during PIO write
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:29:44+02:00 bzolnier@trik.(none) +5 -10
#   [ide] unify PIO code
#   
#   Use PIO code from ide-taskfile.c in ide-disk.c so:
#   - drive status is checked after PIO read
#   - request is failed if invalid data phase
#     is detected during PIO write
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:29:44+02:00 bzolnier@trik.(none) +2 -84
#   [ide] unify PIO code
#   
#   Use PIO code from ide-taskfile.c in ide-disk.c so:
#   - drive status is checked after PIO read
#   - request is failed if invalid data phase
#     is detected during PIO write
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:34:04+02:00 bzolnier@trik.(none) 
#   [ide] merge PIO write/multiwrite code (ide-disk.c)
#   
#   Merge multwrite_intr() into write_intr().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/10 23:50:32+02:00 bzolnier@trik.(none) +6 -34
#   [ide] merge PIO write/multiwrite code (ide-disk.c)
#   
#   Merge multwrite_intr() into write_intr().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:31:58+02:00 bzolnier@trik.(none) 
#   [ide] sg PIO for fs requests
#   
#   Convert CONFIG_IDE_TASKFILE_IO=n code to use
#   scatterlist for PIO transfers.
#   
#   Fixes longstanding 'data integrity on error' issue.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:29:37+02:00 bzolnier@trik.(none) +5 -21
#   [ide] sg PIO for fs requests
#   
#   Convert CONFIG_IDE_TASKFILE_IO=n code to use
#   scatterlist for PIO transfers.
#   
#   Fixes longstanding 'data integrity on error' issue.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:29:37+02:00 bzolnier@trik.(none) +10 -8
#   [ide] sg PIO for fs requests
#   
#   Convert CONFIG_IDE_TASKFILE_IO=n code to use
#   scatterlist for PIO transfers.
#   
#   Fixes longstanding 'data integrity on error' issue.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:29:37+02:00 bzolnier@trik.(none) +60 -164
#   [ide] sg PIO for fs requests
#   
#   Convert CONFIG_IDE_TASKFILE_IO=n code to use
#   scatterlist for PIO transfers.
#   
#   Fixes longstanding 'data integrity on error' issue.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# Documentation/block/biodoc.txt
#   2004/09/16 22:29:37+02:00 bzolnier@trik.(none) +1 -2
#   [ide] sg PIO for fs requests
#   
#   Convert CONFIG_IDE_TASKFILE_IO=n code to use
#   scatterlist for PIO transfers.
#   
#   Fixes longstanding 'data integrity on error' issue.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:29:19+02:00 bzolnier@trik.(none) 
#   [ide] sg PIO for taskfile requests
#   
#   Use scatterlist for taskfile based PIO transfers
#   instead of directly walking rq->bio/cbio list.
#   
#   This code can be also used for fs requests
#   but only if CONFIG_IDE_TASKFILE_IO is defined.
#   
#   ide-taskfile.c:ide_pio_sector() is based on
#   libata-core.c:ata_pio_sector() so kudos to Jeff!
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:29:30+02:00 bzolnier@trik.(none) +7 -29
#   [ide] sg PIO for taskfile requests
#   
#   Use scatterlist for taskfile based PIO transfers
#   instead of directly walking rq->bio/cbio list.
#   
#   This code can be also used for fs requests
#   but only if CONFIG_IDE_TASKFILE_IO is defined.
#   
#   ide-taskfile.c:ide_pio_sector() is based on
#   libata-core.c:ata_pio_sector() so kudos to Jeff!
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-taskfile.c
#   2004/09/16 22:29:30+02:00 bzolnier@trik.(none) +64 -80
#   [ide] sg PIO for taskfile requests
#   
#   Use scatterlist for taskfile based PIO transfers
#   instead of directly walking rq->bio/cbio list.
#   
#   This code can be also used for fs requests
#   but only if CONFIG_IDE_TASKFILE_IO is defined.
#   
#   ide-taskfile.c:ide_pio_sector() is based on
#   libata-core.c:ata_pio_sector() so kudos to Jeff!
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-io.c
#   2004/09/16 22:29:30+02:00 bzolnier@trik.(none) +28 -0
#   [ide] sg PIO for taskfile requests
#   
#   Use scatterlist for taskfile based PIO transfers
#   instead of directly walking rq->bio/cbio list.
#   
#   This code can be also used for fs requests
#   but only if CONFIG_IDE_TASKFILE_IO is defined.
#   
#   ide-taskfile.c:ide_pio_sector() is based on
#   libata-core.c:ata_pio_sector() so kudos to Jeff!
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-disk.c
#   2004/09/16 22:29:30+02:00 bzolnier@trik.(none) +3 -4
#   [ide] sg PIO for taskfile requests
#   
#   Use scatterlist for taskfile based PIO transfers
#   instead of directly walking rq->bio/cbio list.
#   
#   This code can be also used for fs requests
#   but only if CONFIG_IDE_TASKFILE_IO is defined.
#   
#   ide-taskfile.c:ide_pio_sector() is based on
#   libata-core.c:ata_pio_sector() so kudos to Jeff!
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:25:21+02:00 bzolnier@trik.(none) 
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/ide.h
#   2004/09/16 22:09:48+02:00 bzolnier@trik.(none) +1 -0
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/pci/sgiioc4.c
#   2004/09/16 22:29:04+02:00 bzolnier@trik.(none) +1 -8
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide.c
#   2004/09/16 22:04:26+02:00 bzolnier@trik.(none) +1 -0
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-probe.c
#   2004/09/16 22:25:48+02:00 bzolnier@trik.(none) +10 -0
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-dma.c
#   2004/09/16 22:04:26+02:00 bzolnier@trik.(none) +2 -9
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/arm/icside.c
#   2004/09/16 22:15:38+02:00 bzolnier@trik.(none) +1 -26
#   [ide] always allocate hwif->sg_table
#   
#   Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# ChangeSet
#   2004/09/17 14:15:21+02:00 bzolnier@trik.(none) 
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ppc/pmac.c
#   2004/09/10 23:15:28+02:00 bzolnier@trik.(none) +3 -8
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/ide-dma.c
#   2004/09/10 23:15:03+02:00 bzolnier@trik.(none) +3 -8
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# drivers/ide/arm/icside.c
#   2004/09/10 23:14:45+02:00 bzolnier@trik.(none) +2 -4
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# arch/cris/arch-v10/drivers/ide.c
#   2004/09/10 23:14:20+02:00 bzolnier@trik.(none) +2 -6
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/scatterlist.h
#   2004/09/10 23:20:55+02:00 bzolnier@trik.(none) +14 -0
#   [ide] add sg_init_one() helper and teach ide about it
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
# 
# include/linux/scatterlist.h
#   2004/09/10 23:20:55+02:00 bzolnier@trik.(none) +0 -0
#   BitKeeper file /home/bzolnier/bk/ide-dev-2.6/include/linux/scatterlist.h
# 
diff -Nru a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
--- a/Documentation/block/biodoc.txt	2004-09-23 21:11:16 -07:00
+++ b/Documentation/block/biodoc.txt	2004-09-23 21:11:16 -07:00
@@ -1172,8 +1172,7 @@
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
 (Sec 1.1, (ii) ) it needs to use __bio_kmap_atomic and bio_kmap_irq to
-temporarily map a bio into the virtual address space. See how IDE handles
-this with ide_map_buffer.
+temporarily map a bio into the virtual address space.
 
 
 8. Prior/Related/Impacted patches
diff -Nru a/arch/cris/arch-v10/drivers/ide.c b/arch/cris/arch-v10/drivers/ide.c
--- a/arch/cris/arch-v10/drivers/ide.c	2004-09-23 21:11:16 -07:00
+++ b/arch/cris/arch-v10/drivers/ide.c	2004-09-23 21:11:16 -07:00
@@ -30,6 +30,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/arch/svinto.h>
@@ -207,10 +208,8 @@
 #define ATA_PIO0_HOLD    4
 
 static int e100_dma_check (ide_drive_t *drive);
-static int e100_dma_begin (ide_drive_t *drive);
+static void e100_dma_start(ide_drive_t *drive);
 static int e100_dma_end (ide_drive_t *drive);
-static int e100_dma_read (ide_drive_t *drive);
-static int e100_dma_write (ide_drive_t *drive);
 static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int);
 static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int);
 static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
@@ -281,6 +280,40 @@
 	}
 }
 
+static int e100_dma_setup(ide_drive_t *drive)
+{
+	struct request *rq = drive->hwif->hwgroup->rq;
+
+	if (rq_data_dir(rq)) {
+		e100_read_command = 0;
+
+		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_TX_DMA_NBR);
+	} else {
+		e100_read_command = 1;
+
+		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_RX_DMA_NBR);
+	}
+
+	/* set up the Etrax DMA descriptors */
+	if (e100_ide_build_dmatable(drive)) {
+		ide_map_sg(drive, rq);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void e100_dma_exec_cmd(ide_drive_t *drive, u8 command)
+{
+	/* set the irq handler which will finish the request when DMA is done */
+	ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
+
+	/* issue cmd to drive */
+	etrax100_ide_outb(command, IDE_COMMAND_REG);
+}
+
 void __init
 init_e100_ide (void)
 {
@@ -302,9 +335,9 @@
                 hwif->atapi_output_bytes = &e100_atapi_output_bytes;
                 hwif->ide_dma_check = &e100_dma_check;
                 hwif->ide_dma_end = &e100_dma_end;
-		hwif->ide_dma_write = &e100_dma_write;
-		hwif->ide_dma_read = &e100_dma_read;
-		hwif->ide_dma_begin = &e100_dma_begin;
+		hwif->dma_setup = &e100_dma_setup;
+		hwif->dma_exec_cmd = &e100_dma_exec_cmd;
+		hwif->dma_start = &e100_dma_start;
 		hwif->OUTB = &etrax100_ide_outb;
 		hwif->OUTW = &etrax100_ide_outw;
 		hwif->OUTBSYNC = &etrax100_ide_outbsync;
@@ -623,20 +656,9 @@
 
 	ata_tot_size = 0;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
-		u8 *virt_addr = rq->buffer;
-		int sector_count = rq->nr_sectors;
-		memset(&sg[0], 0, sizeof(*sg));
-		sg[0].page = virt_to_page(virt_addr);
-		sg[0].offset = offset_in_page(virt_addr);
-		sg[0].length =  sector_count  * SECTOR_SIZE;
-		hwif->sg_nents = i = 1;
-	}
-	else
-	{
-		hwif->sg_nents = i = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
-	}
+	ide_map_sg(drive, rq);
 
+	i = hwif->sg_nents;
 
 	while(i) {
 		/*
@@ -773,10 +795,6 @@
  * sector address using CHS or LBA.  All that remains is to prepare for DMA
  * and then issue the actual read/write DMA/PIO command to the drive.
  *
- * For ATAPI devices, we just prepare for DMA and return. The caller should
- * then issue the packet command to the drive and call us again with
- * ide_dma_begin afterwards.
- *
  * Returns 0 if all went well.
  * Returns 1 if DMA read/write could not be started, in which case
  * the caller should revert to PIO for the current request.
@@ -793,35 +811,9 @@
 	return 0;
 }
 
-static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
+static void e100_dma_start(ide_drive_t *drive)
 {
-	if(reading) {
-
-		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_RX_DMA_NBR);
-
-		/* set up the Etrax DMA descriptors */
-
-		if(e100_ide_build_dmatable (drive))
-			return 1;
-
-		if(!atapi) {
-			/* set the irq handler which will finish the request when DMA is done */
-
-			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-
-			/* issue cmd to drive */
-                        if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
-			    (drive->addressing == 1)) {
-				ide_task_t *args = HWGROUP(drive)->rq->special;
-				etrax100_ide_outb(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
-			} else if (drive->addressing) {
-				etrax100_ide_outb(WIN_READDMA_EXT, IDE_COMMAND_REG);
-			} else {
-				etrax100_ide_outb(WIN_READDMA, IDE_COMMAND_REG);
-			}
-		}
-
+	if (e100_read_command) {
 		/* begin DMA */
 
 		/* need to do this before RX DMA due to a chip bug
@@ -854,32 +846,6 @@
 
 	} else {
 		/* writing */
-
-		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_TX_DMA_NBR);
-
-		/* set up the Etrax DMA descriptors */
-
-		if(e100_ide_build_dmatable (drive))
-			return 1;
-
-		if(!atapi) {
-			/* set the irq handler which will finish the request when DMA is done */
-
-			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-
-			/* issue cmd to drive */
-			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
-			    (drive->addressing == 1)) {
-				ide_task_t *args = HWGROUP(drive)->rq->special;
-				etrax100_ide_outb(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
-			} else if (drive->addressing) {
-				etrax100_ide_outb(WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
-			} else {
-				etrax100_ide_outb(WIN_WRITEDMA, IDE_COMMAND_REG);
-			}
-		}
-
 		/* begin DMA */
 
 		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
@@ -902,44 +868,4 @@
 
 		D(printk("dma write of %d bytes.\n", ata_tot_size));
 	}
-	return 0;
-}
-
-static int e100_dma_write(ide_drive_t *drive)
-{
-	e100_read_command = 0;
-	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
-	 * then they call ide_dma_begin after they have issued the appropriate drive command
-	 * themselves to actually start the chipset DMA. so we just return here if we're
-	 * not a diskdrive.
-	 */
-	if (drive->media != ide_disk)
-                return 0;
-	return e100_start_dma(drive, 0, 0);
-}
-
-static int e100_dma_read(ide_drive_t *drive)
-{
-	e100_read_command = 1;
-	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
-	 * then they call ide_dma_begin after they have issued the appropriate drive command
-	 * themselves to actually start the chipset DMA. so we just return here if we're
-	 * not a diskdrive.
-	 */
-	if (drive->media != ide_disk)
-                return 0;
-	return e100_start_dma(drive, 0, 1);
-}
-
-static int e100_dma_begin(ide_drive_t *drive)
-{
-	/* begin DMA, used by ATAPI devices which want to issue the
-	 * appropriate IDE command themselves.
-	 *
-	 * they have already called ide_dma_read/write to set the
-	 * static reading flag, now they call ide_dma_begin to do
-	 * the real stuff. we tell our code below not to issue
-	 * any IDE commands itself and jump into it.
-	 */
-	 return e100_start_dma(drive, 1, e100_read_command);
 }
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
--- a/drivers/ide/arm/icside.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/arm/icside.c	2004-09-23 21:11:16 -07:00
@@ -16,6 +16,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/scatterlist.h>
 
 #include <asm/dma.h>
 #include <asm/ecard.h>
@@ -205,15 +206,12 @@
  * here, but we rely on the main IDE driver spotting that both
  * interfaces use the same IRQ, which should guarantee this.
  */
-#define NR_ENTRIES 256
-#define TABLE_SIZE (NR_ENTRIES * 8)
 
 static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct icside_state *state = hwif->hwif_data;
 	struct scatterlist *sg = hwif->sg_table;
-	int nents;
 
 	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
@@ -223,13 +221,9 @@
 		else
 			hwif->sg_dma_direction = DMA_FROM_DEVICE;
 
-		memset(sg, 0, sizeof(*sg));
-		sg->page   = virt_to_page(rq->buffer);
-		sg->offset = offset_in_page(rq->buffer);
-		sg->length = rq->nr_sectors * SECTOR_SIZE;
-		nents = 1;
+		ide_map_sg(drive, rq);
 	} else {
-		nents = blk_rq_map_sg(drive->queue, rq, sg);
+		ide_map_sg(drive, rq);
 
 		if (rq_data_dir(rq) == READ)
 			hwif->sg_dma_direction = DMA_FROM_DEVICE;
@@ -237,12 +231,10 @@
 			hwif->sg_dma_direction = DMA_TO_DEVICE;
 	}
 
-	nents = dma_map_sg(state->dev, sg, nents, hwif->sg_dma_direction);
-
-	hwif->sg_nents = nents;
+	hwif->sg_nents = dma_map_sg(state->dev, sg, hwif->sg_nents,
+				    hwif->sg_dma_direction);
 }
 
-
 /*
  * Configure the IOMD to give the appropriate timings for the transfer
  * mode being requested.  We take the advice of the ATA standards, and
@@ -402,14 +394,13 @@
 	return get_dma_residue(hwif->hw.dma) != 0;
 }
 
-static int icside_dma_begin(ide_drive_t *drive)
+static void icside_dma_start(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 
 	/* We can not enable DMA on both channels simultaneously. */
 	BUG_ON(dma_channel_active(hwif->hw.dma));
 	enable_dma(hwif->hw.dma);
-	return 0;
 }
 
 /*
@@ -441,11 +432,16 @@
 	return DRIVER(drive)->error(drive, __FUNCTION__, stat);
 }
 
-static int
-icside_dma_common(ide_drive_t *drive, struct request *rq,
-		  unsigned int dma_mode)
+static int icside_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
+	struct request *rq = hwif->hwgroup->rq;
+	unsigned int dma_mode;
+
+	if (rq_data_dir(rq))
+		dma_mode = DMA_MODE_WRITE;
+	else
+		dma_mode = DMA_MODE_READ;
 
 	/*
 	 * We can not enable DMA on both channels.
@@ -481,79 +477,10 @@
 	return 0;
 }
 
-static int icside_dma_read(ide_drive_t *drive)
+static void icside_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
-	struct request *rq = HWGROUP(drive)->rq;
-	task_ioreg_t cmd;
-
-	if (icside_dma_common(drive, rq, DMA_MODE_READ))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	BUG_ON(HWGROUP(drive)->handler != NULL);
-
-	/*
-	 * FIX ME to use only ACB ide_task_t args Struct
-	 */
-#if 0
-	{
-		ide_task_t *args = rq->special;
-		cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#else
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-	} else if (drive->addressing == 1) {
-		cmd = WIN_READDMA_EXT;
-	} else {
-		cmd = WIN_READDMA;
-	}
-#endif
 	/* issue cmd to drive */
 	ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
-
-	return icside_dma_begin(drive);
-}
-
-static int icside_dma_write(ide_drive_t *drive)
-{
-	struct request *rq = HWGROUP(drive)->rq;
-	task_ioreg_t cmd;
-
-	if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	BUG_ON(HWGROUP(drive)->handler != NULL);
-
-	/*
-	 * FIX ME to use only ACB ide_task_t args Struct
-	 */
-#if 0
-	{
-		ide_task_t *args = rq->special;
-		cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#else
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-	} else if (drive->addressing == 1) {
-		cmd = WIN_WRITEDMA_EXT;
-	} else {
-		cmd = WIN_WRITEDMA;
-	}
-#endif
-
-	/* issue cmd to drive */
-	ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
-
-	return icside_dma_begin(drive);
 }
 
 static int icside_dma_test_irq(ide_drive_t *drive)
@@ -594,7 +521,7 @@
 	return 1;
 }
 
-static int icside_dma_init(ide_hwif_t *hwif)
+static void icside_dma_init(ide_hwif_t *hwif)
 {
 	int autodma = 0;
 
@@ -604,11 +531,6 @@
 
 	printk("    %s: SG-DMA", hwif->name);
 
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES,
-				 GFP_KERNEL);
-	if (!hwif->sg_table)
-		goto failed;
-
 	hwif->atapi_dma		= 1;
 	hwif->mwdma_mask	= 7; /* MW0..2 */
 	hwif->swdma_mask	= 7; /* SW0..2 */
@@ -623,9 +545,9 @@
 	hwif->ide_dma_off_quietly = icside_dma_off_quietly;
 	hwif->ide_dma_host_on	= icside_dma_host_on;
 	hwif->ide_dma_on	= icside_dma_on;
-	hwif->ide_dma_read	= icside_dma_read;
-	hwif->ide_dma_write	= icside_dma_write;
-	hwif->ide_dma_begin	= icside_dma_begin;
+	hwif->dma_setup		= icside_dma_setup;
+	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
+	hwif->dma_start		= icside_dma_start;
 	hwif->ide_dma_end	= icside_dma_end;
 	hwif->ide_dma_test_irq	= icside_dma_test_irq;
 	hwif->ide_dma_verbose	= icside_dma_verbose;
@@ -636,24 +558,9 @@
 	hwif->drives[1].autodma = hwif->autodma;
 
 	printk(" capable%s\n", hwif->autodma ? ", auto-enable" : "");
-
-	return 1;
-
-failed:
-	printk(" disabled, unable to allocate DMA table\n");
-	return 0;
-}
-
-static void icside_dma_exit(ide_hwif_t *hwif)
-{
-	if (hwif->sg_table) {
-		kfree(hwif->sg_table);
-		hwif->sg_table = NULL;
-	}
 }
 #else
 #define icside_dma_init(hwif)	(0)
-#define icside_dma_exit(hwif)	do { } while (0)
 #endif
 
 static ide_hwif_t *icside_find_hwif(unsigned long dataport)
@@ -878,9 +785,6 @@
 
 	case ICS_TYPE_V6:
 		/* FIXME: tell IDE to stop using the interface */
-		icside_dma_exit(state->hwif[1]);
-		icside_dma_exit(state->hwif[0]);
-
 		if (ec->dma != NO_DMA)
 			free_dma(ec->dma);
 
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-cd.c	2004-09-23 21:11:16 -07:00
@@ -865,20 +865,14 @@
 {
 	ide_startstop_t startstop;
 	struct cdrom_info *info = drive->driver_data;
+	ide_hwif_t *hwif = drive->hwif;
 
 	/* Wait for the controller to be idle. */
 	if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
 		return startstop;
 
-	if (info->dma) {
-		if (info->cmd == READ) {
-			info->dma = !HWIF(drive)->ide_dma_read(drive);
-		} else if (info->cmd == WRITE) {
-			info->dma = !HWIF(drive)->ide_dma_write(drive);
-		} else {
-			printk("ide-cd: DMA set, but not allowed\n");
-		}
-	}
+	if (info->dma)
+		info->dma = !hwif->dma_setup(drive);
 
 	/* Set up the controller registers. */
 	/* FIXME: for Virtual DMA we must check harder */
@@ -916,6 +910,7 @@
 					  struct request *rq,
 					  ide_handler_t *handler)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	int cmd_len;
 	struct cdrom_info *info = drive->driver_data;
 	ide_startstop_t startstop;
@@ -947,7 +942,7 @@
 
 	/* Start the DMA if need be */
 	if (info->dma)
-		(void) HWIF(drive)->ide_dma_begin(drive);
+		hwif->dma_start(drive);
 
 	return ide_started;
 }
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-disk.c	2004-09-23 21:11:16 -07:00
@@ -123,216 +123,6 @@
 #ifndef CONFIG_IDE_TASKFILE_IO
 
 /*
- * read_intr() is the handler for disk read/multread interrupts
- */
-static ide_startstop_t read_intr (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	u32 i = 0, nsect	= 0, msect = drive->mult_count;
-	struct request *rq;
-	unsigned long flags;
-	u8 stat;
-	char *to;
-
-	/* new way for dealing with premature shared PCI interrupts */
-	if (!OK_STAT(stat=hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
-		if (stat & (ERR_STAT|DRQ_STAT)) {
-			return DRIVER(drive)->error(drive, "read_intr", stat);
-		}
-		/* no data yet, so wait for another interrupt */
-		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
-		return ide_started;
-	}
-	
-read_next:
-	rq = HWGROUP(drive)->rq;
-	if (msect) {
-		if ((nsect = rq->current_nr_sectors) > msect)
-			nsect = msect;
-		msect -= nsect;
-	} else
-		nsect = 1;
-	to = ide_map_buffer(rq, &flags);
-	taskfile_input_data(drive, to, nsect * SECTOR_WORDS);
-#ifdef DEBUG
-	printk("%s:  read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
-		drive->name, rq->sector, rq->sector+nsect-1,
-		(unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect);
-#endif
-	ide_unmap_buffer(rq, to, &flags);
-	rq->sector += nsect;
-	rq->errors = 0;
-	i = (rq->nr_sectors -= nsect);
-	if (((long)(rq->current_nr_sectors -= nsect)) <= 0)
-		ide_end_request(drive, 1, rq->hard_cur_sectors);
-	/*
-	 * Another BH Page walker and DATA INTEGRITY Questioned on ERROR.
-	 * If passed back up on multimode read, BAD DATA could be ACKED
-	 * to FILE SYSTEMS above ...
-	 */
-	if (i > 0) {
-		if (msect)
-			goto read_next;
-		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
-                return ide_started;
-	}
-        return ide_stopped;
-}
-
-/*
- * write_intr() is the handler for disk write interrupts
- */
-static ide_startstop_t write_intr (ide_drive_t *drive)
-{
-	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= hwgroup->rq;
-	u32 i = 0;
-	u8 stat;
-
-	if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),
-			DRIVE_READY, drive->bad_wstat)) {
-		printk("%s: write_intr error1: nr_sectors=%ld, stat=0x%02x\n",
-			drive->name, rq->nr_sectors, stat);
-        } else {
-#ifdef DEBUG
-		printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
-			drive->name, rq->sector, (unsigned long) rq->buffer,
-			rq->nr_sectors-1);
-#endif
-		if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) {
-			rq->sector++;
-			rq->errors = 0;
-			i = --rq->nr_sectors;
-			--rq->current_nr_sectors;
-			if (((long)rq->current_nr_sectors) <= 0)
-				ide_end_request(drive, 1, rq->hard_cur_sectors);
-			if (i > 0) {
-				unsigned long flags;
-				char *to = ide_map_buffer(rq, &flags);
-				taskfile_output_data(drive, to, SECTOR_WORDS);
-				ide_unmap_buffer(rq, to, &flags);
-				ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
-                                return ide_started;
-			}
-                        return ide_stopped;
-		}
-		/* the original code did this here (?) */
-		return ide_stopped;
-	}
-	return DRIVER(drive)->error(drive, "write_intr", stat);
-}
-
-/*
- * ide_multwrite() transfers a block of up to mcount sectors of data
- * to a drive as part of a disk multiple-sector write operation.
- *
- * Note that we may be called from two contexts - __ide_do_rw_disk() context
- * and IRQ context. The IRQ can happen any time after we've output the
- * full "mcount" number of sectors, so we must make sure we update the
- * state _before_ we output the final part of the data!
- *
- * The update and return to BH is a BLOCK Layer Fakey to get more data
- * to satisfy the hardware atomic segment.  If the hardware atomic segment
- * is shorter or smaller than the BH segment then we should be OKAY.
- * This is only valid if we can rewind the rq->current_nr_sectors counter.
- */
-static void ide_multwrite(ide_drive_t *drive, unsigned int mcount)
-{
- 	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
- 	struct request *rq	= &hwgroup->wrq;
- 
-  	do {
-  		char *buffer;
-  		int nsect = rq->current_nr_sectors;
-		unsigned long flags;
- 
-		if (nsect > mcount)
-			nsect = mcount;
-		mcount -= nsect;
-		buffer = ide_map_buffer(rq, &flags);
-
-		rq->sector += nsect;
-		rq->nr_sectors -= nsect;
-		rq->current_nr_sectors -= nsect;
-
-		/* Do we move to the next bh after this? */
-		if (!rq->current_nr_sectors) {
-			struct bio *bio = rq->bio;
-
-			/*
-			 * only move to next bio, when we have processed
-			 * all bvecs in this one.
-			 */
-			if (++bio->bi_idx >= bio->bi_vcnt) {
-				bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
-				bio = bio->bi_next;
-			}
-
-			/* end early early we ran out of requests */
-			if (!bio) {
-				mcount = 0;
-			} else {
-				rq->bio = bio;
-				rq->nr_cbio_segments = bio_segments(bio);
-				rq->current_nr_sectors = bio_cur_sectors(bio);
-				rq->hard_cur_sectors = rq->current_nr_sectors;
-			}
-		}
-
-		/*
-		 * Ok, we're all setup for the interrupt
-		 * re-entering us on the last transfer.
-		 */
-		taskfile_output_data(drive, buffer, nsect<<7);
-		ide_unmap_buffer(rq, buffer, &flags);
-	} while (mcount);
-}
-
-/*
- * multwrite_intr() is the handler for disk multwrite interrupts
- */
-static ide_startstop_t multwrite_intr (ide_drive_t *drive)
-{
-	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= &hwgroup->wrq;
-	struct bio *bio		= rq->bio;
-	u8 stat;
-
-	stat = hwif->INB(IDE_STATUS_REG);
-	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) {
-		if (stat & DRQ_STAT) {
-			/*
-			 *	The drive wants data. Remember rq is the copy
-			 *	of the request
-			 */
-			if (rq->nr_sectors) {
-				ide_multwrite(drive, drive->mult_count);
-				ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
-				return ide_started;
-			}
-		} else {
-			/*
-			 *	If the copy has all the blocks completed then
-			 *	we can end the original request.
-			 */
-			if (!rq->nr_sectors) {	/* all done? */
-				bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
-				rq = hwgroup->rq;
-				ide_end_request(drive, 1, rq->nr_sectors);
-				return ide_stopped;
-			}
-		}
-		bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
-		/* the original code did this here (?) */
-		return ide_stopped;
-	}
-	bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
-	return DRIVER(drive)->error(drive, "multwrite_intr", stat);
-}
-
-/*
  * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
@@ -352,6 +142,11 @@
 			dma = 0;
 	}
 
+	if (!dma) {
+		ide_init_sg_cmd(drive, rq);
+		ide_map_sg(drive, rq);
+	}
+
 	if (IDE_CONTROL_REG)
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
 
@@ -419,48 +214,49 @@
 		hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
 	}
 
-	if (rq_data_dir(rq) == READ) {
-		if (dma && !hwif->ide_dma_read(drive))
-			return ide_started;
-
-		command = ((drive->mult_count) ?
-			   ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) :
-			   ((lba48) ? WIN_READ_EXT : WIN_READ));
-		ide_execute_command(drive, command, &read_intr, WAIT_CMD, NULL);
-		return ide_started;
-	} else {
-		ide_startstop_t startstop;
-
-		if (dma && !hwif->ide_dma_write(drive))
+	if (dma) {
+		if (!hwif->dma_setup(drive)) {
+			if (rq_data_dir(rq)) {
+				command = lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+				if (drive->vdma)
+					command = lba48 ? WIN_WRITE_EXT: WIN_WRITE;
+			} else {
+				command = lba48 ? WIN_READDMA_EXT : WIN_READDMA;
+				if (drive->vdma)
+					command = lba48 ? WIN_READ_EXT: WIN_READ;
+			}
+			hwif->dma_exec_cmd(drive, command);
+			hwif->dma_start(drive);
 			return ide_started;
+		}
+		/* fallback to PIO */
+		ide_init_sg_cmd(drive, rq);
+	}
 
-		command = ((drive->mult_count) ?
-			   ((lba48) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE) :
-			   ((lba48) ? WIN_WRITE_EXT : WIN_WRITE));
-		hwif->OUTB(command, IDE_COMMAND_REG);
+	if (rq_data_dir(rq) == READ) {
 
-		if (ide_wait_stat(&startstop, drive, DATA_READY,
-				drive->bad_wstat, WAIT_DRQ)) {
-			printk(KERN_ERR "%s: no DRQ after issuing %s\n",
-				drive->name,
-				drive->mult_count ? "MULTWRITE" : "WRITE");
-			return startstop;
-		}
-		if (!drive->unmask)
-			local_irq_disable();
 		if (drive->mult_count) {
-			ide_hwgroup_t *hwgroup = HWGROUP(drive);
+			hwif->data_phase = TASKFILE_MULTI_IN;
+			command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD;
+		} else {
+			hwif->data_phase = TASKFILE_IN;
+			command = lba48 ? WIN_READ_EXT : WIN_READ;
+		}
 
-			hwgroup->wrq = *rq; /* scratchpad */
-			ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
-			ide_multwrite(drive, drive->mult_count);
+		ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, NULL);
+		return ide_started;
+	} else {
+		if (drive->mult_count) {
+			hwif->data_phase = TASKFILE_MULTI_OUT;
+			command = lba48 ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
 		} else {
-			unsigned long flags;
-			char *to = ide_map_buffer(rq, &flags);
-			ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
-			taskfile_output_data(drive, to, SECTOR_WORDS);
-			ide_unmap_buffer(rq, to, &flags);
+			hwif->data_phase = TASKFILE_OUT;
+			command = lba48 ? WIN_WRITE_EXT : WIN_WRITE;
 		}
+
+		hwif->OUTB(command, IDE_COMMAND_REG);
+
+		pre_task_out_intr(drive, rq);
 		return ide_started;
 	}
 }
@@ -504,6 +300,11 @@
 			dma = 0;
 	}
 
+	if (!dma) {
+		ide_init_sg_cmd(drive, rq);
+		ide_map_sg(drive, rq);
+	}
+
 	if (rq_data_dir(rq) == READ) {
 		task->command_type = IDE_DRIVE_TASK_IN;
 		if (dma)
@@ -767,10 +568,6 @@
 		ide_end_drive_cmd(drive, stat, err);
 		return ide_stopped;
 	}
-#ifdef CONFIG_IDE_TASKFILE_IO
-	/* make rq completion pointers new submission pointers */
-	blk_rq_prep_restart(rq);
-#endif
 
 	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
 		/* other bits are useless when BUSY */
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-dma.c	2004-09-23 21:11:16 -07:00
@@ -85,6 +85,7 @@
 #include <linux/init.h>
 #include <linux/ide.h>
 #include <linux/delay.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -206,73 +207,23 @@
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct scatterlist *sg = hwif->sg_table;
-	int nents;
 
-	nents = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
-		
+	if ((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256)
+		BUG();
+
+	ide_map_sg(drive, rq);
+
 	if (rq_data_dir(rq) == READ)
 		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
 	else
 		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
 
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+	return pci_map_sg(hwif->pci_dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
 }
 
 EXPORT_SYMBOL_GPL(ide_build_sglist);
 
 /**
- *	ide_raw_build_sglist	-	map IDE scatter gather for DMA
- *	@drive: the drive to build the DMA table for
- *	@rq: the request holding the sg list
- *
- *	Perform the PCI mapping magic necessary to access the source or
- *	target buffers of a taskfile request via PCI DMA. The lower layers 
- *	of the  kernel provide the necessary cache management so that we can
- *	operate in a portable fashion
- */
-
-int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	struct scatterlist *sg = hwif->sg_table;
-	int nents = 0;
-	ide_task_t *args = rq->special;
-	u8 *virt_addr = rq->buffer;
-	int sector_count = rq->nr_sectors;
-
-	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-	else
-		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
-#if 1
-	if (sector_count > 256)
-		BUG();
-
-	if (sector_count > 128) {
-#else
-	while (sector_count > 128) {
-#endif
-		memset(&sg[nents], 0, sizeof(*sg));
-		sg[nents].page = virt_to_page(virt_addr);
-		sg[nents].offset = offset_in_page(virt_addr);
-		sg[nents].length = 128  * SECTOR_SIZE;
-		nents++;
-		virt_addr = virt_addr + (128 * SECTOR_SIZE);
-		sector_count -= 128;
-	}
-	memset(&sg[nents], 0, sizeof(*sg));
-	sg[nents].page = virt_to_page(virt_addr);
-	sg[nents].offset = offset_in_page(virt_addr);
-	sg[nents].length =  sector_count  * SECTOR_SIZE;
-	nents++;
-
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-EXPORT_SYMBOL_GPL(ide_raw_build_sglist);
-
-/**
  *	ide_build_dmatable	-	build IDE DMA table
  *
  *	ide_build_dmatable() prepares a dma request. We map the command
@@ -293,10 +244,7 @@
 	int i;
 	struct scatterlist *sg;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
-	else
-		hwif->sg_nents = i = ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
 
 	if (!i)
 		return 0;
@@ -590,10 +538,8 @@
 EXPORT_SYMBOL(__ide_dma_check);
 
 /**
- *	ide_start_dma	-	begin a DMA phase
- *	@hwif: interface
+ *	ide_dma_setup	-	begin a DMA phase
  *	@drive: target device
- *	@reading: set if reading, clear if writing
  *
  *	Build an IDE DMA PRD (IDE speak for scatter gather table)
  *	and then set up the DMA transfer registers for a device
@@ -603,15 +549,24 @@
  *	Returns 0 on success. If a PIO fallback is required then 1
  *	is returned. 
  */
- 
-int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading)
+
+int ide_dma_setup(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq = HWGROUP(drive)->rq;
+	unsigned int reading;
 	u8 dma_stat;
 
+	if (rq_data_dir(rq))
+		reading = 0;
+	else
+		reading = 1 << 3;
+
 	/* fall back to pio! */
-	if (!ide_build_dmatable(drive, rq))
+	if (!ide_build_dmatable(drive, rq)) {
+		ide_map_sg(drive, rq);
 		return 1;
+	}
 
 	/* PRD table */
 	hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
@@ -628,73 +583,15 @@
 	return 0;
 }
 
-EXPORT_SYMBOL(ide_start_dma);
+EXPORT_SYMBOL_GPL(ide_dma_setup);
 
-int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
+static void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= HWGROUP(drive)->rq;
-	unsigned int reading	= 1 << 3;
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
-	task_ioreg_t command	= WIN_NOP;
-
-	/* try pio */
-	if (ide_start_dma(hwif, drive, reading))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-	
-	if (drive->vdma)
-		command = (lba48) ? WIN_READ_EXT: WIN_READ;
-		
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-
 	/* issue cmd to drive */
 	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
-	return hwif->ide_dma_begin(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_read);
-
-int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= HWGROUP(drive)->rq;
-	unsigned int reading	= 0;
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
-	task_ioreg_t command	= WIN_NOP;
-
-	/* try PIO instead of DMA */
-	if (ide_start_dma(hwif, drive, reading))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-	if (drive->vdma)
-		command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
-		
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
-
-	return hwif->ide_dma_begin(drive);
-}
-
-EXPORT_SYMBOL(__ide_dma_write);
-
-int __ide_dma_begin (ide_drive_t *drive)
+void ide_dma_start(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 dma_cmd		= hwif->INB(hwif->dma_command);
@@ -708,10 +605,9 @@
 	hwif->OUTB(dma_cmd|1, hwif->dma_command);
 	hwif->dma = 1;
 	wmb();
-	return 0;
 }
 
-EXPORT_SYMBOL(__ide_dma_begin);
+EXPORT_SYMBOL_GPL(ide_dma_start);
 
 /* returns 1 on error, 0 otherwise */
 int __ide_dma_end (ide_drive_t *drive)
@@ -869,10 +765,6 @@
 				    hwif->dmatable_dma);
 		hwif->dmatable_cpu = NULL;
 	}
-	if (hwif->sg_table) {
-		kfree(hwif->sg_table);
-		hwif->sg_table = NULL;
-	}
 	return 1;
 }
 
@@ -905,15 +797,12 @@
 	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
 						  PRD_ENTRIES * PRD_BYTES,
 						  &hwif->dmatable_dma);
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
-				GFP_KERNEL);
 
-	if ((hwif->dmatable_cpu) && (hwif->sg_table))
+	if (hwif->dmatable_cpu)
 		return 0;
 
-	printk(KERN_ERR "%s: -- Error, unable to allocate%s%s table(s).\n",
+	printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
 		(hwif->dmatable_cpu == NULL) ? " CPU" : "",
-		(hwif->sg_table == NULL) ?  " SG DMA" : " DMA",
 		hwif->cds->name);
 
 	ide_release_dma_engine(hwif);
@@ -1009,12 +898,12 @@
 		hwif->ide_dma_host_on = &__ide_dma_host_on;
 	if (!hwif->ide_dma_check)
 		hwif->ide_dma_check = &__ide_dma_check;
-	if (!hwif->ide_dma_read)
-		hwif->ide_dma_read = &__ide_dma_read;
-	if (!hwif->ide_dma_write)
-		hwif->ide_dma_write = &__ide_dma_write;
-	if (!hwif->ide_dma_begin)
-		hwif->ide_dma_begin = &__ide_dma_begin;
+	if (!hwif->dma_setup)
+		hwif->dma_setup = &ide_dma_setup;
+	if (!hwif->dma_exec_cmd)
+		hwif->dma_exec_cmd = &ide_dma_exec_cmd;
+	if (!hwif->dma_start)
+		hwif->dma_start = &ide_dma_start;
 	if (!hwif->ide_dma_end)
 		hwif->ide_dma_end = &__ide_dma_end;
 	if (!hwif->ide_dma_test_irq)
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-floppy.c	2004-09-23 21:11:16 -07:00
@@ -995,6 +995,7 @@
 static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
 {
 	idefloppy_floppy_t *floppy = drive->driver_data;
+	ide_hwif_t *hwif = drive->hwif;
 	atapi_feature_t feature;
 	atapi_bcount_t bcount;
 	ide_handler_t *pkt_xfer_routine;
@@ -1049,13 +1050,8 @@
 	}
 	feature.all = 0;
 
-	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
-		if (test_bit(PC_WRITING, &pc->flags)) {
-			feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
-		} else {
-			feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
-		}
-	}
+	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+		feature.b.dma = !hwif->dma_setup(drive);
 
 	if (IDE_CONTROL_REG)
 		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
@@ -1067,7 +1063,7 @@
 
 	if (feature.b.dma) {	/* Begin DMA, if necessary */
 		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
-		(void) (HWIF(drive)->ide_dma_begin(drive));
+		hwif->dma_start(drive);
 	}
 
 	/* Can we transfer the packet when we get the interrupt or wait? */
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-io.c	2004-09-23 21:11:16 -07:00
@@ -47,6 +47,7 @@
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/kmod.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -674,6 +675,31 @@
 
 EXPORT_SYMBOL(do_special);
 
+void ide_map_sg(ide_drive_t *drive, struct request *rq)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist *sg = hwif->sg_table;
+
+	if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
+		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
+	} else {
+		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
+		hwif->sg_nents = 1;
+	}
+}
+
+EXPORT_SYMBOL_GPL(ide_map_sg);
+
+void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+{
+	ide_hwif_t *hwif = drive->hwif;
+
+	hwif->nsect = hwif->nleft = rq->nr_sectors;
+	hwif->cursg = hwif->cursg_ofs = 0;
+}
+
+EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
+
 /**
  *	execute_drive_command	-	issue special drive command
  *	@drive: the drive to issue th command on
@@ -696,6 +722,17 @@
 			goto done;
 
 		hwif->data_phase = args->data_phase;
+
+		switch (hwif->data_phase) {
+		case TASKFILE_MULTI_OUT:
+		case TASKFILE_OUT:
+		case TASKFILE_MULTI_IN:
+		case TASKFILE_IN:
+			ide_init_sg_cmd(drive, rq);
+			ide_map_sg(drive, rq);
+		default:
+			break;
+		}
 
 		if (args->tf_out_flags.all != 0) 
 			return flagged_taskfile(drive, args);
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-probe.c	2004-09-23 21:11:16 -07:00
@@ -1255,6 +1255,16 @@
 	if (register_blkdev(hwif->major, hwif->name))
 		return 0;
 
+	if (!hwif->sg_max_nents)
+		hwif->sg_max_nents = PRD_ENTRIES;
+
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+				 GFP_KERNEL);
+	if (!hwif->sg_table) {
+		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
+		goto out;
+	}
+
 	if (alloc_disks(hwif) < 0)
 		goto out;
 	
diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
--- a/drivers/ide/ide-proc.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-proc.c	2004-09-23 21:11:16 -07:00
@@ -8,37 +8,6 @@
 /*
  * This is the /proc/ide/ filesystem implementation.
  *
- * The major reason this exists is to provide sufficient access
- * to driver and config data, such that user-mode programs can
- * be developed to handle chipset tuning for most PCI interfaces.
- * This should provide better utilities, and less kernel bloat.
- *
- * The entire pci config space for a PCI interface chipset can be
- * retrieved by just reading it.  e.g.    "cat /proc/ide3/config"
- *
- * To modify registers *safely*, do something like:
- *   echo "P40:88" >/proc/ide/ide3/config
- * That expression writes 0x88 to pci config register 0x40
- * on the chip which controls ide3.  Multiple tuples can be issued,
- * and the writes will be completed as an atomic set:
- *   echo "P40:88 P41:35 P42:00 P43:00" >/proc/ide/ide3/config
- *
- * All numbers must be specified using pairs of ascii hex digits.
- * It is important to note that these writes will be performed
- * after waiting for the IDE controller (both interfaces)
- * to be completely idle, to ensure no corruption of I/O in progress.
- *
- * Non-PCI registers can also be written, using "R" in place of "P"
- * in the above examples.  The size of the port transfer is determined
- * by the number of pairs of hex digits given for the data.  If a two
- * digit value is given, the write will be a byte operation; if four
- * digits are used, the write will be performed as a 16-bit operation;
- * and if eight digits are specified, a 32-bit "dword" write will be
- * performed.  Odd numbers of digits are not permitted.
- *
- * If there is an error *anywhere* in the string of registers/data
- * then *none* of the writes will be performed.
- *
  * Drive/Driver settings can be retrieved by reading the drive's
  * "settings" files.  e.g.    "cat /proc/ide0/hda/settings"
  * To write a new value "val" into a specific setting "name", use:
@@ -51,10 +20,6 @@
  * returned data as 256 16-bit words.  The "hdparm" utility will
  * be updated someday soon to use this mechanism.
  *
- * Feel free to develop and distribute fancy GUI configuration
- * utilities for your favorite PCI chipsets.  I'll be working on
- * one for the Promise 20246 someday soon.  -ml
- *
  */
 
 #include <linux/config.h>
@@ -74,227 +39,6 @@
 
 #include <asm/io.h>
 
-static int proc_ide_write_config(struct file *file, const char __user *buffer,
-				 unsigned long count, void *data)
-{
-	ide_hwif_t	*hwif = (ide_hwif_t *)data;
-	ide_hwgroup_t *mygroup = (ide_hwgroup_t *)(hwif->hwgroup);
-	ide_hwgroup_t *mategroup = NULL;
-	unsigned long timeout;
-	unsigned long flags;
-	const char *start = NULL, *msg = NULL;
-	struct entry { u32 val; u16 reg; u8 size; u8 pci; } *prog, *q, *r;
-	int want_pci = 0;
-	char *buf, *s;
-	int err;
-
-	if (hwif->mate && hwif->mate->hwgroup)
-		mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
-
-	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-		return -EACCES;
-
-	if (count >= PAGE_SIZE)
-		return -EINVAL;
-
-	s = buf = (char *)__get_free_page(GFP_USER);
-	if (!buf)
-		return -ENOMEM;
-
-	err = -ENOMEM;
-	q = prog = (struct entry *)__get_free_page(GFP_USER);
-	if (!prog)
-		goto out;
-
-	err = -EFAULT;
-	if (copy_from_user(buf, buffer, count))
-		goto out1;
-
-	buf[count] = '\0';
-
-	while (isspace(*s))
-		s++;
-
-	while (*s) {
-		char *p;
-		int digits;
-
-		start = s;
-
-		if ((char *)(q + 1) > (char *)prog + PAGE_SIZE) {
-			msg = "too many entries";
-			goto parse_error;
-		}
-
-		switch (*s++) {
-			case 'R':	q->pci = 0;
-					break;
-			case 'P':	q->pci = 1;
-					want_pci = 1;
-					break;
-			default:	msg = "expected 'R' or 'P'";
-					goto parse_error;
-		}
-
-		q->reg = simple_strtoul(s, &p, 16);
-		digits = p - s;
-		if (!digits || digits > 4 || (q->pci && q->reg > 0xff)) {
-			msg = "bad/missing register number";
-			goto parse_error;
-		}
-		if (*p++ != ':') {
-			msg = "missing ':'";
-			goto parse_error;
-		}
-		q->val = simple_strtoul(p, &s, 16);
-		digits = s - p;
-		if (digits != 2 && digits != 4 && digits != 8) {
-			msg = "bad data, 2/4/8 digits required";
-			goto parse_error;
-		}
-		q->size = digits / 2;
-
-		if (q->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
-			if (q->reg & (q->size - 1)) {
-				msg = "misaligned access";
-				goto parse_error;
-			}
-#else
-			msg = "not a PCI device";
-			goto parse_error;
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		}
-
-		q++;
-
-		if (*s && !isspace(*s++)) {
-			msg = "expected whitespace after data";
-			goto parse_error;
-		}
-		while (isspace(*s))
-			s++;
-	}
-
-	/*
-	 * What follows below is fucking insane, even for IDE people.
-	 * For now I've dealt with the obvious problems on the parsing
-	 * side, but IMNSHO we should simply remove the write access
-	 * to /proc/ide/.../config, killing that FPOS completely.
-	 */
-
-	err = -EBUSY;
-	timeout = jiffies + (3 * HZ);
-	spin_lock_irqsave(&ide_lock, flags);
-	while (mygroup->busy ||
-	       (mategroup && mategroup->busy)) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		if (time_after(jiffies, timeout)) {
-			printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
-			goto out1;
-		}
-		spin_lock_irqsave(&ide_lock, flags);
-	}
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	if (want_pci && (!hwif->pci_dev || hwif->pci_dev->vendor)) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		printk("proc_ide: PCI registers not accessible for %s\n",
-			hwif->name);
-		err = -EINVAL;
-		goto out1;
-	}
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-
-	for (r = prog; r < q; r++) {
-		unsigned int reg = r->reg, val = r->val;
-		if (r->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
-			int rc = 0;
-			struct pci_dev *dev = hwif->pci_dev;
-			switch (q->size) {
-				case 1:	msg = "byte";
-					rc = pci_write_config_byte(dev, reg, val);
-					break;
-				case 2:	msg = "word";
-					rc = pci_write_config_word(dev, reg, val);
-					break;
-				case 4:	msg = "dword";
-					rc = pci_write_config_dword(dev, reg, val);
-					break;
-			}
-			if (rc) {
-				spin_unlock_irqrestore(&ide_lock, flags);
-				printk("proc_ide_write_config: error writing %s at bus %02x dev %02x reg 0x%x value 0x%x\n",
-					msg, dev->bus->number, dev->devfn, reg, val);
-				printk("proc_ide_write_config: error %d\n", rc);
-				err = -EIO;
-				goto out1;
-			}
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		} else {	/* not pci */
-			switch (r->size) {
-				case 1:	hwif->OUTB(val, reg);
-					break;
-				case 2:	hwif->OUTW(val, reg);
-					break;
-				case 4:	hwif->OUTL(val, reg);
-					break;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&ide_lock, flags);
-	err = count;
-out1:
-	free_page((unsigned long)prog);
-out:
-	free_page((unsigned long)buf);
-	return err;
-
-parse_error:
-	printk("parse error\n");
-	printk("proc_ide: error: %s: '%s'\n", msg, start);
-	err = -EINVAL;
-	goto out1;
-}
-
-static int proc_ide_read_config
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	char		*out = page;
-	int		len;
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	ide_hwif_t	*hwif = (ide_hwif_t *)data;
-	struct pci_dev	*dev = hwif->pci_dev;
-	if ((hwif->pci_dev && hwif->pci_dev->vendor) && dev && dev->bus) {
-		int reg = 0;
-
-		out += sprintf(out, "pci bus %02x device %02x vendor %04x "
-				"device %04x channel %d\n",
-			dev->bus->number, dev->devfn,
-			hwif->pci_dev->vendor, hwif->pci_dev->device,
-			hwif->channel);
-		do {
-			u8 val;
-			int rc = pci_read_config_byte(dev, reg, &val);
-			if (rc) {
-				printk("proc_ide_read_config: error %d reading"
-					" bus %02x dev %02x reg 0x%02x\n",
-					rc, dev->bus->number, dev->devfn, reg);
-				out += sprintf(out, "??%c",
-					(++reg & 0xf) ? ' ' : '\n');
-			} else
-				out += sprintf(out, "%02x%c",
-					val, (++reg & 0xf) ? ' ' : '\n');
-		} while (reg < 0x100);
-	} else
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		out += sprintf(out, "(none)\n");
-	len = out - page;
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
-}
-
 static int proc_ide_read_imodel
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -701,7 +445,6 @@
 
 static ide_proc_entry_t hwif_entries[] = {
 	{ "channel",	S_IFREG|S_IRUGO,	proc_ide_read_channel,	NULL },
-	{ "config",	S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config,	proc_ide_write_config },
 	{ "mate",	S_IFREG|S_IRUGO,	proc_ide_read_mate,	NULL },
 	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_imodel,	NULL },
 	{ NULL,	0, NULL, NULL }
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide-tape.c	2004-09-23 21:11:16 -07:00
@@ -2067,7 +2067,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	/* Begin DMA, if necessary */
 	if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags))
-		(void) (HWIF(drive)->ide_dma_begin(drive));
+		hwif->dma_start(drive);
 #endif
 	/* Send the actual packet */
 	HWIF(drive)->atapi_output_bytes(drive, pc->c, 12);
@@ -2135,12 +2135,8 @@
 				"reverting to PIO\n");
 		(void)__ide_dma_off(drive);
 	}
-	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
-		if (test_bit(PC_WRITING, &pc->flags))
-			dma_ok = !HWIF(drive)->ide_dma_write(drive);
-		else
-			dma_ok = !HWIF(drive)->ide_dma_read(drive);
-	}
+	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+		dma_ok = !hwif->dma_setup(drive);
 
 	if (IDE_CONTROL_REG)
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	2004-09-23 21:11:15 -07:00
+++ b/drivers/ide/ide-taskfile.c	2004-09-23 21:11:15 -07:00
@@ -5,7 +5,7 @@
  *  Copyright (C) 2000-2002	Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2001-2002	Klaus Smolin
  *					IBM Storage Technology Division
- *  Copyright (C) 2003		Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2003-2004	Bartlomiej Zolnierkiewicz
  *
  *  The big the bad and the ugly.
  *
@@ -178,15 +178,15 @@
 		case WIN_WRITEDMA_ONCE:
 		case WIN_WRITEDMA:
 		case WIN_WRITEDMA_EXT:
-			if (!hwif->ide_dma_write(drive))
-				return ide_started;
-			break;
 		case WIN_READDMA_ONCE:
 		case WIN_READDMA:
 		case WIN_READDMA_EXT:
 		case WIN_IDENTIFY_DMA:
-			if (!hwif->ide_dma_read(drive))
+			if (!hwif->dma_setup(drive)) {
+				hwif->dma_exec_cmd(drive, taskfile->command);
+				hwif->dma_start(drive);
 				return ide_started;
+			}
 			break;
 		default:
 			if (task->handler == NULL)
@@ -281,73 +281,6 @@
 
 EXPORT_SYMBOL(task_no_data_intr);
 
-static void task_buffer_sectors(ide_drive_t *drive, struct request *rq,
-				unsigned nsect, unsigned rw)
-{
-	char *buf = rq->buffer + blk_rq_offset(rq);
-
-	rq->sector += nsect;
-	rq->current_nr_sectors -= nsect;
-	rq->nr_sectors -= nsect;
-	__task_sectors(drive, buf, nsect, rw);
-}
-
-static inline void task_buffer_multi_sectors(ide_drive_t *drive,
-					     struct request *rq, unsigned rw)
-{
-	unsigned int msect = drive->mult_count, nsect;
-
-	nsect = rq->current_nr_sectors;
-	if (nsect > msect)
-		nsect = msect;
-
-	task_buffer_sectors(drive, rq, nsect, rw);
-}
-
-#ifdef CONFIG_IDE_TASKFILE_IO
-static void task_sectors(ide_drive_t *drive, struct request *rq,
-			 unsigned nsect, unsigned rw)
-{
-	if (rq->cbio) {	/* fs request */
-		rq->errors = 0;
-		task_bio_sectors(drive, rq, nsect, rw);
-	} else		/* task request */
-		task_buffer_sectors(drive, rq, nsect, rw);
-}
-
-static inline void task_bio_multi_sectors(ide_drive_t *drive,
-					  struct request *rq, unsigned rw)
-{
-	unsigned int nsect, msect = drive->mult_count;
-
-	do {
-		nsect = rq->current_nr_sectors;
-		if (nsect > msect)
-			nsect = msect;
-
-		task_bio_sectors(drive, rq, nsect, rw);
-
-		if (!rq->nr_sectors)
-			msect = 0;
-		else
-			msect -= nsect;
-	} while (msect);
-}
-
-static void task_multi_sectors(ide_drive_t *drive,
-			       struct request *rq, unsigned rw)
-{
-	if (rq->cbio) {	/* fs request */
-		rq->errors = 0;
-		task_bio_multi_sectors(drive, rq, rw);
-	} else		/* task request */
-		task_buffer_multi_sectors(drive, rq, rw);
-}
-#else
-# define task_sectors(d, rq, nsect, rw)	task_buffer_sectors(d, rq, nsect, rw)
-# define task_multi_sectors(d, rq, rw)	task_buffer_multi_sectors(d, rq, rw)
-#endif /* CONFIG_IDE_TASKFILE_IO */
-
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -368,37 +301,86 @@
 	return stat;
 }
 
+static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist *sg = hwif->sg_table;
+	struct page *page;
+#ifdef CONFIG_HIGHMEM
+	unsigned long flags;
+#endif
+	u8 *buf;
+
+	page = sg[hwif->cursg].page;
+#ifdef CONFIG_HIGHMEM
+	local_irq_save(flags);
+#endif
+	buf = kmap_atomic(page, KM_BIO_SRC_IRQ) +
+	      sg[hwif->cursg].offset + (hwif->cursg_ofs * SECTOR_SIZE);
+
+	hwif->nleft--;
+	hwif->cursg_ofs++;
+
+	if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) {
+		hwif->cursg++;
+		hwif->cursg_ofs = 0;
+	}
+
+	/* do the actual data transfer */
+	if (write)
+		taskfile_output_data(drive, buf, SECTOR_WORDS);
+	else
+		taskfile_input_data(drive, buf, SECTOR_WORDS);
+
+	kunmap_atomic(page, KM_BIO_SRC_IRQ);
+#ifdef CONFIG_HIGHMEM
+	local_irq_restore(flags);
+#endif
+}
+
+static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
+{
+	unsigned int nsect;
+
+	nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
+	while (nsect--)
+		ide_pio_sector(drive, write);
+}
+
 static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
 				     unsigned int write)
 {
+	if (rq->bio)	/* fs request */
+		rq->errors = 0;
+
 	switch (drive->hwif->data_phase) {
 	case TASKFILE_MULTI_IN:
 	case TASKFILE_MULTI_OUT:
-		task_multi_sectors(drive, rq, write);
+		ide_pio_multi(drive, write);
 		break;
 	default:
-		task_sectors(drive, rq, 1, write);
+		ide_pio_sector(drive, write);
 		break;
 	}
 }
 
-#ifdef CONFIG_IDE_TASKFILE_IO
 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
 				  const char *s, u8 stat)
 {
 	if (rq->bio) {
-		int sectors = rq->hard_nr_sectors - rq->nr_sectors;
+		ide_hwif_t *hwif = drive->hwif;
+		int sectors = hwif->nsect - hwif->nleft;
 
-		switch (drive->hwif->data_phase) {
+		switch (hwif->data_phase) {
 		case TASKFILE_IN:
-			if (rq->nr_sectors)
+			if (hwif->nleft)
 				break;
 			/* fall through */
 		case TASKFILE_OUT:
 			sectors--;
 			break;
 		case TASKFILE_MULTI_IN:
-			if (rq->nr_sectors)
+			if (hwif->nleft)
 				break;
 			/* fall through */
 		case TASKFILE_MULTI_OUT:
@@ -412,9 +394,6 @@
 	}
 	return drive->driver->error(drive, s, stat);
 }
-#else
-# define task_error(d, rq, s, stat) drive->driver->error(d, s, stat)
-#endif
 
 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
@@ -435,9 +414,11 @@
  */
 ide_startstop_t task_in_intr (ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq = HWGROUP(drive)->rq;
-	u8 stat = HWIF(drive)->INB(IDE_STATUS_REG);
+	u8 stat = hwif->INB(IDE_STATUS_REG);
 
+	/* new way for dealing with premature shared PCI interrupts */
 	if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
 		if (stat & (ERR_STAT | DRQ_STAT))
 			return task_error(drive, rq, __FUNCTION__, stat);
@@ -449,7 +430,7 @@
 	ide_pio_datablock(drive, rq, 0);
 
 	/* If it was the last datablock check status and finish transfer. */
-	if (!rq->nr_sectors) {
+	if (!hwif->nleft) {
 		stat = wait_drive_not_busy(drive);
 		if (!OK_STAT(stat, 0, BAD_R_STAT))
 			return task_error(drive, rq, __FUNCTION__, stat);
@@ -469,18 +450,18 @@
  */
 ide_startstop_t task_out_intr (ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq = HWGROUP(drive)->rq;
-	u8 stat;
+	u8 stat = hwif->INB(IDE_STATUS_REG);
 
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);
 	if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
 		return task_error(drive, rq, __FUNCTION__, stat);
 
 	/* Deal with unexpected ATA data phase. */
-	if (((stat & DRQ_STAT) == 0) ^ !rq->nr_sectors)
+	if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft)
 		return task_error(drive, rq, __FUNCTION__, stat);
 
-	if (!rq->nr_sectors) {
+	if (!hwif->nleft) {
 		task_end_request(drive, rq, stat);
 		return ide_stopped;
 	}
@@ -545,6 +526,9 @@
 
 		rq.hard_nr_sectors = rq.nr_sectors;
 		rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
+
+		if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
+			rq.flags |= REQ_RW;
 	}
 
 	rq.special = args;
@@ -942,12 +926,11 @@
 
    	        case TASKFILE_OUT_DMAQ:
 		case TASKFILE_OUT_DMA:
-			hwif->ide_dma_write(drive);
-			break;
-
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMA:
-			hwif->ide_dma_read(drive);
+			hwif->dma_setup(drive);
+			hwif->dma_exec_cmd(drive, taskfile->command);
+			hwif->dma_start(drive);
 			break;
 
 	        default:
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/ide.c	2004-09-23 21:11:16 -07:00
@@ -685,9 +685,9 @@
 	hwif->atapi_input_bytes		= tmp_hwif->atapi_input_bytes;
 	hwif->atapi_output_bytes	= tmp_hwif->atapi_output_bytes;
 
-	hwif->ide_dma_read		= tmp_hwif->ide_dma_read;
-	hwif->ide_dma_write		= tmp_hwif->ide_dma_write;
-	hwif->ide_dma_begin		= tmp_hwif->ide_dma_begin;
+	hwif->dma_setup			= tmp_hwif->dma_setup;
+	hwif->dma_exec_cmd		= tmp_hwif->dma_exec_cmd;
+	hwif->dma_start			= tmp_hwif->dma_start;
 	hwif->ide_dma_end		= tmp_hwif->ide_dma_end;
 	hwif->ide_dma_check		= tmp_hwif->ide_dma_check;
 	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;
@@ -900,6 +900,7 @@
 		hwif->drives[i].disk = NULL;
 		put_disk(disk);
 	}
+	kfree(hwif->sg_table);
 	unregister_blkdev(hwif->major, hwif->name);
 	spin_lock_irq(&ide_lock);
 
diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
--- a/drivers/ide/pci/alim15x3.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/alim15x3.c	2004-09-23 21:11:16 -07:00
@@ -558,18 +558,17 @@
 }
 
 /**
- *	ali15x3_dma_write	-	do a DMA IDE write
- *	@drive:	drive to issue write for
+ *	ali15x3_dma_setup	-	begin a DMA phase
+ *	@drive:	target device
  *
- *	Returns 1 if the DMA write cannot be performed, zero on 
- *	success.
+ *	Returns 1 if the DMA cannot be performed, zero on success.
  */
- 
-static int ali15x3_dma_write (ide_drive_t *drive)
+
+static int ali15x3_dma_setup(ide_drive_t *drive)
 {
 	if ((m5229_revision < 0xC2) && (drive->media != ide_disk))
 		return 1;	/* try PIO instead of DMA */
-	return __ide_dma_write(drive);
+	return ide_dma_setup(drive);
 }
 
 /**
@@ -773,7 +772,7 @@
                  * M1543C or newer for DMAing
                  */
                 hwif->ide_dma_check = &ali15x3_config_drive_for_dma;
-                hwif->ide_dma_write = &ali15x3_dma_write;
+		hwif->dma_setup = &ali15x3_dma_setup;
 		if (!noautodma)
 			hwif->autodma = 1;
 		if (!(hwif->udma_four))
diff -Nru a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
--- a/drivers/ide/pci/cs5530.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/cs5530.c	2004-09-23 21:11:16 -07:00
@@ -31,56 +31,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#define DISPLAY_CS5530_TIMINGS
-
-#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 cs5530_proc = 0;
-
-static struct pci_dev *bmide_dev;
-
-static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count)
-{
-	char *p = buffer;
-	unsigned long bibma = pci_resource_start(bmide_dev, 4);
-	u8  c0 = 0, c1 = 0;
-
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-
-	c0 = inb_p((u16)bibma + 0x02);
-	c1 = inb_p((u16)bibma + 0x0a);
-
-	p += sprintf(p, "\n                                "
-			"Cyrix 5530 Chipset.\n");
-	p += sprintf(p, "--------------- Primary Channel "
-			"---------------- Secondary Channel "
-			"-------------\n");
-	p += sprintf(p, "                %sabled "
-			"                        %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 "
-			"-------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s "
-			"            %s               %s\n",
-			(c0&0x20) ? "yes" : "no ",
-			(c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ",
-			(c1&0x40) ? "yes" : "no " );
-
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
-
-	return p-buffer;
-}
-#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */
-
 /**
  *	cs5530_xfer_set_mode	-	set a new transfer mode at the drive
  *	@drive: drive to tune
@@ -271,14 +221,6 @@
 {
 	struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
 	unsigned long flags;
-
-#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
-	if (!cs5530_proc) {
-		cs5530_proc = 1;
-		bmide_dev = dev;
-		ide_pci_create_host_proc("cs5530", cs5530_get_info);
-	}
-#endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */
 
 	dev = NULL;
 	while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
--- a/drivers/ide/pci/hpt366.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/hpt366.c	2004-09-23 21:11:16 -07:00
@@ -577,7 +577,7 @@
 	/* how about we flush and reset, mmmkay? */
 	pci_write_config_byte(dev, 0x51, 0x1F);
 	/* fall through to a reset */
-	case ide_dma_begin:
+	case dma_start:
 	case ide_dma_end:
 	/* reset the chips state over and over.. */
 	pci_write_config_byte(dev, 0x51, 0x13);
@@ -592,12 +592,12 @@
 	udelay(10);
 }
 
-static int hpt370_ide_dma_begin (ide_drive_t *drive)
+static void hpt370_ide_dma_start(ide_drive_t *drive)
 {
 #ifdef HPT_RESET_STATE_ENGINE
 	hpt370_clear_engine(drive);
 #endif
-	return __ide_dma_begin(drive);
+	ide_dma_start(drive);
 }
 
 static int hpt370_ide_dma_end (ide_drive_t *drive)
@@ -1230,7 +1230,7 @@
 		hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
 		hwif->ide_dma_end = &hpt374_ide_dma_end;
 	} else if (hpt_minimum_revision(dev,3)) {
-		hwif->ide_dma_begin = &hpt370_ide_dma_begin;
+		hwif->dma_start = &hpt370_ide_dma_start;
 		hwif->ide_dma_end = &hpt370_ide_dma_end;
 		hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
 		hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;
diff -Nru a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
--- a/drivers/ide/pci/ns87415.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/ns87415.c	2004-09-23 21:11:16 -07:00
@@ -101,22 +101,11 @@
 	return (dma_stat & 7) != 4;
 }
 
-static int ns87415_ide_dma_read (ide_drive_t *drive)
+static int ns87415_ide_dma_setup(ide_drive_t *drive)
 {
 	/* select DMA xfer */
 	ns87415_prepare_drive(drive, 1);
-	if (!(__ide_dma_read(drive)))
-		return 0;
-	/* DMA failed: select PIO xfer */
-	ns87415_prepare_drive(drive, 0);
-	return 1;
-}
-
-static int ns87415_ide_dma_write (ide_drive_t *drive)
-{
-	/* select DMA xfer */
-	ns87415_prepare_drive(drive, 1);
-	if (!(__ide_dma_write(drive)))
+	if (!ide_dma_setup(drive))
 		return 0;
 	/* DMA failed: select PIO xfer */
 	ns87415_prepare_drive(drive, 0);
@@ -204,8 +193,7 @@
 		return;
 
 	hwif->OUTB(0x60, hwif->dma_status);
-	hwif->ide_dma_read = &ns87415_ide_dma_read;
-	hwif->ide_dma_write = &ns87415_ide_dma_write;
+	hwif->dma_setup = &ns87415_ide_dma_setup;
 	hwif->ide_dma_check = &ns87415_ide_dma_check;
 	hwif->ide_dma_end = &ns87415_ide_dma_end;
 
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/pdc202xx_new.c	2004-09-23 21:11:16 -07:00
@@ -41,61 +41,6 @@
 
 #define PDC202_DEBUG_CABLE	0
 
-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 pdcnew_proc = 0;
-#define PDC202_MAX_DEVS		5
-static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS];
-static int n_pdc202_devs;
-
-static char * pdcnew_info(char *buf, struct pci_dev *dev)
-{
-	char *p = buf;
-
-	p += sprintf(p, "\n                                ");
-	switch(dev->device) {
-		case PCI_DEVICE_ID_PROMISE_20277:
-			p += sprintf(p, "SBFastTrak 133 Lite"); break;
-		case PCI_DEVICE_ID_PROMISE_20276:
-			p += sprintf(p, "MBFastTrak 133 Lite"); break;
-		case PCI_DEVICE_ID_PROMISE_20275:
-			p += sprintf(p, "MBUltra133"); break;
-		case PCI_DEVICE_ID_PROMISE_20271:
-			p += sprintf(p, "FastTrak TX2000"); break;
-		case PCI_DEVICE_ID_PROMISE_20270:
-			p += sprintf(p, "FastTrak LP/TX2/TX4"); break;
-		case PCI_DEVICE_ID_PROMISE_20269:
-			p += sprintf(p, "Ultra133 TX2"); break;
-		case PCI_DEVICE_ID_PROMISE_20268:
-			p += sprintf(p, "Ultra100 TX2"); break;
-		default:
-			p += sprintf(p, "Ultra series"); break;
-			break;
-	}
-	p += sprintf(p, " Chipset.\n");
-	return (char *)p;
-}
-
-static int pdcnew_get_info (char *buffer, char **addr, off_t offset, int count)
-{
-	char *p = buffer;
-	int i, len;
-
-	for (i = 0; i < n_pdc202_devs; i++) {
-		struct pci_dev *dev	= pdc202_devs[i];
-		p = pdcnew_info(buffer, dev);
-	}
-	/* p - buffer must be less than 4k! */
-	len = (p - buffer) - offset;
-	*addr = buffer + offset;
-	
-	return len > count ? count : len;
-}
-#endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
-
-
 static u8 pdcnew_ratemask (ide_drive_t *drive)
 {
 	u8 mode;
@@ -416,15 +361,6 @@
 #ifdef CONFIG_PPC_PMAC
 	apple_kiwi_init(dev);
 #endif
-
-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
-	pdc202_devs[n_pdc202_devs++] = dev;
-
-	if (!pdcnew_proc) {
-		pdcnew_proc = 1;
-		ide_pci_create_host_proc("pdcnew", pdcnew_get_info);
-	}
-#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
 
 	return dev->irq;
 }
diff -Nru a/drivers/ide/pci/pdc202xx_new.h b/drivers/ide/pci/pdc202xx_new.h
--- a/drivers/ide/pci/pdc202xx_new.h	2004-09-23 21:11:15 -07:00
+++ b/drivers/ide/pci/pdc202xx_new.h	2004-09-23 21:11:15 -07:00
@@ -43,8 +43,6 @@
 		set_2regs(0x13,(c));			\
 	} while(0)
 
-#define DISPLAY_PDC202XX_TIMINGS
-
 static void init_setup_pdcnew(struct pci_dev *, ide_pci_device_t *);
 static void init_setup_pdc20270(struct pci_dev *, ide_pci_device_t *);
 static void init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d);
diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
--- a/drivers/ide/pci/pdc202xx_old.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/pdc202xx_old.c	2004-09-23 21:11:16 -07:00
@@ -505,7 +505,7 @@
 	return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
 }
 
-static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
+static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
 {
 	if (drive->current_speed > XFER_UDMA_2)
 		pdc_old_enable_66MHz_clock(drive->hwif);
@@ -526,7 +526,7 @@
 					word_count | 0x06000000;
 		hwif->OUTL(word_count, atapi_reg);
 	}
-	return __ide_dma_begin(drive);
+	ide_dma_start(drive);
 }
 
 static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
@@ -747,7 +747,7 @@
 	if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
 		if (!(hwif->udma_four))
 			hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1;
-		hwif->ide_dma_begin = &pdc202xx_old_ide_dma_begin;
+		hwif->dma_start = &pdc202xx_old_ide_dma_start;
 		hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
 	} 
 	hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq;
diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
--- a/drivers/ide/pci/sc1200.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/sc1200.c	2004-09-23 21:11:16 -07:00
@@ -67,55 +67,6 @@
 	return pci_clock;
 }
 
-#define DISPLAY_SC1200_TIMINGS
-
-#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static int sc1200_get_info(char *, char **, off_t, int);
-extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */
-extern char *ide_media_verbose(ide_drive_t *);
-static u8 sc1200_proc = 0;
-
-static struct pci_dev *bmide_dev;
-
-static int sc1200_get_info (char *buffer, char **addr, off_t offset, int count)
-{
-	char *p = buffer;
-	unsigned long bibma = pci_resource_start(bmide_dev, 4);
-	int len;
-	u8  c0 = 0, c1 = 0;
-
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-
-	c0 = inb_p(bibma + 0x02);
-	c1 = inb_p(bibma + 0x0a);
-
-	p += sprintf(p, "\n                               National SCx200 Chipset.\n");
-	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
-	p += sprintf(p, "                %sabled                         %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-			(c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
-
-	p += sprintf(p, "UDMA\n");
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
-
-	len = (p - buffer) - offset;
-	*addr = buffer + offset;
-	
-	return len > count ? count : len;
-}
-#endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
-
 extern char *ide_xfer_verbose (byte xfer_rate);
 
 /*
@@ -505,21 +456,6 @@
 }
 
 /*
- * Initialize the sc1200 bridge for reliable IDE DMA operation.
- */
-static unsigned int __init init_chipset_sc1200 (struct pci_dev *dev, const char *name)
-{
-#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
-	if (!bmide_dev) {
-		sc1200_proc = 1;
-		bmide_dev = dev;
-		ide_pci_create_host_proc("sc1200", sc1200_get_info);
-	}
-#endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
-	return 0;
-}
-
-/*
  * This gets invoked by the IDE driver once for each channel,
  * and performs channel-specific pre-initialization before drive probing.
  */
@@ -545,7 +481,6 @@
 
 static ide_pci_device_t sc1200_chipset __devinitdata = {
 	.name		= "SC1200",
-	.init_chipset	= init_chipset_sc1200,
 	.init_hwif	= init_hwif_sc1200,
 	.channels	= 2,
 	.autodma	= AUTODMA,
diff -Nru a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
--- a/drivers/ide/pci/sgiioc4.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/sgiioc4.c	2004-09-23 21:11:16 -07:00
@@ -192,16 +192,13 @@
 	return intr_reg & 3;
 }
 
-static int
-sgiioc4_ide_dma_begin(ide_drive_t * drive)
+static void sgiioc4_ide_dma_start(ide_drive_t * drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
 	unsigned int temp_reg = reg | IOC4_S_DMA_START;
 
 	hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
-
-	return 0;
 }
 
 static u32
@@ -407,11 +404,7 @@
 	if (!hwif->dmatable_cpu)
 		goto dma_alloc_failure;
 
-	hwif->sg_table =
-	    kmalloc(sizeof (struct scatterlist) * IOC4_PRD_ENTRIES, GFP_KERNEL);
-
-	if (!hwif->sg_table)
-		goto dma_sgalloc_failure;
+	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
 	hwif->dma_base2 = (unsigned long)
 		pci_alloc_consistent(hwif->pci_dev,
@@ -424,9 +417,6 @@
 	return;
 
 dma_base2alloc_failure:
-	kfree(hwif->sg_table);
-
-dma_sgalloc_failure:
 	pci_free_consistent(hwif->pci_dev,
 			    IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
 			    hwif->dmatable_cpu, hwif->dmatable_dma);
@@ -511,10 +501,7 @@
 	unsigned int count = 0, i = 1;
 	struct scatterlist *sg;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
-	else
-		hwif->sg_nents = i = ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
 
 	if (!i)
 		return 0;	/* sglist of length Zero */
@@ -574,35 +561,31 @@
 	return 0;		/* revert to PIO for this request */
 }
 
-static int
-sgiioc4_ide_dma_read(ide_drive_t * drive)
+static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 	unsigned int count = 0;
+	int ddir;
 
-	if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_FROMDEVICE))) {
-		/* try PIO instead of DMA */
-		return 1;
-	}
-	/* Writes FROM the IOC4 TO Main Memory */
-	sgiioc4_configure_for_dma(IOC4_DMA_WRITE, drive);
-
-	return 0;
-}
-
-static int
-sgiioc4_ide_dma_write(ide_drive_t * drive)
-{
-	struct request *rq = HWGROUP(drive)->rq;
-	unsigned int count = 0;
+	if (rq_data_dir(rq))
+		ddir = PCI_DMA_TODEVICE;
+	else
+		ddir = PCI_DMA_FROMDEVICE;
 
-	if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_TODEVICE))) {
+	if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
 		/* try PIO instead of DMA */
+		ide_map_sg(drive, rq);
 		return 1;
 	}
 
-	sgiioc4_configure_for_dma(IOC4_DMA_READ, drive);
-	/* Writes TO the IOC4 FROM Main Memory */
+	if (rq_data_dir(rq))
+		/* Writes TO the IOC4 FROM Main Memory */
+		ddir = IOC4_DMA_READ;
+	else
+		/* Writes FROM the IOC4 TO Main Memory */
+		ddir = IOC4_DMA_WRITE;
+
+	sgiioc4_configure_for_dma(ddir, drive);
 
 	return 0;
 }
@@ -629,9 +612,8 @@
 	hwif->quirkproc = NULL;
 	hwif->busproc = NULL;
 
-	hwif->ide_dma_read = &sgiioc4_ide_dma_read;
-	hwif->ide_dma_write = &sgiioc4_ide_dma_write;
-	hwif->ide_dma_begin = &sgiioc4_ide_dma_begin;
+	hwif->dma_setup = &sgiioc4_ide_dma_setup;
+	hwif->dma_start = &sgiioc4_ide_dma_start;
 	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
 	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
 	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
diff -Nru a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
--- a/drivers/ide/pci/sl82c105.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/sl82c105.c	2004-09-23 21:11:16 -07:00
@@ -236,15 +236,13 @@
  * The generic IDE core will have disabled the BMEN bit before this
  * function is called.
  */
-static int sl82c105_ide_dma_begin(ide_drive_t *drive)
+static void sl82c105_ide_dma_start(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *dev = hwif->pci_dev;
 
-//	DBG(("sl82c105_ide_dma_begin(drive:%s)\n", drive->name));
-
 	sl82c105_reset_host(dev);
-	return __ide_dma_begin(drive);
+	ide_dma_start(drive);
 }
 
 static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
@@ -469,7 +467,7 @@
 	hwif->ide_dma_on = &sl82c105_ide_dma_on;
 	hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
 	hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
-	hwif->ide_dma_begin = &sl82c105_ide_dma_begin;
+	hwif->dma_start = &sl82c105_ide_dma_start;
 	hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
 
 	if (!noautodma)
diff -Nru a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
--- a/drivers/ide/pci/triflex.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/ide/pci/triflex.c	2004-09-23 21:11:16 -07:00
@@ -41,57 +41,6 @@
 #include <linux/ide.h>
 #include <linux/init.h>
 
-static struct pci_dev *triflex_dev;
-
-#ifdef CONFIG_PROC_FS
-static int triflex_get_info(char *buf, char **addr, off_t offset, int count)
-{
-	char *p = buf;
-	int len;
-
-	struct pci_dev *dev	= triflex_dev;
-	unsigned long bibma = pci_resource_start(dev, 4);
-	u8  c0 = 0, c1 = 0;
-	u32 pri_timing, sec_timing;
-
-	p += sprintf(p, "\n                                Compaq Triflex Chipset\n");
-	
-	pci_read_config_dword(dev, 0x70, &pri_timing);
-	pci_read_config_dword(dev, 0x74, &sec_timing);
-
-	/*
-	 * at that point bibma+0x2 et bibma+0xa are byte registers
-	 * to investigate:
-	 */
-	c0 = inb((unsigned short)bibma + 0x02);
-	c1 = inb((unsigned short)bibma + 0x0a);
-
-	p += sprintf(p, "--------------- Primary Channel "
-			"---------------- Secondary Channel "
-			"-------------\n");
-	p += sprintf(p, "                %sabled "
-			"                        %sabled\n",
-			(c0&0x80) ? "dis" : " en",
-			(c1&0x80) ? "dis" : " en");
-	p += sprintf(p, "--------------- drive0 --------- drive1 "
-			"-------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:    %s              %s "
-			"            %s               %s\n",
-			(c0&0x20) ? "yes" : "no ",
-			(c0&0x40) ? "yes" : "no ",
-			(c1&0x20) ? "yes" : "no ",
-			(c1&0x40) ? "yes" : "no " );
-
-	p += sprintf(p, "DMA\n");
-	p += sprintf(p, "PIO\n");
-
-	len = (p - buf) - offset;
-	*addr = buf + offset;
-	
-	return len > count ? count : len;
-}
-#endif
-
 static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -206,18 +155,8 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
-static unsigned int __init init_chipset_triflex(struct pci_dev *dev, 
-		const char *name) 
-{
-#ifdef CONFIG_PROC_FS
-	ide_pci_create_host_proc("triflex", triflex_get_info);
-#endif
-	return 0;	
-}
-
 static ide_pci_device_t triflex_device __devinitdata = {
 	.name		= "TRIFLEX",
-	.init_chipset	= init_chipset_triflex,
 	.init_hwif	= init_hwif_triflex,
 	.channels	= 2,
 	.autodma	= AUTODMA,
@@ -229,7 +168,6 @@
 		const struct pci_device_id *id)
 {
 	ide_setup_pci_device(dev, &triflex_device);
-	triflex_dev = dev;
 
 	return 0;
 }
diff -Nru a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
--- a/drivers/ide/pci/trm290.c	2004-09-23 21:11:15 -07:00
+++ b/drivers/ide/pci/trm290.c	2004-09-23 21:11:15 -07:00
@@ -179,64 +179,32 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int trm290_ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
+static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= HWGROUP(drive)->rq;
-//	ide_task_t *args	= rq->special;
-	task_ioreg_t command	= WIN_NOP;
-	unsigned int count, reading = 2, writing = 0;
 
-	reading = 0;
-	writing = 1;
-#ifdef TRM290_NO_DMA_WRITES
-	/* always use PIO for writes */
-	trm290_prepare_drive(drive, 0);	/* select PIO xfer */
-	return 1;
-#endif
-	if (!(count = ide_build_dmatable(drive, rq))) {
-		/* try PIO instead of DMA */
-		trm290_prepare_drive(drive, 0); /* select PIO xfer */
-		return 1;
-	}
-	/* select DMA xfer */
-	trm290_prepare_drive(drive, 1);
-	hwif->OUTL(hwif->dmatable_dma|reading|writing, hwif->dma_command);
-	drive->waiting_for_dma = 1;
-	/* start DMA */
-	hwif->OUTW((count * 2) - 1, hwif->dma_status);
-	if (drive->media != ide_disk)
-		return 0;
 	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
 		BUG();
 	ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-	/*
-	 * FIX ME to use only ACB ide_task_t args Struct
-	 */
-#if 0
-	{
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#else
-	command = /* (lba48) ? WIN_READDMA_EXT : */ WIN_READDMA;
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#endif
 	/* issue cmd to drive */
 	hwif->OUTB(command, IDE_COMMAND_REG);
-	return hwif->ide_dma_begin(drive);
 }
 
-static int trm290_ide_dma_read (ide_drive_t *drive  /*, struct request *rq */)
+static int trm290_ide_dma_setup(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct request *rq	= HWGROUP(drive)->rq;
-//	ide_task_t *args	= rq->special;
-	task_ioreg_t command	= WIN_NOP;
-	unsigned int count, reading = 2, writing = 0;
+	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = hwif->hwgroup->rq;
+	unsigned int count, rw;
+
+	if (rq_data_dir(rq)) {
+#ifdef TRM290_NO_DMA_WRITES
+		/* always use PIO for writes */
+		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
+		return 1;
+#endif
+		rw = 1;
+	} else
+		rw = 2;
 
 	if (!(count = ide_build_dmatable(drive, rq))) {
 		/* try PIO instead of DMA */
@@ -245,38 +213,15 @@
 	}
 	/* select DMA xfer */
 	trm290_prepare_drive(drive, 1);
-	hwif->OUTL(hwif->dmatable_dma|reading|writing, hwif->dma_command);
+	hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command);
 	drive->waiting_for_dma = 1;
 	/* start DMA */
 	hwif->OUTW((count * 2) - 1, hwif->dma_status);
-	if (drive->media != ide_disk)
-		return 0;
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
-	ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-	/*
-	 * FIX ME to use only ACB ide_task_t args Struct
-	 */
-#if 0
-	{
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#else
-	command = /* (lba48) ? WIN_WRITEDMA_EXT : */ WIN_WRITEDMA;
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-#endif
-	/* issue cmd to drive */
-	hwif->OUTB(command, IDE_COMMAND_REG);
-	return hwif->ide_dma_begin(drive);
+	return 0;
 }
 
-static int trm290_ide_dma_begin (ide_drive_t *drive)
+static void trm290_ide_dma_start(ide_drive_t *drive)
 {
-	return 0;
 }
 
 static int trm290_ide_dma_end (ide_drive_t *drive)
@@ -347,9 +292,9 @@
 	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	hwif->ide_dma_write = &trm290_ide_dma_write;
-	hwif->ide_dma_read = &trm290_ide_dma_read;
-	hwif->ide_dma_begin = &trm290_ide_dma_begin;
+	hwif->dma_setup = &trm290_ide_dma_setup;
+	hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd;
+	hwif->dma_start = &trm290_ide_dma_start;
 	hwif->ide_dma_end = &trm290_ide_dma_end;
 	hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c	2004-09-23 21:11:15 -07:00
+++ b/drivers/ide/ppc/pmac.c	2004-09-23 21:11:15 -07:00
@@ -34,6 +34,7 @@
 #include <linux/pci.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
+#include <linux/scatterlist.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
@@ -77,10 +78,6 @@
 	 */
 	volatile struct dbdma_regs*	dma_regs;
 	struct dbdma_cmd*		dma_table_cpu;
-	dma_addr_t			dma_table_dma;
-	struct scatterlist*		sg_table;
-	int				sg_nents;
-	int				sg_dma_direction;
 #endif
 	
 } pmac_ide_hwif_t;
@@ -361,7 +358,6 @@
 static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio);
 static void pmac_ide_selectproc(ide_drive_t *drive);
 static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
-static int pmac_ide_dma_begin (ide_drive_t *drive);
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
@@ -1249,6 +1245,8 @@
 		hwif->noprobe = 0;
 #endif /* CONFIG_PMAC_PBOOK */
 
+	hwif->sg_max_nents = MAX_DCMDS;
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	/* has a DBDMA controller channel */
 	if (pmif->dma_regs)
@@ -1566,66 +1564,6 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 
 /*
- * This is very close to the generic ide-dma version of the function except
- * that we don't use the fields in the hwif but our own copies for sg_table
- * and friends. We build & map the sglist for a given request
- */
-static int __pmac
-pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-	struct scatterlist *sg = pmif->sg_table;
-	int nents;
-
-	nents = blk_rq_map_sg(drive->queue, rq, sg);
-		
-	if (rq_data_dir(rq) == READ)
-		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-	else
-		pmif->sg_dma_direction = PCI_DMA_TODEVICE;
-
-	return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
-}
-
-/*
- * Same as above but for a "raw" taskfile request
- */
-static int __pmac
-pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-	struct scatterlist *sg = pmif->sg_table;
-	int nents = 0;
-	ide_task_t *args = rq->special;
-	unsigned char *virt_addr = rq->buffer;
-	int sector_count = rq->nr_sectors;
-
-	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-		pmif->sg_dma_direction = PCI_DMA_TODEVICE;
-	else
-		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-	
-	if (sector_count > 128) {
-		memset(&sg[nents], 0, sizeof(*sg));
-		sg[nents].page = virt_to_page(virt_addr);
-		sg[nents].offset = offset_in_page(virt_addr);
-		sg[nents].length = 128  * SECTOR_SIZE;
-		nents++;
-		virt_addr = virt_addr + (128 * SECTOR_SIZE);
-		sector_count -= 128;
-	}
-	memset(&sg[nents], 0, sizeof(*sg));
-	sg[nents].page = virt_to_page(virt_addr);
-	sg[nents].offset = offset_in_page(virt_addr);
-	sg[nents].length =  sector_count  * SECTOR_SIZE;
-	nents++;
-   
-	return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
-}
-
-/*
  * pmac_ide_build_dmatable builds the DBDMA command list
  * for a transfer and sets the DBDMA channel to point to it.
  */
@@ -1648,16 +1586,13 @@
 	while (readl(&dma->status) & RUN)
 		udelay(1);
 
-	/* Build sglist */
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		pmif->sg_nents = i = pmac_ide_raw_build_sglist(drive, rq);
-	else
-		pmif->sg_nents = i = pmac_ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
+
 	if (!i)
 		return 0;
 
 	/* Build DBDMA commands list */
-	sg = pmif->sg_table;
+	sg = hwif->sg_table;
 	while (i && sg_dma_len(sg)) {
 		u32 cur_addr;
 		u32 cur_len;
@@ -1702,16 +1637,16 @@
 		memset(table, 0, sizeof(struct dbdma_cmd));
 		st_le16(&table->command, DBDMA_STOP);
 		mb();
-		writel(pmif->dma_table_dma, &dma->cmdptr);
+		writel(hwif->dmatable_dma, &dma->cmdptr);
 		return 1;
 	}
 
 	printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
  use_pio_instead:
 	pci_unmap_sg(hwif->pci_dev,
-		     pmif->sg_table,
-		     pmif->sg_nents,
-		     pmif->sg_dma_direction);
+		     hwif->sg_table,
+		     hwif->sg_nents,
+		     hwif->sg_dma_direction);
 	return 0; /* revert to PIO for this request */
 }
 
@@ -1719,14 +1654,14 @@
 static void __pmac
 pmac_ide_destroy_dmatable (ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct pci_dev *dev = HWIF(drive)->pci_dev;
-	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
-	struct scatterlist *sg = pmif->sg_table;
-	int nents = pmif->sg_nents;
+	struct scatterlist *sg = hwif->sg_table;
+	int nents = hwif->sg_nents;
 
 	if (nents) {
-		pci_unmap_sg(dev, sg, nents, pmif->sg_dma_direction);
-		pmif->sg_nents = 0;
+		pci_unmap_sg(dev, sg, nents, hwif->sg_dma_direction);
+		hwif->sg_nents = 0;
 	}
 }
 
@@ -1889,7 +1824,7 @@
  * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
  */
 static int __pmac
-pmac_ide_dma_start(ide_drive_t *drive, int reading)
+pmac_ide_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
@@ -1901,12 +1836,14 @@
 		return 1;
 	ata4 = (pmif->kind == controller_kl_ata4);	
 
-	if (!pmac_ide_build_dmatable(drive, rq))
+	if (!pmac_ide_build_dmatable(drive, rq)) {
+		ide_map_sg(drive, rq);
 		return 1;
+	}
 
 	/* Apple adds 60ns to wrDataSetup on reads */
 	if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
-		writel(pmif->timings[unit] + (reading ? 0x00800000UL : 0),
+		writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
 			(unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG));
 		(void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG));
 	}
@@ -1916,87 +1853,28 @@
 	return 0;
 }
 
-/*
- * Start a DMA READ command
- */
-static int __pmac
-pmac_ide_dma_read(ide_drive_t *drive)
-{
-	struct request *rq = HWGROUP(drive)->rq;
-	u8 lba48 = (drive->addressing == 1) ? 1 : 0;
-	task_ioreg_t command = WIN_NOP;
-
-	if (pmac_ide_dma_start(drive, 1))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-	
-	if (drive->vdma)
-		command = (lba48) ? WIN_READ_EXT: WIN_READ;
-		
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-
-	return pmac_ide_dma_begin(drive);
-}
-
-/*
- * Start a DMA WRITE command
- */
-static int __pmac
-pmac_ide_dma_write (ide_drive_t *drive)
+static void __pmac
+pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
-	struct request *rq = HWGROUP(drive)->rq;
-	u8 lba48 = (drive->addressing == 1) ? 1 : 0;
-	task_ioreg_t command = WIN_NOP;
-
-	if (pmac_ide_dma_start(drive, 0))
-		return 1;
-
-	if (drive->media != ide_disk)
-		return 0;
-
-	command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-	if (drive->vdma)
-		command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
-		
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-		command = args->tfRegister[IDE_COMMAND_OFFSET];
-	}
-
 	/* issue cmd to drive */
 	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-
-	return pmac_ide_dma_begin(drive);
 }
 
 /*
  * Kick the DMA controller into life after the DMA command has been issued
  * to the drive.
  */
-static int __pmac
-pmac_ide_dma_begin (ide_drive_t *drive)
+static void __pmac
+pmac_ide_dma_start(ide_drive_t *drive)
 {
 	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
 	volatile struct dbdma_regs *dma;
 
-	if (pmif == NULL)
-		return 1;
 	dma = pmif->dma_regs;
 
 	writel((RUN << 16) | RUN, &dma->control);
 	/* Make sure it gets to the controller right now */
 	(void)readl(&dma->control);
-	return 0;
 }
 
 /*
@@ -2134,27 +2012,19 @@
 	pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
 		hwif->pci_dev,
 		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
-		&pmif->dma_table_dma);
+		&hwif->dmatable_dma);
 	if (pmif->dma_table_cpu == NULL) {
 		printk(KERN_ERR "%s: unable to allocate DMA command list\n",
 		       hwif->name);
 		return;
 	}
 
-	pmif->sg_table = kmalloc(sizeof(struct scatterlist) * MAX_DCMDS,
-				 GFP_KERNEL);
-	if (pmif->sg_table == NULL) {
-		pci_free_consistent(	hwif->pci_dev,
-					(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
-				    	pmif->dma_table_cpu, pmif->dma_table_dma);
-		return;
-	}
 	hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
 	hwif->ide_dma_on = &__ide_dma_on;
 	hwif->ide_dma_check = &pmac_ide_dma_check;
-	hwif->ide_dma_read = &pmac_ide_dma_read;
-	hwif->ide_dma_write = &pmac_ide_dma_write;
-	hwif->ide_dma_begin = &pmac_ide_dma_begin;
+	hwif->dma_setup = &pmac_ide_dma_setup;
+	hwif->dma_exec_dma = &pmac_ide_dma_exec_cmd;
+	hwif->dma_start = &pmac_ide_dma_start;
 	hwif->ide_dma_end = &pmac_ide_dma_end;
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
 	hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	2004-09-23 21:11:16 -07:00
+++ b/drivers/scsi/ide-scsi.c	2004-09-23 21:11:16 -07:00
@@ -552,6 +552,7 @@
 
 static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	idescsi_pc_t *pc = scsi->pc;
 	atapi_ireason_t ireason;
@@ -576,7 +577,7 @@
 	atapi_output_bytes(drive, scsi->pc->c, 12);
 	if (test_bit (PC_DMA_OK, &pc->flags)) {
 		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
-		(void) (HWIF(drive)->ide_dma_begin(drive));
+		hwif->dma_start(drive);
 	}
 	return ide_started;
 }
@@ -587,6 +588,7 @@
 static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 {
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+	ide_hwif_t *hwif = drive->hwif;
 	atapi_feature_t feature;
 	atapi_bcount_t bcount;
 	struct request *rq = pc->rq;
@@ -597,12 +599,8 @@
 	bcount.all = min(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
 	feature.all = 0;
-	if (drive->using_dma && rq->bio) {
-		if (test_bit(PC_WRITING, &pc->flags))
-			feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
-		else
-			feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
-	}
+	if (drive->using_dma && rq->bio)
+		feature.b.dma = !hwif->dma_setup(drive);
 
 	SELECT_DRIVE(drive);
 	if (IDE_CONTROL_REG)
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	2004-09-23 21:11:16 -07:00
+++ b/include/linux/ide.h	2004-09-23 21:11:16 -07:00
@@ -796,27 +796,6 @@
 	struct gendisk *disk;
 } ide_drive_t;
 
-/*
- * mapping stuff, prepare for highmem...
- * 
- * temporarily mapping a (possible) highmem bio for PIO transfer
- */
-#ifndef CONFIG_IDE_TASKFILE_IO
-
-#define ide_rq_offset(rq) \
-	(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
-
-static inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
-{
-	return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
-}
-
-static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags)
-{
-	bio_kunmap_irq(buffer, flags);
-}
-#endif /* !CONFIG_IDE_TASKFILE_IO */
-
 #define IDE_CHIPSET_PCI_MASK	\
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)	((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
@@ -894,9 +873,9 @@
 	void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
 	void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
 
-	int (*ide_dma_read)(ide_drive_t *drive);
-	int (*ide_dma_write)(ide_drive_t *drive);
-	int (*ide_dma_begin)(ide_drive_t *drive);
+	int (*dma_setup)(ide_drive_t *);
+	void (*dma_exec_cmd)(ide_drive_t *, u8);
+	void (*dma_start)(ide_drive_t *);
 	int (*ide_dma_end)(ide_drive_t *drive);
 	int (*ide_dma_check)(ide_drive_t *drive);
 	int (*ide_dma_on)(ide_drive_t *drive);
@@ -927,12 +906,18 @@
 	dma_addr_t	dmatable_dma;
 	/* Scatter-gather list used to build the above */
 	struct scatterlist *sg_table;
+	int sg_max_nents;		/* Maximum number of entries in it */
 	int sg_nents;			/* Current number of entries in it */
 	int sg_dma_direction;		/* dma transfer direction */
 
 	/* data phase of the active command (currently only valid for PIO/DMA) */
 	int		data_phase;
 
+	unsigned int nsect;
+	unsigned int nleft;
+	unsigned int cursg;
+	unsigned int cursg_ofs;
+
 	int		mmio;		/* hosts iomio (0) or custom (2) select */
 	int		rqsize;		/* max sectors per request */
 	int		irq;		/* our irq number */
@@ -1376,35 +1361,6 @@
 extern void taskfile_input_data(ide_drive_t *, void *, u32);
 extern void taskfile_output_data(ide_drive_t *, void *, u32);
 
-#define IDE_PIO_IN	0
-#define IDE_PIO_OUT	1
-
-static inline void __task_sectors(ide_drive_t *drive, char *buf,
-				  unsigned nsect, unsigned rw)
-{
-	/*
-	 * IRQ can happen instantly after reading/writing
-	 * last sector of the datablock.
-	 */
-	if (rw == IDE_PIO_OUT)
-		taskfile_output_data(drive, buf, nsect * SECTOR_WORDS);
-	else
-		taskfile_input_data(drive, buf, nsect * SECTOR_WORDS);
-}
-
-#ifdef CONFIG_IDE_TASKFILE_IO
-static inline void task_bio_sectors(ide_drive_t *drive, struct request *rq,
-				    unsigned nsect, unsigned rw)
-{
-	unsigned long flags;
-	char *buf = rq_map_buffer(rq, &flags);
-
-	process_that_request_first(rq, nsect);
-	__task_sectors(drive, buf, nsect, rw);
-	rq_unmap_buffer(buf, &flags);
-}
-#endif /* CONFIG_IDE_TASKFILE_IO */
-
 extern int drive_is_ready(ide_drive_t *);
 extern int wait_for_ready(ide_drive_t *, int /* timeout */);
 
@@ -1535,6 +1491,9 @@
 extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
 extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
 
+extern void ide_init_sg_cmd(ide_drive_t *, struct request *);
+void ide_map_sg(ide_drive_t *, struct request *);
+
 #define BAD_DMA_DRIVE		0
 #define GOOD_DMA_DRIVE		1
 
@@ -1545,22 +1504,19 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 extern int ide_build_sglist(ide_drive_t *, struct request *);
-extern int ide_raw_build_sglist(ide_drive_t *, struct request *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 extern void ide_destroy_dmatable(ide_drive_t *);
 extern ide_startstop_t ide_dma_intr(ide_drive_t *);
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
-extern int ide_start_dma(ide_hwif_t *, ide_drive_t *, int);
 
 extern int __ide_dma_host_off(ide_drive_t *);
 extern int __ide_dma_off_quietly(ide_drive_t *);
 extern int __ide_dma_host_on(ide_drive_t *);
 extern int __ide_dma_on(ide_drive_t *);
 extern int __ide_dma_check(ide_drive_t *);
-extern int __ide_dma_read(ide_drive_t *);
-extern int __ide_dma_write(ide_drive_t *);
-extern int __ide_dma_begin(ide_drive_t *);
+extern int ide_dma_setup(ide_drive_t *);
+extern void ide_dma_start(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
 extern int __ide_dma_test_irq(ide_drive_t *);
 extern int __ide_dma_verbose(ide_drive_t *);
diff -Nru a/include/linux/scatterlist.h b/include/linux/scatterlist.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/scatterlist.h	2004-09-23 21:11:16 -07:00
@@ -0,0 +1,14 @@
+#ifndef _LINUX_SCATTERLIST_H
+#define _LINUX_SCATTERLIST_H
+
+static inline void sg_init_one(struct scatterlist *sg,
+			       u8 *buf, unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+
+	sg->page = virt_to_page(buf);
+	sg->offset = offset_in_page(buf);
+	sg->length = buflen;
+}
+
+#endif /* _LINUX_SCATTERLIST_H */