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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 @@ -74,227 +39,6 @@ #include -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 * 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 #include -#define DISPLAY_CS5530_TIMINGS - -#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -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 -#include - -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 -#include - -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 #include -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 #include #include +#include #include #include @@ -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<> (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 */