Commit 77ec183a authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley

[PATCH] aacraid reset handler

Adds a reset handler to the aacraid template
parent 7bfdc29f
......@@ -512,6 +512,7 @@ struct adapter_ops
void (*adapter_enable_int)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev, u32 event);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 *status);
int (*adapter_check_health)(struct aac_dev *dev);
};
/*
......@@ -942,6 +943,8 @@ struct aac_dev
#define aac_adapter_disable_int(dev, event) \
dev->a_ops.adapter_disable_int(dev, event)
#define aac_adapter_check_health(dev) \
(dev)->a_ops.adapter_check_health(dev)
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
......
......@@ -49,6 +49,7 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_eh.h>
#include "aacraid.h"
......@@ -339,6 +340,51 @@ static int aac_eh_abort(struct scsi_cmnd *cmd)
return FAILED;
}
/*
* aac_eh_reset - Reset command handling
* @scsi_cmd: SCSI command block causing the reset
*
*/
static int aac_eh_reset(struct scsi_cmnd* cmd)
{
struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host;
struct scsi_cmnd * command;
int count;
unsigned long flags;
printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME);
if (aac_adapter_check_health((struct aac_dev *)host->hostdata)) {
printk(KERN_ERR "%s: Host adapter appears dead\n",
AAC_DRIVERNAME);
return -ENODEV;
}
/*
* Wait for all commands to complete to this specific
* target (block maximum 60 seconds).
*/
for (count = 60; count; --count) {
__shost_for_each_device(dev, host) {
spin_lock_irqsave(&dev->list_lock, flags);
list_for_each_entry(command, &dev->cmd_list, list) {
if (command->serial_number) {
spin_unlock_irqrestore(&dev->list_lock, flags);
return SUCCESS;
}
}
spin_unlock_irqrestore(&dev->list_lock, flags);
}
spin_unlock_irq(host->host_lock);
scsi_sleep(HZ);
spin_lock_irq(host->host_lock);
}
printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
return -ETIMEDOUT;
}
/**
* aac_cfg_open - open a configuration file
* @inode: inode being opened
......@@ -397,6 +443,7 @@ static struct scsi_host_template aac_driver_template = {
.bios_param = aac_biosparm,
.slave_configure = aac_slave_configure,
.eh_abort_handler = aac_eh_abort,
.eh_host_reset_handler = aac_eh_reset,
.can_queue = AAC_NUM_IO_FIB,
.this_id = 16,
.sg_tablesize = 16,
......
......@@ -324,6 +324,38 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
}
/**
* aac_rkt_check_health
* @dev: device to check if healthy
*
* Will attempt to determine if the specified adapter is alive and
* capable of handling requests, returning 0 if alive.
*/
static int aac_rkt_check_health(struct aac_dev *dev)
{
long status = rkt_readl(dev, IndexRegs.Mailbox[7]);
/*
* Check to see if the board failed any self tests.
*/
if (status & SELF_TEST_FAILED)
return -1;
/*
* Check to see if the board panic'd while booting.
*/
if (status & KERNEL_PANIC)
return -2;
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
*/
if (!(status & KERNEL_UP_AND_RUNNING))
return -3;
/*
* Everything is OK
*/
return 0;
} /* aac_rkt_check_health */
/**
* aac_rkt_init - initialize an i960 based AAC card
* @dev: device to configure
......
......@@ -324,6 +324,38 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
}
/**
* aac_rx_check_health
* @dev: device to check if healthy
*
* Will attempt to determine if the specified adapter is alive and
* capable of handling requests, returning 0 if alive.
*/
static int aac_rx_check_health(struct aac_dev *dev)
{
long status = rx_readl(dev, IndexRegs.Mailbox[7]);
/*
* Check to see if the board failed any self tests.
*/
if (status & SELF_TEST_FAILED)
return -1;
/*
* Check to see if the board panic'd while booting.
*/
if (status & KERNEL_PANIC)
return -2;
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
*/
if (!(status & KERNEL_UP_AND_RUNNING))
return -3;
/*
* Everything is OK
*/
return 0;
} /* aac_rx_check_health */
/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
......
......@@ -299,6 +299,38 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &ret);
}
/**
* aac_sa_check_health
* @dev: device to check if healthy
*
* Will attempt to determine if the specified adapter is alive and
* capable of handling requests, returning 0 if alive.
*/
static int aac_sa_check_health(struct aac_dev *dev)
{
long status = sa_readl(dev, Mailbox7);
/*
* Check to see if the board failed any self tests.
*/
if (status & SELF_TEST_FAILED)
return -1;
/*
* Check to see if the board panic'd while booting.
*/
if (status & KERNEL_PANIC)
return -2;
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
*/
if (!(status & KERNEL_UP_AND_RUNNING))
return -3;
/*
* Everything is OK
*/
return 0;
} /* aac_sa_check_health */
/**
* aac_sa_init - initialize an ARM based AAC card
* @dev: device to configure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment