lkml.org 
[lkml]   [2015]   [Nov]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 62/71] ncr5380: Implement new eh_bus_reset_handler
    NCR5380.c lacks a sane eh_bus_reset_handler. The atari_NCR5380.c code is
    much better but it should not throw out the issue queue (that would be
    a host reset) and it neglects to set the result code for commands that it
    throws out. Fix these bugs and keep the two core drivers in sync.

    Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

    ---
    drivers/scsi/NCR5380.c | 50 ++++++++++++++++++++++++++++++++++++++++++-
    drivers/scsi/atari_NCR5380.c | 39 +++++++++++++++++++--------------
    2 files changed, 72 insertions(+), 17 deletions(-)

    Index: linux/drivers/scsi/atari_NCR5380.c
    ===================================================================
    --- linux.orig/drivers/scsi/atari_NCR5380.c 2015-11-18 19:34:29.000000000 +1100
    +++ linux/drivers/scsi/atari_NCR5380.c 2015-11-18 19:34:30.000000000 +1100
    @@ -2703,11 +2703,12 @@ static int NCR5380_bus_reset(struct scsi
    struct NCR5380_hostdata *hostdata = shost_priv(instance);
    int i;
    unsigned long flags;
    + struct NCR5380_cmd *ncmd;

    spin_lock_irqsave(&hostdata->lock, flags);

    #if (NDEBUG & NDEBUG_ANY)
    - scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
    + scmd_printk(KERN_INFO, cmd, __func__);
    #endif
    NCR5380_dprint(NDEBUG_ANY, instance);
    NCR5380_dprint_phase(NDEBUG_ANY, instance);
    @@ -2727,27 +2728,32 @@ static int NCR5380_bus_reset(struct scsi

    hostdata->selecting = NULL;

    - if (hostdata->connected)
    - dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
    - hostdata->connected = NULL;
    + list_for_each_entry(ncmd, &hostdata->disconnected, list) {
    + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
    +
    + set_host_byte(cmd, DID_RESET);
    + cmd->scsi_done(cmd);
    + }
    +
    + list_for_each_entry(ncmd, &hostdata->autosense, list) {
    + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
    +
    + set_host_byte(cmd, DID_RESET);
    + cmd->scsi_done(cmd);
    + }
    +
    + if (hostdata->connected) {
    + set_host_byte(hostdata->connected, DID_RESET);
    + complete_cmd(instance, hostdata->connected);
    + hostdata->connected = NULL;
    + }

    if (hostdata->sensing) {
    + set_host_byte(hostdata->connected, DID_RESET);
    complete_cmd(instance, hostdata->sensing);
    hostdata->sensing = NULL;
    }

    - if (!list_empty(&hostdata->autosense))
    - dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
    - INIT_LIST_HEAD(&hostdata->autosense);
    -
    - if (!list_empty(&hostdata->unissued))
    - dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
    - INIT_LIST_HEAD(&hostdata->unissued);
    -
    - if (!list_empty(&hostdata->disconnected))
    - dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
    - INIT_LIST_HEAD(&hostdata->disconnected);
    -
    #ifdef SUPPORT_TAGS
    free_all_tags(hostdata);
    #endif
    @@ -2757,6 +2763,7 @@ static int NCR5380_bus_reset(struct scsi
    hostdata->dma_len = 0;
    #endif

    + queue_work(hostdata->work_q, &hostdata->main_task);
    maybe_release_dma_irq(instance);
    spin_unlock_irqrestore(&hostdata->lock, flags);

    Index: linux/drivers/scsi/NCR5380.c
    ===================================================================
    --- linux.orig/drivers/scsi/NCR5380.c 2015-11-18 19:34:29.000000000 +1100
    +++ linux/drivers/scsi/NCR5380.c 2015-11-18 19:34:30.000000000 +1100
    @@ -2489,18 +2489,66 @@ static int NCR5380_bus_reset(struct scsi
    {
    struct Scsi_Host *instance = cmd->device->host;
    struct NCR5380_hostdata *hostdata = shost_priv(instance);
    + int i;
    unsigned long flags;
    + struct NCR5380_cmd *ncmd;

    spin_lock_irqsave(&hostdata->lock, flags);

    #if (NDEBUG & NDEBUG_ANY)
    - scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
    + scmd_printk(KERN_INFO, cmd, __func__);
    #endif
    NCR5380_dprint(NDEBUG_ANY, instance);
    NCR5380_dprint_phase(NDEBUG_ANY, instance);

    do_reset(instance);

    + /* reset NCR registers */
    + NCR5380_write(MODE_REG, MR_BASE);
    + NCR5380_write(TARGET_COMMAND_REG, 0);
    + NCR5380_write(SELECT_ENABLE_REG, 0);
    +
    + /* After the reset, there are no more connected or disconnected commands
    + * and no busy units; so clear the low-level status here to avoid
    + * conflicts when the mid-level code tries to wake up the affected
    + * commands!
    + */
    +
    + hostdata->selecting = NULL;
    +
    + list_for_each_entry(ncmd, &hostdata->disconnected, list) {
    + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
    +
    + set_host_byte(cmd, DID_RESET);
    + cmd->scsi_done(cmd);
    + }
    +
    + list_for_each_entry(ncmd, &hostdata->autosense, list) {
    + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
    +
    + set_host_byte(cmd, DID_RESET);
    + cmd->scsi_done(cmd);
    + }
    +
    + if (hostdata->connected) {
    + set_host_byte(hostdata->connected, DID_RESET);
    + complete_cmd(instance, hostdata->connected);
    + hostdata->connected = NULL;
    + }
    +
    + if (hostdata->sensing) {
    + set_host_byte(hostdata->connected, DID_RESET);
    + complete_cmd(instance, hostdata->sensing);
    + hostdata->sensing = NULL;
    + }
    +
    + for (i = 0; i < 8; ++i)
    + hostdata->busy[i] = 0;
    +#ifdef REAL_DMA
    + hostdata->dma_len = 0;
    +#endif
    +
    + queue_work(hostdata->work_q, &hostdata->main_task);
    spin_unlock_irqrestore(&hostdata->lock, flags);

    return SUCCESS;



    \
     
     \ /
      Last update: 2015-11-18 10:01    [W:4.199 / U:0.504 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site