Commit e6f86a31 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bart.bkbits.net/ide-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents e8990100 5a8191fb
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/scatterlist.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/svinto.h> #include <asm/arch/svinto.h>
...@@ -207,10 +208,8 @@ etrax100_ide_inb(ide_ioreg_t reg) ...@@ -207,10 +208,8 @@ etrax100_ide_inb(ide_ioreg_t reg)
#define ATA_PIO0_HOLD 4 #define ATA_PIO0_HOLD 4
static int e100_dma_check (ide_drive_t *drive); 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_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_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_ide_output_data (ide_drive_t *drive, void *, unsigned int);
static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
...@@ -281,6 +280,38 @@ static void tune_e100_ide(ide_drive_t *drive, byte pio) ...@@ -281,6 +280,38 @@ static void tune_e100_ide(ide_drive_t *drive, byte pio)
} }
} }
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))
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 void __init
init_e100_ide (void) init_e100_ide (void)
{ {
...@@ -302,9 +333,9 @@ init_e100_ide (void) ...@@ -302,9 +333,9 @@ init_e100_ide (void)
hwif->atapi_output_bytes = &e100_atapi_output_bytes; hwif->atapi_output_bytes = &e100_atapi_output_bytes;
hwif->ide_dma_check = &e100_dma_check; hwif->ide_dma_check = &e100_dma_check;
hwif->ide_dma_end = &e100_dma_end; hwif->ide_dma_end = &e100_dma_end;
hwif->ide_dma_write = &e100_dma_write; hwif->dma_setup = &e100_dma_setup;
hwif->ide_dma_read = &e100_dma_read; hwif->dma_exec_cmd = &e100_dma_exec_cmd;
hwif->ide_dma_begin = &e100_dma_begin; hwif->dma_start = &e100_dma_start;
hwif->OUTB = &etrax100_ide_outb; hwif->OUTB = &etrax100_ide_outb;
hwif->OUTW = &etrax100_ide_outw; hwif->OUTW = &etrax100_ide_outw;
hwif->OUTBSYNC = &etrax100_ide_outbsync; hwif->OUTBSYNC = &etrax100_ide_outbsync;
...@@ -624,12 +655,7 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) ...@@ -624,12 +655,7 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
ata_tot_size = 0; ata_tot_size = 0;
if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) { if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
u8 *virt_addr = rq->buffer; sg_init_one(&sg[0], rq->buffer, rq->nr_sectors * SECTOR_SIZE);
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; hwif->sg_nents = i = 1;
} }
else else
...@@ -773,10 +799,6 @@ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive) ...@@ -773,10 +799,6 @@ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
* sector address using CHS or LBA. All that remains is to prepare for DMA * 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. * 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 0 if all went well.
* Returns 1 if DMA read/write could not be started, in which case * Returns 1 if DMA read/write could not be started, in which case
* the caller should revert to PIO for the current request. * the caller should revert to PIO for the current request.
...@@ -793,35 +815,9 @@ static int e100_dma_end(ide_drive_t *drive) ...@@ -793,35 +815,9 @@ static int e100_dma_end(ide_drive_t *drive)
return 0; 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) { if (e100_read_command) {
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);
}
}
/* begin DMA */ /* begin DMA */
/* need to do this before RX DMA due to a chip bug /* need to do this before RX DMA due to a chip bug
...@@ -854,32 +850,6 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading) ...@@ -854,32 +850,6 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
} else { } else {
/* writing */ /* 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 */ /* begin DMA */
*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs); *R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
...@@ -902,44 +872,4 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading) ...@@ -902,44 +872,4 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
D(printk("dma write of %d bytes.\n", ata_tot_size)); 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);
} }
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/scatterlist.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/ecard.h> #include <asm/ecard.h>
...@@ -223,10 +224,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq) ...@@ -223,10 +224,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
else else
hwif->sg_dma_direction = DMA_FROM_DEVICE; hwif->sg_dma_direction = DMA_FROM_DEVICE;
memset(sg, 0, sizeof(*sg)); sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
sg->page = virt_to_page(rq->buffer);
sg->offset = offset_in_page(rq->buffer);
sg->length = rq->nr_sectors * SECTOR_SIZE;
nents = 1; nents = 1;
} else { } else {
nents = blk_rq_map_sg(drive->queue, rq, sg); nents = blk_rq_map_sg(drive->queue, rq, sg);
...@@ -402,14 +400,13 @@ static int icside_dma_end(ide_drive_t *drive) ...@@ -402,14 +400,13 @@ static int icside_dma_end(ide_drive_t *drive)
return get_dma_residue(hwif->hw.dma) != 0; 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); ide_hwif_t *hwif = HWIF(drive);
/* We can not enable DMA on both channels simultaneously. */ /* We can not enable DMA on both channels simultaneously. */
BUG_ON(dma_channel_active(hwif->hw.dma)); BUG_ON(dma_channel_active(hwif->hw.dma));
enable_dma(hwif->hw.dma); enable_dma(hwif->hw.dma);
return 0;
} }
/* /*
...@@ -441,11 +438,16 @@ static ide_startstop_t icside_dmaintr(ide_drive_t *drive) ...@@ -441,11 +438,16 @@ static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
return DRIVER(drive)->error(drive, __FUNCTION__, stat); return DRIVER(drive)->error(drive, __FUNCTION__, stat);
} }
static int static int icside_dma_setup(ide_drive_t *drive)
icside_dma_common(ide_drive_t *drive, struct request *rq,
unsigned int dma_mode)
{ {
ide_hwif_t *hwif = HWIF(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. * We can not enable DMA on both channels.
...@@ -481,79 +483,10 @@ icside_dma_common(ide_drive_t *drive, struct request *rq, ...@@ -481,79 +483,10 @@ icside_dma_common(ide_drive_t *drive, struct request *rq,
return 0; 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 */ /* issue cmd to drive */
ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL); 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) static int icside_dma_test_irq(ide_drive_t *drive)
...@@ -623,9 +556,9 @@ static int icside_dma_init(ide_hwif_t *hwif) ...@@ -623,9 +556,9 @@ static int icside_dma_init(ide_hwif_t *hwif)
hwif->ide_dma_off_quietly = icside_dma_off_quietly; hwif->ide_dma_off_quietly = icside_dma_off_quietly;
hwif->ide_dma_host_on = icside_dma_host_on; hwif->ide_dma_host_on = icside_dma_host_on;
hwif->ide_dma_on = icside_dma_on; hwif->ide_dma_on = icside_dma_on;
hwif->ide_dma_read = icside_dma_read; hwif->dma_setup = icside_dma_setup;
hwif->ide_dma_write = icside_dma_write; hwif->dma_exec_cmd = icside_dma_exec_cmd;
hwif->ide_dma_begin = icside_dma_begin; hwif->dma_start = icside_dma_start;
hwif->ide_dma_end = icside_dma_end; hwif->ide_dma_end = icside_dma_end;
hwif->ide_dma_test_irq = icside_dma_test_irq; hwif->ide_dma_test_irq = icside_dma_test_irq;
hwif->ide_dma_verbose = icside_dma_verbose; hwif->ide_dma_verbose = icside_dma_verbose;
......
...@@ -865,20 +865,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, ...@@ -865,20 +865,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
{ {
ide_startstop_t startstop; ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
/* Wait for the controller to be idle. */ /* Wait for the controller to be idle. */
if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY)) if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
return startstop; return startstop;
if (info->dma) { if (info->dma)
if (info->cmd == READ) { info->dma = !hwif->dma_setup(drive);
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");
}
}
/* Set up the controller registers. */ /* Set up the controller registers. */
/* FIXME: for Virtual DMA we must check harder */ /* FIXME: for Virtual DMA we must check harder */
...@@ -916,6 +910,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, ...@@ -916,6 +910,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
struct request *rq, struct request *rq,
ide_handler_t *handler) ide_handler_t *handler)
{ {
ide_hwif_t *hwif = drive->hwif;
int cmd_len; int cmd_len;
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -947,7 +942,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, ...@@ -947,7 +942,7 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
/* Start the DMA if need be */ /* Start the DMA if need be */
if (info->dma) if (info->dma)
(void) HWIF(drive)->ide_dma_begin(drive); hwif->dma_start(drive);
return ide_started; return ide_started;
} }
......
...@@ -419,10 +419,25 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector ...@@ -419,10 +419,25 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
hwif->OUTB(head|drive->select.all,IDE_SELECT_REG); hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
} }
if (rq_data_dir(rq) == READ) { if (dma) {
if (dma && !hwif->ide_dma_read(drive)) 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; return ide_started;
}
/* fallback to PIO */
}
if (rq_data_dir(rq) == READ) {
command = ((drive->mult_count) ? command = ((drive->mult_count) ?
((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) : ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) :
((lba48) ? WIN_READ_EXT : WIN_READ)); ((lba48) ? WIN_READ_EXT : WIN_READ));
...@@ -431,9 +446,6 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector ...@@ -431,9 +446,6 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
} else { } else {
ide_startstop_t startstop; ide_startstop_t startstop;
if (dma && !hwif->ide_dma_write(drive))
return ide_started;
command = ((drive->mult_count) ? command = ((drive->mult_count) ?
((lba48) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE) : ((lba48) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE) :
((lba48) ? WIN_WRITE_EXT : WIN_WRITE)); ((lba48) ? WIN_WRITE_EXT : WIN_WRITE));
......
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/scatterlist.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -253,18 +254,12 @@ int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq) ...@@ -253,18 +254,12 @@ int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
#else #else
while (sector_count > 128) { while (sector_count > 128) {
#endif #endif
memset(&sg[nents], 0, sizeof(*sg)); sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = offset_in_page(virt_addr);
sg[nents].length = 128 * SECTOR_SIZE;
nents++; nents++;
virt_addr = virt_addr + (128 * SECTOR_SIZE); virt_addr = virt_addr + (128 * SECTOR_SIZE);
sector_count -= 128; sector_count -= 128;
} }
memset(&sg[nents], 0, sizeof(*sg)); sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = offset_in_page(virt_addr);
sg[nents].length = sector_count * SECTOR_SIZE;
nents++; nents++;
return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
...@@ -590,10 +585,8 @@ int __ide_dma_check (ide_drive_t *drive) ...@@ -590,10 +585,8 @@ int __ide_dma_check (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_check); EXPORT_SYMBOL(__ide_dma_check);
/** /**
* ide_start_dma - begin a DMA phase * ide_dma_setup - begin a DMA phase
* @hwif: interface
* @drive: target device * @drive: target device
* @reading: set if reading, clear if writing
* *
* Build an IDE DMA PRD (IDE speak for scatter gather table) * Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers for a device * and then set up the DMA transfer registers for a device
...@@ -604,11 +597,18 @@ EXPORT_SYMBOL(__ide_dma_check); ...@@ -604,11 +597,18 @@ EXPORT_SYMBOL(__ide_dma_check);
* is returned. * 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; struct request *rq = HWGROUP(drive)->rq;
unsigned int reading;
u8 dma_stat; u8 dma_stat;
if (rq_data_dir(rq))
reading = 0;
else
reading = 1 << 3;
/* fall back to pio! */ /* fall back to pio! */
if (!ide_build_dmatable(drive, rq)) if (!ide_build_dmatable(drive, rq))
return 1; return 1;
...@@ -628,73 +628,15 @@ int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading) ...@@ -628,73 +628,15 @@ int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading)
return 0; return 0;
} }
EXPORT_SYMBOL(ide_start_dma); EXPORT_SYMBOL_GPL(ide_dma_setup);
int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
{
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 */) 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 = 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 */ /* issue cmd to drive */
ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); 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); void ide_dma_start(ide_drive_t *drive)
int __ide_dma_begin (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
u8 dma_cmd = hwif->INB(hwif->dma_command); u8 dma_cmd = hwif->INB(hwif->dma_command);
...@@ -708,10 +650,9 @@ int __ide_dma_begin (ide_drive_t *drive) ...@@ -708,10 +650,9 @@ int __ide_dma_begin (ide_drive_t *drive)
hwif->OUTB(dma_cmd|1, hwif->dma_command); hwif->OUTB(dma_cmd|1, hwif->dma_command);
hwif->dma = 1; hwif->dma = 1;
wmb(); wmb();
return 0;
} }
EXPORT_SYMBOL(__ide_dma_begin); EXPORT_SYMBOL_GPL(ide_dma_start);
/* returns 1 on error, 0 otherwise */ /* returns 1 on error, 0 otherwise */
int __ide_dma_end (ide_drive_t *drive) int __ide_dma_end (ide_drive_t *drive)
...@@ -1009,12 +950,12 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p ...@@ -1009,12 +950,12 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
hwif->ide_dma_host_on = &__ide_dma_host_on; hwif->ide_dma_host_on = &__ide_dma_host_on;
if (!hwif->ide_dma_check) if (!hwif->ide_dma_check)
hwif->ide_dma_check = &__ide_dma_check; hwif->ide_dma_check = &__ide_dma_check;
if (!hwif->ide_dma_read) if (!hwif->dma_setup)
hwif->ide_dma_read = &__ide_dma_read; hwif->dma_setup = &ide_dma_setup;
if (!hwif->ide_dma_write) if (!hwif->dma_exec_cmd)
hwif->ide_dma_write = &__ide_dma_write; hwif->dma_exec_cmd = &ide_dma_exec_cmd;
if (!hwif->ide_dma_begin) if (!hwif->dma_start)
hwif->ide_dma_begin = &__ide_dma_begin; hwif->dma_start = &ide_dma_start;
if (!hwif->ide_dma_end) if (!hwif->ide_dma_end)
hwif->ide_dma_end = &__ide_dma_end; hwif->ide_dma_end = &__ide_dma_end;
if (!hwif->ide_dma_test_irq) if (!hwif->ide_dma_test_irq)
......
...@@ -995,6 +995,7 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) ...@@ -995,6 +995,7 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc) static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
atapi_feature_t feature; atapi_feature_t feature;
atapi_bcount_t bcount; atapi_bcount_t bcount;
ide_handler_t *pkt_xfer_routine; ide_handler_t *pkt_xfer_routine;
...@@ -1049,13 +1050,8 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p ...@@ -1049,13 +1050,8 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
} }
feature.all = 0; feature.all = 0;
if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) { if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
if (test_bit(PC_WRITING, &pc->flags)) { feature.b.dma = !hwif->dma_setup(drive);
feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
} else {
feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
}
}
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
...@@ -1067,7 +1063,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p ...@@ -1067,7 +1063,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
if (feature.b.dma) { /* Begin DMA, if necessary */ if (feature.b.dma) { /* Begin DMA, if necessary */
set_bit(PC_DMA_IN_PROGRESS, &pc->flags); 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? */ /* Can we transfer the packet when we get the interrupt or wait? */
......
...@@ -2067,7 +2067,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) ...@@ -2067,7 +2067,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
/* Begin DMA, if necessary */ /* Begin DMA, if necessary */
if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags))
(void) (HWIF(drive)->ide_dma_begin(drive)); hwif->dma_start(drive);
#endif #endif
/* Send the actual packet */ /* Send the actual packet */
HWIF(drive)->atapi_output_bytes(drive, pc->c, 12); HWIF(drive)->atapi_output_bytes(drive, pc->c, 12);
...@@ -2135,12 +2135,8 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape ...@@ -2135,12 +2135,8 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
"reverting to PIO\n"); "reverting to PIO\n");
(void)__ide_dma_off(drive); (void)__ide_dma_off(drive);
} }
if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) { if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
if (test_bit(PC_WRITING, &pc->flags)) dma_ok = !hwif->dma_setup(drive);
dma_ok = !HWIF(drive)->ide_dma_write(drive);
else
dma_ok = !HWIF(drive)->ide_dma_read(drive);
}
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
......
...@@ -150,15 +150,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -150,15 +150,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
case WIN_WRITEDMA_ONCE: case WIN_WRITEDMA_ONCE:
case WIN_WRITEDMA: case WIN_WRITEDMA:
case WIN_WRITEDMA_EXT: case WIN_WRITEDMA_EXT:
if (!hwif->ide_dma_write(drive))
return ide_started;
break;
case WIN_READDMA_ONCE: case WIN_READDMA_ONCE:
case WIN_READDMA: case WIN_READDMA:
case WIN_READDMA_EXT: case WIN_READDMA_EXT:
case WIN_IDENTIFY_DMA: 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; return ide_started;
}
break; break;
default: default:
if (task->handler == NULL) if (task->handler == NULL)
...@@ -517,6 +517,9 @@ int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_ ...@@ -517,6 +517,9 @@ int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_
rq.hard_nr_sectors = rq.nr_sectors; rq.hard_nr_sectors = rq.nr_sectors;
rq.hard_cur_sectors = rq.current_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; rq.special = args;
...@@ -896,12 +899,11 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -896,12 +899,11 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMA: case TASKFILE_OUT_DMA:
hwif->ide_dma_write(drive);
break;
case TASKFILE_IN_DMAQ: case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA: 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; break;
default: default:
......
...@@ -685,9 +685,9 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) ...@@ -685,9 +685,9 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes; hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes;
hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes; hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes;
hwif->ide_dma_read = tmp_hwif->ide_dma_read; hwif->dma_setup = tmp_hwif->dma_setup;
hwif->ide_dma_write = tmp_hwif->ide_dma_write; hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd;
hwif->ide_dma_begin = tmp_hwif->ide_dma_begin; hwif->dma_start = tmp_hwif->dma_start;
hwif->ide_dma_end = tmp_hwif->ide_dma_end; hwif->ide_dma_end = tmp_hwif->ide_dma_end;
hwif->ide_dma_check = tmp_hwif->ide_dma_check; hwif->ide_dma_check = tmp_hwif->ide_dma_check;
hwif->ide_dma_on = tmp_hwif->ide_dma_on; hwif->ide_dma_on = tmp_hwif->ide_dma_on;
......
...@@ -558,18 +558,19 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) ...@@ -558,18 +558,19 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
} }
/** /**
* ali15x3_dma_write - do a DMA IDE write * ali15x3_dma_setup - begin a DMA phase
* @drive: drive to issue write for * @drive: target device
* *
* Returns 1 if the DMA write cannot be performed, zero on * Returns 1 if the DMA cannot be performed, zero on success.
* 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)) if (m5229_revision < 0xC2 && drive->media != ide_disk) {
if (rq_data_dir(drive->hwif->hwgroup->rq))
return 1; /* try PIO instead of DMA */ return 1; /* try PIO instead of DMA */
return __ide_dma_write(drive); }
return ide_dma_setup(drive);
} }
/** /**
...@@ -773,7 +774,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif) ...@@ -773,7 +774,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
* M1543C or newer for DMAing * M1543C or newer for DMAing
*/ */
hwif->ide_dma_check = &ali15x3_config_drive_for_dma; hwif->ide_dma_check = &ali15x3_config_drive_for_dma;
hwif->ide_dma_write = &ali15x3_dma_write; hwif->dma_setup = &ali15x3_dma_setup;
if (!noautodma) if (!noautodma)
hwif->autodma = 1; hwif->autodma = 1;
if (!(hwif->udma_four)) if (!(hwif->udma_four))
......
...@@ -577,7 +577,7 @@ static int hpt366_ide_dma_lostirq (ide_drive_t *drive) ...@@ -577,7 +577,7 @@ static int hpt366_ide_dma_lostirq (ide_drive_t *drive)
/* how about we flush and reset, mmmkay? */ /* how about we flush and reset, mmmkay? */
pci_write_config_byte(dev, 0x51, 0x1F); pci_write_config_byte(dev, 0x51, 0x1F);
/* fall through to a reset */ /* fall through to a reset */
case ide_dma_begin: case dma_start:
case ide_dma_end: case ide_dma_end:
/* reset the chips state over and over.. */ /* reset the chips state over and over.. */
pci_write_config_byte(dev, 0x51, 0x13); pci_write_config_byte(dev, 0x51, 0x13);
...@@ -592,12 +592,12 @@ static void hpt370_clear_engine (ide_drive_t *drive) ...@@ -592,12 +592,12 @@ static void hpt370_clear_engine (ide_drive_t *drive)
udelay(10); 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 #ifdef HPT_RESET_STATE_ENGINE
hpt370_clear_engine(drive); hpt370_clear_engine(drive);
#endif #endif
return __ide_dma_begin(drive); ide_dma_start(drive);
} }
static int hpt370_ide_dma_end (ide_drive_t *drive) static int hpt370_ide_dma_end (ide_drive_t *drive)
...@@ -1230,7 +1230,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) ...@@ -1230,7 +1230,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
hwif->ide_dma_end = &hpt374_ide_dma_end; hwif->ide_dma_end = &hpt374_ide_dma_end;
} else if (hpt_minimum_revision(dev,3)) { } 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_end = &hpt370_ide_dma_end;
hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq; hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;
......
...@@ -101,22 +101,11 @@ static int ns87415_ide_dma_end (ide_drive_t *drive) ...@@ -101,22 +101,11 @@ static int ns87415_ide_dma_end (ide_drive_t *drive)
return (dma_stat & 7) != 4; 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 */ /* select DMA xfer */
ns87415_prepare_drive(drive, 1); ns87415_prepare_drive(drive, 1);
if (!(__ide_dma_read(drive))) if (!ide_dma_setup(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)))
return 0; return 0;
/* DMA failed: select PIO xfer */ /* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0); ns87415_prepare_drive(drive, 0);
...@@ -204,8 +193,7 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif) ...@@ -204,8 +193,7 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
return; return;
hwif->OUTB(0x60, hwif->dma_status); hwif->OUTB(0x60, hwif->dma_status);
hwif->ide_dma_read = &ns87415_ide_dma_read; hwif->dma_setup = &ns87415_ide_dma_setup;
hwif->ide_dma_write = &ns87415_ide_dma_write;
hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_check = &ns87415_ide_dma_check;
hwif->ide_dma_end = &ns87415_ide_dma_end; hwif->ide_dma_end = &ns87415_ide_dma_end;
......
...@@ -494,7 +494,7 @@ static int pdc202xx_quirkproc (ide_drive_t *drive) ...@@ -494,7 +494,7 @@ static int pdc202xx_quirkproc (ide_drive_t *drive)
return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); 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) if (drive->current_speed > XFER_UDMA_2)
pdc_old_enable_66MHz_clock(drive->hwif); pdc_old_enable_66MHz_clock(drive->hwif);
...@@ -515,7 +515,7 @@ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive) ...@@ -515,7 +515,7 @@ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
word_count | 0x06000000; word_count | 0x06000000;
hwif->OUTL(word_count, atapi_reg); 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) static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
...@@ -736,7 +736,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) ...@@ -736,7 +736,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
if (!(hwif->udma_four)) if (!(hwif->udma_four))
hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1; 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_end = &pdc202xx_old_ide_dma_end;
} }
hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq; hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq;
......
...@@ -192,16 +192,13 @@ sgiioc4_clearirq(ide_drive_t * drive) ...@@ -192,16 +192,13 @@ sgiioc4_clearirq(ide_drive_t * drive)
return intr_reg & 3; return intr_reg & 3;
} }
static int static void sgiioc4_ide_dma_start(ide_drive_t * drive)
sgiioc4_ide_dma_begin(ide_drive_t * drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4); unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
unsigned int temp_reg = reg | IOC4_S_DMA_START; unsigned int temp_reg = reg | IOC4_S_DMA_START;
hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4); hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
return 0;
} }
static u32 static u32
...@@ -574,35 +571,30 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) ...@@ -574,35 +571,30 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
return 0; /* revert to PIO for this request */ return 0; /* revert to PIO for this request */
} }
static int static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
sgiioc4_ide_dma_read(ide_drive_t * drive)
{ {
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
unsigned int count = 0; unsigned int count = 0;
int ddir;
if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_FROMDEVICE))) { if (rq_data_dir(rq))
/* try PIO instead of DMA */ ddir = PCI_DMA_TODEVICE;
return 1; else
} ddir = PCI_DMA_FROMDEVICE;
/* 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 (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_TODEVICE))) { if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
/* try PIO instead of DMA */ /* try PIO instead of DMA */
return 1; return 1;
} }
sgiioc4_configure_for_dma(IOC4_DMA_READ, drive); if (rq_data_dir(rq))
/* Writes TO the IOC4 FROM Main Memory */ /* 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; return 0;
} }
...@@ -629,9 +621,8 @@ ide_init_sgiioc4(ide_hwif_t * hwif) ...@@ -629,9 +621,8 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->quirkproc = NULL; hwif->quirkproc = NULL;
hwif->busproc = NULL; hwif->busproc = NULL;
hwif->ide_dma_read = &sgiioc4_ide_dma_read; hwif->dma_setup = &sgiioc4_ide_dma_setup;
hwif->ide_dma_write = &sgiioc4_ide_dma_write; hwif->dma_start = &sgiioc4_ide_dma_start;
hwif->ide_dma_begin = &sgiioc4_ide_dma_begin;
hwif->ide_dma_end = &sgiioc4_ide_dma_end; hwif->ide_dma_end = &sgiioc4_ide_dma_end;
hwif->ide_dma_check = &sgiioc4_ide_dma_check; hwif->ide_dma_check = &sgiioc4_ide_dma_check;
hwif->ide_dma_on = &sgiioc4_ide_dma_on; hwif->ide_dma_on = &sgiioc4_ide_dma_on;
......
...@@ -236,15 +236,13 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) ...@@ -236,15 +236,13 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
* The generic IDE core will have disabled the BMEN bit before this * The generic IDE core will have disabled the BMEN bit before this
* function is called. * 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
// DBG(("sl82c105_ide_dma_begin(drive:%s)\n", drive->name));
sl82c105_reset_host(dev); sl82c105_reset_host(dev);
return __ide_dma_begin(drive); ide_dma_start(drive);
} }
static int sl82c105_ide_dma_timeout(ide_drive_t *drive) static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
...@@ -469,7 +467,7 @@ static void __init init_hwif_sl82c105(ide_hwif_t *hwif) ...@@ -469,7 +467,7 @@ static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->ide_dma_on = &sl82c105_ide_dma_on; hwif->ide_dma_on = &sl82c105_ide_dma_on;
hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; 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; hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
if (!noautodma) if (!noautodma)
......
...@@ -179,64 +179,32 @@ static void trm290_selectproc (ide_drive_t *drive) ...@@ -179,64 +179,32 @@ static void trm290_selectproc (ide_drive_t *drive)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #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); 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 */ if (HWGROUP(drive)->handler != NULL) /* paranoia check */
BUG(); BUG();
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); 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 */ /* issue cmd to drive */
hwif->OUTB(command, IDE_COMMAND_REG); 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); ide_hwif_t *hwif = drive->hwif;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = hwif->hwgroup->rq;
// ide_task_t *args = rq->special; unsigned int count, rw;
task_ioreg_t command = WIN_NOP;
unsigned int count, reading = 2, writing = 0; 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))) { if (!(count = ide_build_dmatable(drive, rq))) {
/* try PIO instead of DMA */ /* try PIO instead of DMA */
...@@ -245,38 +213,15 @@ static int trm290_ide_dma_read (ide_drive_t *drive /*, struct request *rq */) ...@@ -245,38 +213,15 @@ static int trm290_ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
} }
/* select DMA xfer */ /* select DMA xfer */
trm290_prepare_drive(drive, 1); 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; drive->waiting_for_dma = 1;
/* start DMA */ /* start DMA */
hwif->OUTW((count * 2) - 1, hwif->dma_status); hwif->OUTW((count * 2) - 1, hwif->dma_status);
if (drive->media != ide_disk)
return 0; 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);
} }
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) static int trm290_ide_dma_end (ide_drive_t *drive)
...@@ -347,9 +292,9 @@ void __devinit init_hwif_trm290(ide_hwif_t *hwif) ...@@ -347,9 +292,9 @@ void __devinit init_hwif_trm290(ide_hwif_t *hwif)
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_write = &trm290_ide_dma_write; hwif->dma_setup = &trm290_ide_dma_setup;
hwif->ide_dma_read = &trm290_ide_dma_read; hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd;
hwif->ide_dma_begin = &trm290_ide_dma_begin; hwif->dma_start = &trm290_ide_dma_start;
hwif->ide_dma_end = &trm290_ide_dma_end; hwif->ide_dma_end = &trm290_ide_dma_end;
hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif /* CONFIG_BLK_DEV_IDEDMA */
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/adb.h> #include <linux/adb.h>
#include <linux/pmu.h> #include <linux/pmu.h>
#include <linux/scatterlist.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -361,7 +362,6 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, u8 speed); ...@@ -361,7 +362,6 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, u8 speed);
static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio); static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio);
static void pmac_ide_selectproc(ide_drive_t *drive); static void pmac_ide_selectproc(ide_drive_t *drive);
static void pmac_ide_kauai_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 */ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
...@@ -1604,18 +1604,12 @@ pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq) ...@@ -1604,18 +1604,12 @@ pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
if (sector_count > 128) { if (sector_count > 128) {
memset(&sg[nents], 0, sizeof(*sg)); sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = offset_in_page(virt_addr);
sg[nents].length = 128 * SECTOR_SIZE;
nents++; nents++;
virt_addr = virt_addr + (128 * SECTOR_SIZE); virt_addr = virt_addr + (128 * SECTOR_SIZE);
sector_count -= 128; sector_count -= 128;
} }
memset(&sg[nents], 0, sizeof(*sg)); sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = offset_in_page(virt_addr);
sg[nents].length = sector_count * SECTOR_SIZE;
nents++; nents++;
return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction); return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
...@@ -1885,7 +1879,7 @@ pmac_ide_dma_check(ide_drive_t *drive) ...@@ -1885,7 +1879,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/ */
static int __pmac 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); ide_hwif_t *hwif = HWIF(drive);
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
...@@ -1902,7 +1896,7 @@ pmac_ide_dma_start(ide_drive_t *drive, int reading) ...@@ -1902,7 +1896,7 @@ pmac_ide_dma_start(ide_drive_t *drive, int reading)
/* Apple adds 60ns to wrDataSetup on reads */ /* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { 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),
PMAC_IDE_REG(IDE_TIMING_CONFIG)); PMAC_IDE_REG(IDE_TIMING_CONFIG));
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
} }
...@@ -1912,87 +1906,28 @@ pmac_ide_dma_start(ide_drive_t *drive, int reading) ...@@ -1912,87 +1906,28 @@ pmac_ide_dma_start(ide_drive_t *drive, int reading)
return 0; return 0;
} }
/* static void __pmac
* Start a DMA READ command pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 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)
{ {
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 */ /* issue cmd to drive */
ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL); 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 * Kick the DMA controller into life after the DMA command has been issued
* to the drive. * to the drive.
*/ */
static int __pmac static void __pmac
pmac_ide_dma_begin (ide_drive_t *drive) pmac_ide_dma_start(ide_drive_t *drive)
{ {
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
volatile struct dbdma_regs __iomem *dma; volatile struct dbdma_regs __iomem *dma;
if (pmif == NULL)
return 1;
dma = pmif->dma_regs; dma = pmif->dma_regs;
writel((RUN << 16) | RUN, &dma->control); writel((RUN << 16) | RUN, &dma->control);
/* Make sure it gets to the controller right now */ /* Make sure it gets to the controller right now */
(void)readl(&dma->control); (void)readl(&dma->control);
return 0;
} }
/* /*
...@@ -2148,9 +2083,9 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) ...@@ -2148,9 +2083,9 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
hwif->ide_dma_on = &__ide_dma_on; hwif->ide_dma_on = &__ide_dma_on;
hwif->ide_dma_check = &pmac_ide_dma_check; hwif->ide_dma_check = &pmac_ide_dma_check;
hwif->ide_dma_read = &pmac_ide_dma_read; hwif->dma_setup = &pmac_ide_dma_setup;
hwif->ide_dma_write = &pmac_ide_dma_write; hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
hwif->ide_dma_begin = &pmac_ide_dma_begin; hwif->dma_start = &pmac_ide_dma_start;
hwif->ide_dma_end = &pmac_ide_dma_end; hwif->ide_dma_end = &pmac_ide_dma_end;
hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
hwif->ide_dma_host_off = &pmac_ide_dma_host_off; hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
......
...@@ -555,6 +555,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) ...@@ -555,6 +555,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) 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_scsi_t *scsi = drive_to_idescsi(drive);
idescsi_pc_t *pc = scsi->pc; idescsi_pc_t *pc = scsi->pc;
atapi_ireason_t ireason; atapi_ireason_t ireason;
...@@ -579,7 +580,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) ...@@ -579,7 +580,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
atapi_output_bytes(drive, scsi->pc->c, 12); atapi_output_bytes(drive, scsi->pc->c, 12);
if (test_bit (PC_DMA_OK, &pc->flags)) { if (test_bit (PC_DMA_OK, &pc->flags)) {
set_bit (PC_DMA_IN_PROGRESS, &pc->flags); set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
(void) (HWIF(drive)->ide_dma_begin(drive)); hwif->dma_start(drive);
} }
return ide_started; return ide_started;
} }
...@@ -590,6 +591,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) ...@@ -590,6 +591,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
{ {
idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_scsi_t *scsi = drive_to_idescsi(drive);
ide_hwif_t *hwif = drive->hwif;
atapi_feature_t feature; atapi_feature_t feature;
atapi_bcount_t bcount; atapi_bcount_t bcount;
struct request *rq = pc->rq; struct request *rq = pc->rq;
...@@ -600,12 +602,8 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -600,12 +602,8 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
bcount.all = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ bcount.all = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */
feature.all = 0; feature.all = 0;
if (drive->using_dma && rq->bio) { if (drive->using_dma && rq->bio)
if (test_bit(PC_WRITING, &pc->flags)) feature.b.dma = !hwif->dma_setup(drive);
feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
else
feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
}
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
......
...@@ -887,9 +887,9 @@ typedef struct hwif_s { ...@@ -887,9 +887,9 @@ typedef struct hwif_s {
void (*atapi_input_bytes)(ide_drive_t *, void *, u32); void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
void (*atapi_output_bytes)(ide_drive_t *, void *, u32); void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
int (*ide_dma_read)(ide_drive_t *drive); int (*dma_setup)(ide_drive_t *);
int (*ide_dma_write)(ide_drive_t *drive); void (*dma_exec_cmd)(ide_drive_t *, u8);
int (*ide_dma_begin)(ide_drive_t *drive); void (*dma_start)(ide_drive_t *);
int (*ide_dma_end)(ide_drive_t *drive); int (*ide_dma_end)(ide_drive_t *drive);
int (*ide_dma_check)(ide_drive_t *drive); int (*ide_dma_check)(ide_drive_t *drive);
int (*ide_dma_on)(ide_drive_t *drive); int (*ide_dma_on)(ide_drive_t *drive);
...@@ -1544,16 +1544,14 @@ extern void ide_destroy_dmatable(ide_drive_t *); ...@@ -1544,16 +1544,14 @@ extern void ide_destroy_dmatable(ide_drive_t *);
extern ide_startstop_t ide_dma_intr(ide_drive_t *); extern ide_startstop_t ide_dma_intr(ide_drive_t *);
extern int ide_release_dma(ide_hwif_t *); extern int ide_release_dma(ide_hwif_t *);
extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); 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_host_off(ide_drive_t *);
extern int __ide_dma_off_quietly(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_host_on(ide_drive_t *);
extern int __ide_dma_on(ide_drive_t *); extern int __ide_dma_on(ide_drive_t *);
extern int __ide_dma_check(ide_drive_t *); extern int __ide_dma_check(ide_drive_t *);
extern int __ide_dma_read(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *);
extern int __ide_dma_write(ide_drive_t *); extern void ide_dma_start(ide_drive_t *);
extern int __ide_dma_begin(ide_drive_t *);
extern int __ide_dma_end(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *);
extern int __ide_dma_test_irq(ide_drive_t *); extern int __ide_dma_test_irq(ide_drive_t *);
extern int __ide_dma_verbose(ide_drive_t *); extern int __ide_dma_verbose(ide_drive_t *);
......
#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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment