From c7016e95a556098db6dc4d9096a6189be9e18266 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:33 +0100 Subject: ide: remove no longer needed PC_FLAG_TIMEDOUT packet command flag There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 6adc5b4..f44474b 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -336,11 +336,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD : WAIT_TAPE_CMD; - if (pc->flags & PC_FLAG_TIMEDOUT) { - drive->pc_callback(drive, 0); - return ide_stopped; - } - /* Clear the interrupt */ stat = tp_ops->read_status(hwif); -- cgit v1.1 From 03a2faaea8f44edfe583ddf1240948019becfbe4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:36 +0100 Subject: ide: return request status from ->pc_callback method Make ->pc_callback method return request status and then move the request completion from ->pc_callback to ide_pc_intr(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f44474b..f72b5a6 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -357,6 +357,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* No more interrupts */ if ((stat & ATA_DRQ) == 0) { + int uptodate; + debug_log("Packet command completed, %d bytes transferred\n", pc->xferred); @@ -395,7 +397,15 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) dsc = 1; /* Command finished - Call the callback function */ - drive->pc_callback(drive, dsc); + uptodate = drive->pc_callback(drive, dsc); + + if (uptodate == 0) + drive->failed_pc = NULL; + + if (blk_special_request(rq)) + ide_complete_rq(drive, 0); + else + ide_end_request(drive, uptodate, 0); return ide_stopped; } -- cgit v1.1 From e6830a86c260d73c6f370aa7ed17ee6c71e5ee05 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:37 +0100 Subject: ide: call ide_build_sglist() prior to ->dma_setup (v2) * Re-map sg table if needed in ide_build_sglist(). * Move ide_build_sglist() call from ->dma_setup to its users. * Un-export ide_build_sglist(). v2: * Build fix for CONFIG_BLK_DEV_IDEDMA=n (noticed by Randy Dunlap). There should be no functional changes caused by this patch. Cc: Randy Dunlap Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f72b5a6..2b9ac21 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -631,18 +631,23 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; ide_expiry_t *expiry = NULL; + struct request *rq = hwif->rq; unsigned int timeout; u32 tf_flags; u16 bcount; if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; - bcount = ide_cd_get_xferlen(hwif->rq); + bcount = ide_cd_get_xferlen(rq); expiry = ide_cd_expiry; timeout = ATAPI_WAIT_PC; - if (drive->dma) - drive->dma = !hwif->dma_ops->dma_setup(drive); + if (drive->dma) { + if (ide_build_sglist(drive, rq)) + drive->dma = !hwif->dma_ops->dma_setup(drive); + else + drive->dma = 0; + } } else { pc = drive->pc; @@ -661,8 +666,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) } if ((pc->flags & PC_FLAG_DMA_OK) && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) - drive->dma = !hwif->dma_ops->dma_setup(drive); + (drive->dev_flags & IDE_DFLAG_USING_DMA)) { + if (ide_build_sglist(drive, rq)) + drive->dma = !hwif->dma_ops->dma_setup(drive); + else + drive->dma = 0; + } if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; -- cgit v1.1 From 22aa4b32a19b1f231d4ce7e9af6354b577a22a35 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:37 +0100 Subject: ide: remove ide_task_t typedef While at it: - rename struct ide_task_s to struct ide_cmd - remove stale comments from idedisk_{read_native,set}_max_address() - drop unused 'cmd' argument from ide_{cmd,task}_ioctl() - drop unused 'task' argument from tx4939ide_tf_load_fixup() - rename ide_complete_task() to ide_complete_cmd() - use consistent naming for struct ide_cmd variables There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2b9ac21..92c6ef6 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -302,16 +302,16 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) { - ide_task_t task; + struct ide_cmd cmd; - memset(&task, 0, sizeof(task)); - task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | - IDE_TFLAG_IN_NSECT; + memset(&cmd, 0, sizeof(cmd)); + cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &task); + drive->hwif->tp_ops->tf_read(drive, &cmd); - *bcount = (task.tf.lbah << 8) | task.tf.lbam; - *ireason = task.tf.nsect & 3; + *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam; + *ireason = cmd.tf.nsect & 3; } EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); @@ -482,32 +482,32 @@ next_irq: static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) { ide_hwif_t *hwif = drive->hwif; - ide_task_t task; + struct ide_cmd cmd; u8 dma = drive->dma; - memset(&task, 0, sizeof(task)); - task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_FEATURE | tf_flags; - task.tf.feature = dma; /* Use PIO/DMA */ - task.tf.lbam = bcount & 0xff; - task.tf.lbah = (bcount >> 8) & 0xff; + memset(&cmd, 0, sizeof(cmd)); + cmd.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_FEATURE | tf_flags; + cmd.tf.feature = dma; /* Use PIO/DMA */ + cmd.tf.lbam = bcount & 0xff; + cmd.tf.lbah = (bcount >> 8) & 0xff; - ide_tf_dump(drive->name, &task.tf); + ide_tf_dump(drive->name, &cmd.tf); hwif->tp_ops->set_irq(hwif, 1); SELECT_MASK(drive, 0); - hwif->tp_ops->tf_load(drive, &task); + hwif->tp_ops->tf_load(drive, &cmd); } static u8 ide_read_ireason(ide_drive_t *drive) { - ide_task_t task; + struct ide_cmd cmd; - memset(&task, 0, sizeof(task)); - task.tf_flags = IDE_TFLAG_IN_NSECT; + memset(&cmd, 0, sizeof(cmd)); + cmd.tf_flags = IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &task); + drive->hwif->tp_ops->tf_read(drive, &cmd); - return task.tf.nsect & 3; + return cmd.tf.nsect & 3; } static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) -- cgit v1.1 From 6902a5331256e1b9f4cef95a1e3622252113b260 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:43 +0100 Subject: ide: pass error value to ide_complete_rq() Set rq->errors at ide_complete_rq() call sites and then pass error value to ide_complete_rq(). [ Some rq->errors assignments look really wrong but this patch leaves them alone to not introduce too many changes at once. ] There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 92c6ef6..5d57af2 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -402,9 +402,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (uptodate == 0) drive->failed_pc = NULL; - if (blk_special_request(rq)) + if (blk_special_request(rq)) { + rq->errors = 0; ide_complete_rq(drive, 0); - else + } else ide_end_request(drive, uptodate, 0); return ide_stopped; -- cgit v1.1 From 89f78b3261f7e331e41753ea2459fbb9b60a6f7a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:43 +0100 Subject: ide: move rq->errors quirk out from ide_end_request() Move rq->errors quirk out from ide_end_request() to its call sites. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 5d57af2..5504a84 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -405,8 +405,13 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (blk_special_request(rq)) { rq->errors = 0; ide_complete_rq(drive, 0); - } else + } else { + if (blk_fs_request(rq) == 0 && uptodate <= 0) { + if (rq->errors == 0) + rq->errors = -EIO; + } ide_end_request(drive, uptodate, 0); + } return ide_stopped; } -- cgit v1.1 From f974b196f58fe042c7b2b4c0ee15d5a6112dbf40 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:44 +0100 Subject: ide: pass number of bytes to complete to ide_complete_rq() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 5504a84..30156aa 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -404,7 +404,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (blk_special_request(rq)) { rq->errors = 0; - ide_complete_rq(drive, 0); + ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } else { if (blk_fs_request(rq) == 0 && uptodate <= 0) { if (rq->errors == 0) -- cgit v1.1 From 130e886708d6e11f3d54e5d27c266578de56f343 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:45 +0100 Subject: ide: remove ide_end_request() * Add ide_rq_bytes() helper. * Add blk_noretry_request() quirk to ide_complete_rq() (currently only fs requests can be marked as "noretry" so there is no change in behavior). * Switch current ide_end_request() users to use ide_complete_rq(). [ No need to check for rq->nr_sectors == 0 in {ide_dma,task_pio}_intr(), nsectors == 0 in cdrom_end_request() and err == 0 in ide_do_devset(). ] * Remove no longer needed ide_end_request(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 30156aa..c3fd528 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -410,7 +410,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (rq->errors == 0) rq->errors = -EIO; } - ide_end_request(drive, uptodate, 0); + ide_complete_rq(drive, uptodate ? 0 : -EIO, + ide_rq_bytes(rq)); } return ide_stopped; @@ -469,7 +470,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* FIXME: don't do partial completions */ if (drive->media == ide_floppy) - ide_end_request(drive, 1, done >> 9); + ide_complete_rq(drive, 0, + done ? done : ide_rq_bytes(rq)); } else xferfunc(drive, NULL, pc->cur_pos, bcount); -- cgit v1.1 From 2298169418f43ba5e0919762a4bab95a1227872a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:46 +0100 Subject: ide: pass command to ide_map_sg() * 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 Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c3fd528..b56af49 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -638,12 +638,20 @@ 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); @@ -651,8 +659,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) 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; } @@ -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; } -- cgit v1.1 From b788ee9c6561fd9219a503216284d61036a0dc0b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:46 +0100 Subject: ide: use do_rw_taskfile() for ATA_CMD_PACKET commands * Pass command to ide_issue_pc() and update ->do_request methods in ide-{cd,floppy,tape}.c accordingly. * Convert ide_pktcmd_tf_load() to ide_init_packet_cmd() which just initializes command structure and use do_rw_taskfile() to load ATA_CMD_PACKET commands. While at it: * Rename ide{floppy,tape}_issue_pc() to ide_{floppy,tape}_issue_pc(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index b56af49..75df05a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -487,23 +487,15 @@ next_irq: return ide_started; } -static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) +static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, + u16 bcount, u8 dma) { - ide_hwif_t *hwif = drive->hwif; - struct ide_cmd cmd; - u8 dma = drive->dma; - - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_FEATURE | tf_flags; - cmd.tf.feature = dma; /* Use PIO/DMA */ - cmd.tf.lbam = bcount & 0xff; - cmd.tf.lbah = (bcount >> 8) & 0xff; - - ide_tf_dump(drive->name, &cmd.tf); - hwif->tp_ops->set_irq(hwif, 1); - SELECT_MASK(drive, 0); - hwif->tp_ops->tf_load(drive, &cmd); + cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; + cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_FEATURE | tf_flags; + cmd->tf.feature = dma; /* Use PIO/DMA */ + cmd->tf.lbam = bcount & 0xff; + cmd->tf.lbah = (bcount >> 8) & 0xff; } static u8 ide_read_ireason(ide_drive_t *drive) @@ -634,24 +626,17 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive) +ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) { 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); @@ -696,7 +681,9 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) : WAIT_TAPE_CMD; } - ide_pktcmd_tf_load(drive, tf_flags, bcount); + ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma); + + (void)do_rw_taskfile(drive, cmd); /* Issue the packet command */ if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { -- cgit v1.1 From 60c0cd02b254805691cdc61101ada6af7bd56fde Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:46 +0100 Subject: ide: set hwif->expiry prior to calling [__]ide_set_handler() * Set hwif->expiry prior to calling [__]ide_set_handler() and drop 'expiry' argument. * Set hwif->expiry to NULL in ide_{timer_expiry,intr}() and remove 'hwif->expiry = NULL' assignments. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 75df05a..f1b1b71 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -483,7 +483,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->cmd[0], bcount); next_irq: /* And set the interrupt handler again */ - ide_set_handler(drive, ide_pc_intr, timeout, NULL); + ide_set_handler(drive, ide_pc_intr, timeout); return ide_started; } @@ -602,11 +602,13 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } } + hwif->expiry = expiry; + /* Set the interrupt routine */ ide_set_handler(drive, (dev_is_idecd(drive) ? drive->irq_handler : ide_pc_intr), - timeout, expiry); + timeout); /* Begin DMA, if necessary */ if (dev_is_idecd(drive)) { -- cgit v1.1 From 22117d6eaac50d366d9013c88318a869ea4d8739 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:47 +0100 Subject: ide: add ->dma_timer_expiry method and remove ->dma_exec_cmd one (v2) * Rename dma_timer_expiry() to ide_dma_sff_timer_expiry() and export it. * Add ->dma_timer_expiry method and use it to set hwif->expiry for ATA_PROT_DMA protocol in do_rw_taskfile(). * Initialize ->dma_timer_expiry to ide_dma_sff_timer_expiry() for SFF hosts. * Move setting hwif->expiry from ide_execute_command() to its users and drop 'expiry' argument. * Use ide_execute_command() instead of ->dma_exec_cmd in do_rw_taskfile(). * Remove ->dma_exec_cmd method and its implementations. * Unexport ide_execute_command() and ide_dma_intr(). v2: * Fix CONFIG_BLK_DEV_IDEDMA=n build (noticed by Randy Dunlap). * Fix *dma_expiry naming (suggested by Sergei Shtylyov). There should be no functional changes caused by this patch. Cc: Randy Dunlap Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f1b1b71..f7fe1de 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -691,8 +691,9 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { if (drive->dma) drive->waiting_for_dma = 0; + hwif->expiry = expiry; ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, - timeout, expiry); + timeout); return ide_started; } else { ide_execute_pkt_cmd(drive); -- cgit v1.1 From 35b5d0be3d8de9a5ac51471c12029fb115200cdc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 27 Mar 2009 12:46:47 +0100 Subject: ide: remove ide_execute_pkt_cmd() (v2) * Pass command structure to ide_execute_command() and skip __ide_set_handler() for ATAPI protocols on non-DRQ devices. * Convert ide_issue_pc() to always use ide_execute_command() and remove no longer needed ide_execute_pkt_cmd(). v2: * Fix for non-DRQ devices (based on report from Borislav). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f7fe1de..2fb5d28 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -493,6 +493,7 @@ static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | IDE_TFLAG_OUT_FEATURE | tf_flags; + cmd->tf.command = ATA_CMD_PACKET; cmd->tf.feature = dma; /* Use PIO/DMA */ cmd->tf.lbam = bcount & 0xff; cmd->tf.lbah = (bcount >> 8) & 0xff; @@ -638,6 +639,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) unsigned int timeout; u32 tf_flags; u16 bcount; + u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; @@ -687,17 +689,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) (void)do_rw_taskfile(drive, cmd); - /* Issue the packet command */ - if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { + if (drq_int) { if (drive->dma) drive->waiting_for_dma = 0; hwif->expiry = expiry; - ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, - timeout); - return ide_started; - } else { - ide_execute_pkt_cmd(drive); - return ide_transfer_pc(drive); } + + ide_execute_command(drive, cmd, ide_transfer_pc, timeout); + + return drq_int ? ide_started : ide_transfer_pc(drive); } EXPORT_SYMBOL_GPL(ide_issue_pc); -- cgit v1.1 From 479edf065576aeed7ac99d10838bb3b4f870b5f9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 Mar 2009 20:14:57 +0200 Subject: ide: drivers/ide/ide-atapi.c needs On m68k: | drivers/ide/ide-atapi.c: In function 'ide_io_buffers': | drivers/ide/ide-atapi.c:87: error: implicit declaration of function 'sg_page' | drivers/ide/ide-atapi.c:87: warning: passing argument 1 of 'PageHighMem' makes pointer from integer without a cast | drivers/ide/ide-atapi.c:91: warning: passing argument 1 of 'kmap_atomic' makes pointer from integer without a cast | drivers/ide/ide-atapi.c:96: error: implicit declaration of function 'sg_virt' | drivers/ide/ide-atapi.c:96: warning: assignment makes pointer from integer without a cast | drivers/ide/ide-atapi.c:107: error: implicit declaration of function 'sg_next' | drivers/ide/ide-atapi.c:107: warning: assignment makes pointer from integer without a cast [bart: Dmitri Vorobiev submitted similar patch fixing MIPS] Signed-off-by: Geert Uytterhoeven Cc: Dmitri Vorobiev Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2fb5d28..d937e45 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -6,6 +6,8 @@ #include #include #include +#include + #include #ifdef DEBUG -- cgit v1.1 From 2eba08270990b99fb5429b76ee97184ddd272f7f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 31 Mar 2009 20:14:58 +0200 Subject: ide-atapi: start DMA after issuing a packet command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently¹, some ATAPI devices want to see the packet command first before enabling DMA otherwise they simply hang indefinitely. Reorder the two steps and start DMA only after having issued the command first. [1] http://marc.info/?l=linux-kernel&m=123835520317235&w=2 Signed-off-by: Borislav Petkov Reported-by: Michael Roth Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index d937e45..f591166 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -613,6 +613,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) : ide_pc_intr), timeout); + /* Send the actual packet */ + if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) + hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); + /* Begin DMA, if necessary */ if (dev_is_idecd(drive)) { if (drive->dma) @@ -624,10 +628,6 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } } - /* Send the actual packet */ - if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) - hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); - return ide_started; } -- cgit v1.1 From 4453011f959a5f5c6c7a33aea54fe17f5e43a867 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:20 +0200 Subject: ide: destroy DMA mappings after ending DMA (v2) Move ide_destroy_dmatable() call out from ->dma_end method to {ide_pc,cdrom_newpc,ide_dma}_intr(), ide_dma_timeout_retry() and sgiioc4_resetproc(). This causes minor/safe behavior changes w.r.t.: * cmd64x.c::cmd64{8,x}_dma_end() * cs5536.c::cs5536_dma_end() * icside.c::icside_dma_end() * it821x.c::it821x_dma_end() * scc_pata.c::__scc_dma_end() * sl82c105.c::sl82c105_dma_end() * tx4939ide.c::tx4939ide_dma_end() v2: * Fix build for CONFIG_BLK_DEV_IDEDMA=n (reported by Randy Dunlap). Cc: Randy Dunlap Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f591166..1481f71f 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -342,8 +342,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) stat = tp_ops->read_status(hwif); if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - if (hwif->dma_ops->dma_end(drive) || - (drive->media == ide_tape && (stat & ATA_ERR))) { + int rc = hwif->dma_ops->dma_end(drive); + + ide_destroy_dmatable(drive); + + if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { if (drive->media == ide_floppy) printk(KERN_ERR "%s: DMA %s error\n", drive->name, rq_data_dir(pc->rq) -- cgit v1.1 From 5ae5412d9a23b05ab08461b202bad21ad8f6b66d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:20 +0200 Subject: ide: add ide_dma_prepare() helper * Add ide_dma_prepare() helper. * Convert ide_issue_pc() and do_rw_taskfile() to use it. * Make ide_build_sglist() static. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 1481f71f..89d2339 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -638,7 +638,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) { struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; - const struct ide_dma_ops *dma_ops = hwif->dma_ops; ide_expiry_t *expiry = NULL; struct request *rq = hwif->rq; unsigned int timeout; @@ -652,12 +651,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) expiry = ide_cd_expiry; timeout = ATAPI_WAIT_PC; - if (drive->dma) { - if (ide_build_sglist(drive, cmd)) - drive->dma = !dma_ops->dma_setup(drive, cmd); - else - drive->dma = 0; - } + if (drive->dma) + drive->dma = !ide_dma_prepare(drive, cmd); } else { pc = drive->pc; @@ -675,13 +670,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) ide_dma_off(drive); } - if ((pc->flags & PC_FLAG_DMA_OK) && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) { - if (ide_build_sglist(drive, cmd)) - drive->dma = !dma_ops->dma_setup(drive, cmd); - else - drive->dma = 0; - } + if (pc->flags & PC_FLAG_DMA_OK) + drive->dma = !ide_dma_prepare(drive, cmd); if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; -- cgit v1.1 From 88b4132e101e60e8fa67996ae3072ab6b71e8500 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:22 +0200 Subject: ide: set/clear drive->waiting_for_dma flag in the core code Set/clear drive->waiting_for_dma flag in the core code instead of in ->dma_setup and ->dma_end methods. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 89d2339..db6e617 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -342,8 +342,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) stat = tp_ops->read_status(hwif); if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - int rc = hwif->dma_ops->dma_end(drive); + int rc; + drive->waiting_for_dma = 0; + rc = hwif->dma_ops->dma_end(drive); ide_destroy_dmatable(drive); if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { -- cgit v1.1 From f094d4d83bccee9277ddb6aadccf35747889426b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:24 +0200 Subject: ide: sanitize ide_build_sglist() and ide_destroy_dmatable() * Move ide_map_sg() calls out from ide_build_sglist() to ide_dma_prepare(). * Pass command to ide_destroy_dmatable(). * Rename ide_build_sglist() to ide_dma_map_sg() and ide_destroy_dmatable() to ide_dma_unmap_sg(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index db6e617..3f3fc7c 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -326,6 +326,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) { struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; + struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; @@ -346,7 +347,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) drive->waiting_for_dma = 0; rc = hwif->dma_ops->dma_end(drive); - ide_destroy_dmatable(drive); + ide_dma_unmap_sg(drive, cmd); if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { if (drive->media == ide_floppy) -- cgit v1.1 From d93bc4521c80e9d87767779814e88f6d725453d7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:26 +0200 Subject: ide-{floppy,tape}: fix padding for PIO transfers * Return number of bytes left to transfer from idetape_{in,out}put_buffers() and number of bytes done from ide_tape_io_buffers(). * Fix padding for PIO transfers in ide_pc_intr() so read/write buffers are always completely processed and then the transfer is padded if necessary. * Remove invalid error messages. * Remove now superfluous padding from ide{_io_buffers,tape_input_buffers}(). While at it: * Set pc->bh to NULL in idetape_input_buffers() after all bh-s are done. * Cache !!(pc->flags & PC_FLAG_WRITING) in local variable in ide_pc_intr(). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 57 +++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 3f3fc7c..40f413b 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -110,13 +110,6 @@ int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, } } - if (bcount) { - printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name, - bcount, write ? "padding with zeros" - : "discarding data"); - ide_pad_transfer(drive, write, bcount); - } - return done; } EXPORT_SYMBOL_GPL(ide_io_buffers); @@ -330,9 +323,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) struct request *rq = hwif->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; - unsigned int timeout, temp; + unsigned int timeout, done; u16 bcount; u8 stat, ireason, dsc = 0; + u8 write = !!(pc->flags & PC_FLAG_WRITING); debug_log("Enter %s - interrupt handler\n", __func__); @@ -441,8 +435,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - if (((ireason & ATAPI_IO) == ATAPI_IO) == - !!(pc->flags & PC_FLAG_WRITING)) { + if (((ireason & ATAPI_IO) == ATAPI_IO) == write) { /* Hopefully, we will never get here */ printk(KERN_ERR "%s: We wanted to %s, but the device wants us " "to %s!\n", drive->name, @@ -451,45 +444,33 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - if (!(pc->flags & PC_FLAG_WRITING)) { - /* Reading - Check that we have enough space */ - temp = pc->xferred + bcount; - if (temp > pc->req_xfer) { - if (temp > pc->buf_size) { - printk(KERN_ERR "%s: The device wants to send " - "us more data than expected - " - "discarding data\n", - drive->name); - - ide_pad_transfer(drive, 0, bcount); - goto next_irq; - } - debug_log("The device wants to send us more data than " - "expected - allowing transfer\n"); - } - xferfunc = tp_ops->input_data; - } else - xferfunc = tp_ops->output_data; + xferfunc = write ? tp_ops->output_data : tp_ops->input_data; if ((drive->media == ide_floppy && !pc->buf) || (drive->media == ide_tape && pc->bh)) { - int done = drive->pc_io_buffers(drive, pc, bcount, - !!(pc->flags & PC_FLAG_WRITING)); + done = drive->pc_io_buffers(drive, pc, bcount, write); /* FIXME: don't do partial completions */ if (drive->media == ide_floppy) ide_complete_rq(drive, 0, done ? done : ide_rq_bytes(rq)); - } else - xferfunc(drive, NULL, pc->cur_pos, bcount); + } else { + done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); + xferfunc(drive, NULL, pc->cur_pos, done); + } /* Update the current position */ - pc->xferred += bcount; - pc->cur_pos += bcount; + pc->xferred += done; + pc->cur_pos += done; + + bcount -= done; + + if (bcount) + ide_pad_transfer(drive, write, bcount); + + debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n", + rq->cmd[0], done, bcount); - debug_log("[cmd %x] transferred %d bytes on that intr.\n", - rq->cmd[0], bcount); -next_irq: /* And set the interrupt handler again */ ide_set_handler(drive, ide_pc_intr, timeout); return ide_started; -- cgit v1.1 From 349d12a1fe57d49287a539909cf14f362634342d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Mar 2009 20:15:26 +0200 Subject: ide-floppy: use ide_pio_bytes() * Fix ide_init_sg_cmd() setup for non-fs requests. * Convert ide_pc_intr() to use ide_pio_bytes() for floppy media. * Remove no longer needed ide_io_buffers() and sg/sg_cnt fields from struct ide_atapi_pc. * Remove partial completions; kill idefloppy_update_buffers(), as a result. * Add some more debugging statements. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 68 ++++++++++++------------------------------------- 1 file changed, 16 insertions(+), 52 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 40f413b..100e6f9 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -71,49 +71,6 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s) } EXPORT_SYMBOL_GPL(ide_check_atapi_device); -/* PIO data transfer routine using the scatter gather table. */ -int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount, int write) -{ - ide_hwif_t *hwif = drive->hwif; - const struct ide_tp_ops *tp_ops = hwif->tp_ops; - xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data; - struct scatterlist *sg = pc->sg; - char *buf; - int count, done = 0; - - while (bcount) { - count = min(sg->length - pc->b_count, bcount); - - if (PageHighMem(sg_page(sg))) { - unsigned long flags; - - local_irq_save(flags); - buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; - xf(drive, NULL, buf + pc->b_count, count); - kunmap_atomic(buf - sg->offset, KM_IRQ0); - local_irq_restore(flags); - } else { - buf = sg_virt(sg); - xf(drive, NULL, buf + pc->b_count, count); - } - - bcount -= count; - pc->b_count += count; - done += count; - - if (pc->b_count == sg->length) { - if (!--pc->sg_cnt) - break; - pc->sg = sg = sg_next(sg); - pc->b_count = 0; - } - } - - return done; -} -EXPORT_SYMBOL_GPL(ide_io_buffers); - void ide_init_pc(struct ide_atapi_pc *pc) { memset(pc, 0, sizeof(*pc)); @@ -353,6 +310,9 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) pc->xferred = pc->req_xfer; if (drive->pc_update_buffers) drive->pc_update_buffers(drive, pc); + + if (drive->media == ide_floppy) + ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } debug_log("%s: DMA finished\n", drive->name); } @@ -408,12 +368,19 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->errors = 0; ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } else { + unsigned int done; + if (blk_fs_request(rq) == 0 && uptodate <= 0) { if (rq->errors == 0) rq->errors = -EIO; } - ide_complete_rq(drive, uptodate ? 0 : -EIO, - ide_rq_bytes(rq)); + + if (drive->media == ide_tape) + done = ide_rq_bytes(rq); /* FIXME */ + else + done = blk_rq_bytes(rq); + + ide_complete_rq(drive, uptodate ? 0 : -EIO, done); } return ide_stopped; @@ -446,14 +413,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) xferfunc = write ? tp_ops->output_data : tp_ops->input_data; - if ((drive->media == ide_floppy && !pc->buf) || - (drive->media == ide_tape && pc->bh)) { + if (drive->media == ide_floppy && pc->buf == NULL) { + done = min_t(unsigned int, bcount, cmd->nleft); + ide_pio_bytes(drive, cmd, write, done); + } else if (drive->media == ide_tape && pc->bh) { done = drive->pc_io_buffers(drive, pc, bcount, write); - - /* FIXME: don't do partial completions */ - if (drive->media == ide_floppy) - ide_complete_rq(drive, 0, - done ? done : ide_rq_bytes(rq)); } else { done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); xferfunc(drive, NULL, pc->cur_pos, done); -- cgit v1.1 From 5b6c942dd1f13835eff8105ec2aa859544a1498d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 31 Mar 2009 20:15:34 +0200 Subject: ide-floppy: do not complete rq's prematurely ... and access them afterwards. Simplify rq completing code while at it. Spotted-by: Tejun Heo Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/ide/ide-atapi.c') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 100e6f9..3e43b88 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -310,16 +310,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) pc->xferred = pc->req_xfer; if (drive->pc_update_buffers) drive->pc_update_buffers(drive, pc); - - if (drive->media == ide_floppy) - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } debug_log("%s: DMA finished\n", drive->name); } /* No more interrupts */ if ((stat & ATA_DRQ) == 0) { - int uptodate; + int uptodate, error; + unsigned int done; debug_log("Packet command completed, %d bytes transferred\n", pc->xferred); @@ -366,9 +364,9 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (blk_special_request(rq)) { rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); + done = blk_rq_bytes(rq); + error = 0; } else { - unsigned int done; if (blk_fs_request(rq) == 0 && uptodate <= 0) { if (rq->errors == 0) @@ -380,9 +378,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) else done = blk_rq_bytes(rq); - ide_complete_rq(drive, uptodate ? 0 : -EIO, done); + error = uptodate ? 0 : -EIO; } + ide_complete_rq(drive, error, done); return ide_stopped; } -- cgit v1.1