Skip to content

Commit

Permalink
ide: pass command to ide_map_sg()
Browse files Browse the repository at this point in the history
* Set IDE_TFLAG_WRITE flag and ->rq also for ATA_CMD_PACKET
  commands.

* Pass command to ->dma_setup method and update all its
  implementations accordingly.

* Pass command instead of request to ide_build_sglist(),
  *_build_dmatable() and ide_map_sg().

While at it:

* Fix scc_dma_setup() documentation + use ATA_DMA_WR define.

* Rename sgiioc4_build_dma_table() to sgiioc4_build_dmatable(),
  change return value type to 'int' and drop unused 'ddir'
  argument.

* Do some minor cleanups in [tx4939]ide_dma_setup().

There should be no functional changes caused by this patch.

Acked-by: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Mar 27, 2009
1 parent 130e886 commit 2298169
Show file tree
Hide file tree
Showing 17 changed files with 101 additions and 114 deletions.
7 changes: 4 additions & 3 deletions drivers/ide/alim15x3.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,18 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
/**
* ali15x3_dma_setup - begin a DMA phase
* @drive: target device
* @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/

static int ali15x3_dma_setup(ide_drive_t *drive)
static int ali15x3_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
if (rq_data_dir(drive->hwif->rq))
if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
return ide_dma_setup(drive);
return ide_dma_setup(drive, cmd);
}

/**
Expand Down
15 changes: 6 additions & 9 deletions drivers/ide/au1xxx-ide.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,14 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
*/

#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int auide_build_dmatable(ide_drive_t *drive)
static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->rq;
_auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
int i = hwif->cmd.sg_nents, iswrite, count = 0;
int i = cmd->sg_nents, count = 0;
int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);

iswrite = (rq_data_dir(rq) == WRITE);
/* Save for interrupt context */
ahwif->drive = drive;

Expand Down Expand Up @@ -298,12 +297,10 @@ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
(2*WAIT_CMD), NULL);
}

static int auide_dma_setup(ide_drive_t *drive)
static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct request *rq = drive->hwif->rq;

if (!auide_build_dmatable(drive)) {
ide_map_sg(drive, rq);
if (auide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
return 1;
}

Expand Down
7 changes: 3 additions & 4 deletions drivers/ide/icside.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,14 @@ static void icside_dma_start(ide_drive_t *drive)
enable_dma(ec->dma);
}

static int icside_dma_setup(ide_drive_t *drive)
static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
struct request *rq = hwif->rq;
unsigned int dma_mode;

if (rq_data_dir(rq))
if (cmd->tf_flags & IDE_TFLAG_WRITE)
dma_mode = DMA_MODE_WRITE;
else
dma_mode = DMA_MODE_READ;
Expand Down Expand Up @@ -344,7 +343,7 @@ static int icside_dma_setup(ide_drive_t *drive)
* Tell the DMA engine about the SG table and
* data direction.
*/
set_dma_sg(ec->dma, hwif->sg_table, hwif->cmd.sg_nents);
set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);

drive->waiting_for_dma = 1;
Expand Down
16 changes: 12 additions & 4 deletions drivers/ide/ide-atapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,21 +638,29 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
struct ide_cmd *cmd = &hwif->cmd;
ide_expiry_t *expiry = NULL;
struct request *rq = hwif->rq;
unsigned int timeout;
u32 tf_flags;
u16 bcount;

if (drive->media != ide_floppy) {
if (rq_data_dir(rq))
cmd->tf_flags |= IDE_TFLAG_WRITE;
cmd->rq = rq;
}

if (dev_is_idecd(drive)) {
tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
bcount = ide_cd_get_xferlen(rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;

if (drive->dma) {
if (ide_build_sglist(drive, rq))
drive->dma = !hwif->dma_ops->dma_setup(drive);
if (ide_build_sglist(drive, cmd))
drive->dma = !dma_ops->dma_setup(drive, cmd);
else
drive->dma = 0;
}
Expand All @@ -675,8 +683,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)

if ((pc->flags & PC_FLAG_DMA_OK) &&
(drive->dev_flags & IDE_DFLAG_USING_DMA)) {
if (ide_build_sglist(drive, rq))
drive->dma = !hwif->dma_ops->dma_setup(drive);
if (ide_build_sglist(drive, cmd))
drive->dma = !dma_ops->dma_setup(drive, cmd);
else
drive->dma = 0;
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/ide/ide-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,6 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
memset(&cmd, 0, sizeof(cmd));
cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;

if (dma == 0) {
ide_init_sg_cmd(&cmd, nsectors);
ide_map_sg(drive, rq);
}

if (drive->dev_flags & IDE_DFLAG_LBA) {
if (lba48) {
pr_debug("%s: LBA=0x%012llx\n", drive->name,
Expand Down Expand Up @@ -156,6 +151,11 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
ide_tf_set_cmd(drive, &cmd, dma);
cmd.rq = rq;

if (dma == 0) {
ide_init_sg_cmd(&cmd, nsectors);
ide_map_sg(drive, &cmd);
}

rc = do_rw_taskfile(drive, &cmd);

if (rc == ide_stopped && dma) {
Expand Down
18 changes: 9 additions & 9 deletions drivers/ide/ide-dma-sff.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
* May also be invoked from trm290.c
*/

int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
__le32 *table = (__le32 *)hwif->dmatable_cpu;
Expand All @@ -120,7 +120,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
struct scatterlist *sg;
u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);

for_each_sg(hwif->sg_table, sg, hwif->cmd.sg_nents, i) {
for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, xcount, bcount;

cur_addr = sg_dma_address(sg);
Expand Down Expand Up @@ -175,6 +175,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
/**
* ide_dma_setup - begin a DMA phase
* @drive: target device
* @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers for a device
Expand All @@ -185,17 +186,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
* is returned.
*/

int ide_dma_setup(ide_drive_t *drive)
int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->rq;
unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;

/* fall back to pio! */
if (!ide_build_dmatable(drive, rq)) {
ide_map_sg(drive, rq);
if (ide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
return 1;
}

Expand All @@ -208,9 +208,9 @@ int ide_dma_setup(ide_drive_t *drive)

/* specify r/w */
if (mmio)
writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
else
outb(reading, hwif->dma_base + ATA_DMA_CMD);
outb(rw, hwif->dma_base + ATA_DMA_CMD);

/* read DMA status for INTR & ERROR flags */
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
Expand Down
15 changes: 7 additions & 8 deletions drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,31 +120,30 @@ int ide_dma_good_drive(ide_drive_t *drive)
/**
* ide_build_sglist - map IDE scatter gather for DMA I/O
* @drive: the drive to build the DMA table for
* @rq: the request holding the sg list
* @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
* target buffers of a request via DMA. The lower layers of the
* kernel provide the necessary cache management so that we can
* operate in a portable fashion.
*/

int ide_build_sglist(ide_drive_t *drive, struct request *rq)
int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
struct ide_cmd *cmd = &hwif->cmd;
int i;

ide_map_sg(drive, rq);
ide_map_sg(drive, cmd);

if (rq_data_dir(rq) == READ)
cmd->sg_dma_direction = DMA_FROM_DEVICE;
else
if (cmd->tf_flags & IDE_TFLAG_WRITE)
cmd->sg_dma_direction = DMA_TO_DEVICE;
else
cmd->sg_dma_direction = DMA_FROM_DEVICE;

i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
if (i == 0)
ide_map_sg(drive, rq);
ide_map_sg(drive, cmd);
else {
cmd->orig_sg_nents = cmd->sg_nents;
cmd->sg_nents = i;
Expand Down
6 changes: 5 additions & 1 deletion drivers/ide/ide-floppy.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,13 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
goto out_end;
}

if (rq_data_dir(rq))
cmd->tf_flags |= IDE_TFLAG_WRITE;
cmd->rq = rq;

if (blk_fs_request(rq) || pc->req_xfer) {
ide_init_sg_cmd(cmd, rq->nr_sectors);
ide_map_sg(drive, rq);
ide_map_sg(drive, cmd);
}

pc->sg = hwif->sg_table;
Expand Down
6 changes: 3 additions & 3 deletions drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ static ide_startstop_t do_special (ide_drive_t *drive)
return ide_stopped;
}

void ide_map_sg(ide_drive_t *drive, struct request *rq)
void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
struct scatterlist *sg = hwif->sg_table;
struct request *rq = cmd->rq;

if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
Expand Down Expand Up @@ -273,7 +273,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
if (cmd) {
if (cmd->protocol == ATA_PROT_PIO) {
ide_init_sg_cmd(cmd, rq->nr_sectors);
ide_map_sg(drive, rq);
ide_map_sg(drive, cmd);
}

return do_rw_taskfile(drive, cmd);
Expand Down
4 changes: 2 additions & 2 deletions drivers/ide/ide-taskfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
return ide_started;
default:
if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
ide_build_sglist(drive, hwif->rq) == 0 ||
dma_ops->dma_setup(drive))
ide_build_sglist(drive, cmd) == 0 ||
dma_ops->dma_setup(drive, cmd))
return ide_stopped;
dma_ops->dma_exec_cmd(drive, tf->command);
dma_ops->dma_start(drive);
Expand Down
4 changes: 2 additions & 2 deletions drivers/ide/ns87415.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
return (dma_stat & 7) != 4;
}

static int ns87415_dma_setup(ide_drive_t *drive)
static int ns87415_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
/* select DMA xfer */
ns87415_prepare_drive(drive, 1);
if (!ide_dma_setup(drive))
if (ide_dma_setup(drive, cmd) == 0)
return 0;
/* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
Expand Down
19 changes: 8 additions & 11 deletions drivers/ide/pmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)

static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
static void pmac_ide_selectproc(ide_drive_t *drive);
static void pmac_ide_kauai_selectproc(ide_drive_t *drive);

Expand Down Expand Up @@ -1422,17 +1421,16 @@ int __init pmac_ide_probe(void)
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
static int
pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct dbdma_cmd *table;
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
int wr = (rq_data_dir(rq) == WRITE);
int i = hwif->cmd.sg_nents, count = 0;
int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
int i = cmd->sg_nents, count = 0;

/* DMA table is already aligned */
table = (struct dbdma_cmd *) pmif->dma_table_cpu;
Expand Down Expand Up @@ -1504,23 +1502,22 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
static int
pmac_ide_dma_setup(ide_drive_t *drive)
static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct request *rq = hwif->rq;
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);

if (!pmac_ide_build_dmatable(drive, rq)) {
ide_map_sg(drive, rq);
if (pmac_ide_build_dmatable(drive, cmd) == 0) {
ide_map_sg(drive, cmd);
return 1;
}

/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
PMAC_IDE_REG(IDE_TIMING_CONFIG));
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
Expand Down
Loading

0 comments on commit 2298169

Please sign in to comment.