lkml.org 
[lkml]   [2003]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] 2.5.67-ac1 IDE - fix Taskfile IOCTLs

    tf-ioctls-2.diff:

    # Taskfile and flagged Taskfile PIO handlers unification [1/2].
    # Incremental to tf-ioctls-1 patch.
    #
    # Detailed changelog:
    # - add request validity checking present in flagged PIO handlers
    # to execute_drive_cmd(), so we now check also not flagged Taskfile
    # and we abort bad requests early
    # - add flagged_wait_drive_ready() for wating for non-busy drive status
    # - add check for DATA_READY to task_out_intr() and task_mulout_intr()
    #
    # Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>

    diff -uNr linux-2.5.67-ac1-tf1/drivers/ide/ide-io.c linux/drivers/ide/ide-io.c
    --- linux-2.5.67-ac1-tf1/drivers/ide/ide-io.c Thu Apr 17 20:03:36 2003
    +++ linux/drivers/ide/ide-io.c Thu Apr 17 21:49:49 2003
    @@ -496,7 +496,23 @@

    if (!args)
    goto done;
    -
    +
    + /* Some validity checking. */
    + if (!rq->hard_nr_sectors &&
    + (args->command_type != IDE_DRIVE_TASK_NO_DATA &&
    + args->command_type != IDE_DRIVE_TASK_SET_XFER)) {
    + printk(KERN_ERR "%s: %s: no data to transfer\n",
    + drive->name, __FUNCTION__);
    + goto abort;
    + }
    + if (!drive->mult_count &&
    + (args->data_phase == TASKFILE_MULTI_IN ||
    + args->data_phase == TASKFILE_MULTI_OUT)) {
    + printk(KERN_ERR "%s: %s: multimode not set\n",
    + drive->name, __FUNCTION__);
    + goto abort;
    + }
    +
    if (args->tf_out_flags.all != 0)
    return flagged_taskfile(drive, args);
    return do_rw_taskfile(drive, args);
    @@ -559,6 +575,7 @@
    #ifdef DEBUG
    printk("%s: DRIVE_CMD (null)\n", drive->name);
    #endif
    +abort:
    ide_end_drive_cmd(drive,
    hwif->INB(IDE_STATUS_REG),
    hwif->INB(IDE_ERROR_REG));
    diff -uNr linux-2.5.67-ac1-tf1/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
    --- linux-2.5.67-ac1-tf1/drivers/ide/ide-taskfile.c Thu Apr 17 20:10:59 2003
    +++ linux/drivers/ide/ide-taskfile.c Thu Apr 17 21:17:43 2003
    @@ -355,6 +355,20 @@

    EXPORT_SYMBOL(task_no_data_intr);

    +static u8 flagged_wait_drive_ready(ide_drive_t *drive)
    +{
    + ide_hwif_t *hwif = HWIF(drive);
    + int retries = 5;
    + u8 stat;
    + /*
    + * (ks) Last sector was transfered, wait until drive is ready.
    + * This can take up to 10 usec. We willl wait max 50 us.
    + */
    + while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
    + udelay(10);
    + return stat;
    +}
    +
    #define PIO_IN 0
    #define PIO_OUT 1

    @@ -386,11 +400,12 @@
    ide_startstop_t task_in_intr (ide_drive_t *drive)
    {
    struct request *rq = HWGROUP(drive)->rq;
    + ide_task_t *task = (ide_task_t *) rq->special;
    u8 stat, good_stat;

    good_stat = DATA_READY;
    -check_status:
    stat = HWIF(drive)->INB(IDE_STATUS_REG);
    +check_status:
    if (!OK_STAT(stat, good_stat, BAD_R_STAT)) {
    if (stat & (ERR_STAT|DRQ_STAT))
    return DRIVER(drive)->error(drive, __FUNCTION__, stat);
    @@ -417,6 +432,11 @@

    /* If it was the last datablock check status and finish transfer. */
    if (!rq->nr_sectors) {
    + /* FIXME: Use for all requests? --bzolnier */
    + if (!blk_fs_request(rq) && task->tf_out_flags.all != 0)
    + stat = flagged_wait_drive_ready(drive);
    + else
    + stat = HWIF(drive)->INB(IDE_STATUS_REG);
    good_stat = 0;
    goto check_status;
    }
    @@ -435,13 +455,14 @@
    ide_startstop_t task_mulin_intr (ide_drive_t *drive)
    {
    struct request *rq = HWGROUP(drive)->rq;
    + ide_task_t *task = (ide_task_t *) rq->special;
    unsigned int msect = drive->mult_count;
    unsigned int nsect;
    u8 stat, good_stat;

    good_stat = DATA_READY;
    -check_status:
    stat = HWIF(drive)->INB(IDE_STATUS_REG);
    +check_status:
    if (!OK_STAT(stat, good_stat, BAD_R_STAT)) {
    if (stat & (ERR_STAT|DRQ_STAT))
    return DRIVER(drive)->error(drive, __FUNCTION__, stat);
    @@ -479,6 +500,11 @@

    /* If it was the last datablock check status and finish transfer. */
    if (!rq->nr_sectors) {
    + /* FIXME: Use for all requests? --bzolnier */
    + if (!blk_fs_request(rq) && task->tf_out_flags.all != 0)
    + stat = flagged_wait_drive_ready(drive);
    + else
    + stat = HWIF(drive)->INB(IDE_STATUS_REG);
    good_stat = 0;
    goto check_status;
    }
    @@ -513,6 +539,11 @@
    }
    }

    + /* Deal with unexpected ATA data phase. */
    + ok_stat = OK_STAT(stat, DATA_READY, drive->bad_wstat);
    + if (!ok_stat && rq->nr_sectors)
    + return DRIVER(drive)->error(drive, __FUNCTION__, stat);
    +
    /*
    * Complete previously submitted bios (if any).
    * Status was already verifyied.
    @@ -577,6 +608,11 @@
    }
    }

    + /* Deal with unexpected ATA data phase. */
    + ok_stat = OK_STAT(stat, DATA_READY, drive->bad_wstat);
    + if (!ok_stat && rq->nr_sectors)
    + return DRIVER(drive)->error(drive, __FUNCTION__, stat);
    +
    /*
    * Complete previously submitted bios (if any).
    * Status was already verifyied.
    @@ -1619,7 +1655,6 @@
    u8 stat = hwif->INB(IDE_STATUS_REG);
    struct request *rq = HWGROUP(drive)->rq;
    char *pBuf = NULL;
    - int retries = 5;

    if (rq->current_nr_sectors == 0)
    return DRIVER(drive)->error(drive, "flagged_task_in_intr (no data requested)", stat);
    @@ -1650,12 +1685,7 @@
    ide_set_handler(drive, &flagged_task_in_intr, WAIT_WORSTCASE, NULL);
    return ide_started;
    }
    - /*
    - * (ks) Last sector was transfered, wait until drive is ready.
    - * This can take up to 10 usec. We willl wait max 50 us.
    - */
    - while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
    - udelay(10);
    + stat = flagged_wait_drive_ready(drive);
    ide_end_drive_cmd (drive, stat, hwif->INB(IDE_ERROR_REG));

    return ide_stopped;
    @@ -1667,7 +1697,6 @@
    u8 stat = hwif->INB(IDE_STATUS_REG);
    struct request *rq = HWGROUP(drive)->rq;
    char *pBuf = NULL;
    - int retries = 5;
    unsigned int msect, nsect;

    if (rq->current_nr_sectors == 0)
    @@ -1707,13 +1736,7 @@
    ide_set_handler(drive, &flagged_task_mulin_intr, WAIT_WORSTCASE, NULL);
    return ide_started;
    }
    -
    - /*
    - * (ks) Last sector was transfered, wait until drive is ready.
    - * This can take up to 10 usec. We willl wait max 50 us.
    - */
    - while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
    - udelay(10);
    + stat = flagged_wait_drive_ready(drive);
    ide_end_drive_cmd (drive, stat, hwif->INB(IDE_ERROR_REG));

    return ide_stopped;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:34    [W:0.040 / U:0.028 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site