lkml.org 
[lkml]   [2005]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH 2.6.11-rc2 01/04] ide: ide_write_taskfile() implemented.
    From
    Date

    01_ide_write_taskfile.patch

    ide_write_taskfile(), which writes the content of a ide_task_t
    into the IDE taskfile registers, is implemented, and
    do_rw_taskfile() and flagged_taskfile() are converted to use
    ide_write_taskfile(). Behavior changes are
    - flagged taskfile now honors HOB feature register.
    - No do_rw_taskfile() HIHI check on select register. Except
    for the DEV bit, all bits are honored.


    Signed-off-by: Tejun Heo <tj@home-tj.org>


    Index: linux-ide-series3-export/drivers/ide/ide-taskfile.c
    ===================================================================
    --- linux-ide-series3-export.orig/drivers/ide/ide-taskfile.c 2005-02-06 19:48:58.868249056 +0900
    +++ linux-ide-series3-export/drivers/ide/ide-taskfile.c 2005-02-06 19:49:18.730022291 +0900
    @@ -96,12 +96,94 @@ int taskfile_lib_get_identify (ide_drive
    return ide_raw_taskfile(drive, &args, buf);
    }

    +void ide_write_taskfile(ide_drive_t *drive, ide_task_t *task)
    +{
    + ide_hwif_t *hwif = drive->hwif;
    + void (*OUTB)(u8, unsigned long) = hwif->OUTB;
    + unsigned long *ports = hwif->io_ports;
    + task_struct_t *tf = (task_struct_t *)task->tfRegister;
    + hob_struct_t *hob = (hob_struct_t *)task->hobRegister;
    +
    + /*
    + * (ks) Check taskfile out flags.
    + * If set, then execute as it is defined.
    + * If not set, then,
    + * write all taskfile registers (except data)
    + * write the hob registers (feature,sector,nsector,lcyl,hcyl)
    + */
    + if (task->tf_out_flags.all == 0) {
    + /* Hot path optimization */
    + if (drive->addressing == 1) {
    + /* Send hob registers first */
    + OUTB(hob->feature, ports[IDE_FEATURE_OFFSET]);
    + OUTB(hob->sector_count, ports[IDE_NSECTOR_OFFSET]);
    + OUTB(hob->sector_number, ports[IDE_SECTOR_OFFSET]);
    + OUTB(hob->low_cylinder, ports[IDE_LCYL_OFFSET]);
    + OUTB(hob->high_cylinder, ports[IDE_HCYL_OFFSET]);
    + }
    +
    + /* Send now the standard registers */
    + OUTB(tf->feature, ports[IDE_FEATURE_OFFSET]);
    + OUTB(tf->sector_count, ports[IDE_NSECTOR_OFFSET]);
    + OUTB(tf->sector_number, ports[IDE_SECTOR_OFFSET]);
    + OUTB(tf->low_cylinder, ports[IDE_LCYL_OFFSET]);
    + OUTB(tf->high_cylinder, ports[IDE_HCYL_OFFSET]);
    +
    + OUTB((tf->device_head & ~0x10) | drive->select.all,
    + ports[IDE_SELECT_OFFSET]);
    +
    + return;
    + }
    +
    + /* Flagged */
    + if (drive->addressing == 1) {
    + /* (ks) Send hob registers first */
    + if (task->tf_out_flags.b.error_feature)
    + OUTB(hob->feature, ports[IDE_FEATURE_OFFSET]);
    + if (task->tf_out_flags.b.nsector_hob)
    + OUTB(hob->sector_count, ports[IDE_NSECTOR_OFFSET]);
    + if (task->tf_out_flags.b.sector_hob)
    + OUTB(hob->sector_number, ports[IDE_SECTOR_OFFSET]);
    + if (task->tf_out_flags.b.lcyl_hob)
    + OUTB(hob->low_cylinder, ports[IDE_LCYL_OFFSET]);
    + if (task->tf_out_flags.b.hcyl_hob)
    + OUTB(hob->high_cylinder, ports[IDE_HCYL_OFFSET]);
    + }
    +
    + /* (ks) Send now the standard registers */
    + if (task->tf_out_flags.b.error_feature)
    + OUTB(tf->feature, ports[IDE_FEATURE_OFFSET]);
    + if (task->tf_out_flags.b.nsector)
    + OUTB(tf->sector_count, ports[IDE_NSECTOR_OFFSET]);
    + if (task->tf_out_flags.b.sector)
    + OUTB(tf->sector_number, ports[IDE_SECTOR_OFFSET]);
    + if (task->tf_out_flags.b.lcyl)
    + OUTB(tf->low_cylinder, ports[IDE_LCYL_OFFSET]);
    + if (task->tf_out_flags.b.hcyl)
    + OUTB(tf->high_cylinder, ports[IDE_HCYL_OFFSET]);
    +
    + if (task->tf_out_flags.b.data) {
    + u16 data = tf->data + (hob->data << 8);
    + hwif->OUTW(data, ports[IDE_DATA_OFFSET]);
    + }
    +
    + /*
    + * (ks) In the flagged taskfile approch, we will use all
    + * specified registers and the register value will not be
    + * changed, except the select bit (master/slave) in the
    + * drive_head register. We must make sure that the desired
    + * drive is selected.
    + */
    + hwif->OUTB(tf->device_head | drive->select.all,
    + ports[IDE_SELECT_OFFSET]);
    +}
    +
    +EXPORT_SYMBOL(ide_write_taskfile);
    +
    ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
    {
    ide_hwif_t *hwif = HWIF(drive);
    task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
    - hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
    - u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF;

    /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
    if (IDE_CONTROL_REG) {
    @@ -110,21 +192,7 @@ ide_startstop_t do_rw_taskfile (ide_driv
    }
    SELECT_MASK(drive, 0);

    - if (drive->addressing == 1) {
    - hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
    - hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
    - hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
    - hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
    - hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
    - }
    -
    - hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
    - hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
    - hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
    - hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
    - hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
    -
    - hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
    + ide_write_taskfile(drive, task);

    if (task->handler != NULL) {
    if (task->prehandler != NULL) {
    @@ -799,7 +867,6 @@ ide_startstop_t flagged_taskfile (ide_dr
    {
    ide_hwif_t *hwif = HWIF(drive);
    task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
    - hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
    #if DEBUG_TASKFILE
    u8 status;
    #endif
    @@ -812,26 +879,6 @@ ide_startstop_t flagged_taskfile (ide_dr
    }
    }

    - /*
    - * (ks) Check taskfile in/out flags.
    - * If set, then execute as it is defined.
    - * If not set, then define default settings.
    - * The default values are:
    - * write and read all taskfile registers (except data)
    - * write and read the hob registers (sector,nsector,lcyl,hcyl)
    - */
    - if (task->tf_out_flags.all == 0) {
    - task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
    - if (drive->addressing == 1)
    - task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
    - }
    -
    - if (task->tf_in_flags.all == 0) {
    - task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
    - if (drive->addressing == 1)
    - task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
    - }
    -
    /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
    if (IDE_CONTROL_REG)
    /* clear nIEN */
    @@ -848,42 +895,8 @@ ide_startstop_t flagged_taskfile (ide_dr
    }
    #endif

    - if (task->tf_out_flags.b.data) {
    - u16 data = taskfile->data + (hobfile->data << 8);
    - hwif->OUTW(data, IDE_DATA_REG);
    - }
    -
    - /* (ks) send hob registers first */
    - if (task->tf_out_flags.b.nsector_hob)
    - hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
    - if (task->tf_out_flags.b.sector_hob)
    - hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
    - if (task->tf_out_flags.b.lcyl_hob)
    - hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
    - if (task->tf_out_flags.b.hcyl_hob)
    - hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
    -
    - /* (ks) Send now the standard registers */
    - if (task->tf_out_flags.b.error_feature)
    - hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
    - /* refers to number of sectors to transfer */
    - if (task->tf_out_flags.b.nsector)
    - hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
    - /* refers to sector offset or start sector */
    - if (task->tf_out_flags.b.sector)
    - hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
    - if (task->tf_out_flags.b.lcyl)
    - hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
    - if (task->tf_out_flags.b.hcyl)
    - hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
    + ide_write_taskfile(drive, task);

    - /*
    - * (ks) In the flagged taskfile approch, we will use all specified
    - * registers and the register value will not be changed, except the
    - * select bit (master/slave) in the drive_head register. We must make
    - * sure that the desired drive is selected.
    - */
    - hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
    switch(task->data_phase) {

    case TASKFILE_OUT_DMAQ:
    Index: linux-ide-series3-export/include/linux/ide.h
    ===================================================================
    --- linux-ide-series3-export.orig/include/linux/ide.h 2005-02-06 19:48:58.869248893 +0900
    +++ linux-ide-series3-export/include/linux/ide.h 2005-02-06 19:49:18.732021966 +0900
    @@ -1295,6 +1295,8 @@ extern void atapi_output_bytes(ide_drive
    extern int drive_is_ready(ide_drive_t *);
    extern int wait_for_ready(ide_drive_t *, int /* timeout */);

    +void ide_write_taskfile(ide_drive_t *drive, ide_task_t *task);
    +
    /*
    * taskfile io for disks for now...and builds request from ide_ioctl
    */
    -
    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 14:10    [W:0.033 / U:0.496 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site