[PATCH] move ->eh_strategy_handler to the transport class

Overriding the whole EH code is a per-transport, not per-host thing.
Move ->eh_strategy_handler to the transport class, same as
->eh_timed_out.

Downside is that scsi_host_alloc can't check for the total lack of EH
anymore, but the transition period from old EH where we needed it is
long gone already.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Christoph Hellwig 2006-04-01 19:21:04 +02:00 committed by Jeff Garzik
parent 676165a8af
commit 9227c33de8
26 changed files with 18 additions and 66 deletions

View File

@ -705,7 +705,7 @@ and other resources, etc.
<sect1><title>ata_scsi_error()</title>
<para>
ata_scsi_error() is the current hostt->eh_strategy_handler()
ata_scsi_error() is the current transportt->eh_strategy_handler()
for libata. As discussed above, this will be entered in two
cases - timeout and ATAPI error completion. This function
calls low level libata driver's eng_timeout() callback, the

View File

@ -19,9 +19,9 @@ TABLE OF CONTENTS
[2-1-1] Overview
[2-1-2] Flow of scmds through EH
[2-1-3] Flow of control
[2-2] EH through hostt->eh_strategy_handler()
[2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions
[2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions
[2-2] EH through transportt->eh_strategy_handler()
[2-2-1] Pre transportt->eh_strategy_handler() SCSI midlayer conditions
[2-2-2] Post transportt->eh_strategy_handler() SCSI midlayer conditions
[2-2-3] Things to consider
@ -413,9 +413,9 @@ scmd->allowed.
layer of failure of the scmds.
[2-2] EH through hostt->eh_strategy_handler()
[2-2] EH through transportt->eh_strategy_handler()
hostt->eh_strategy_handler() is invoked in the place of
transportt->eh_strategy_handler() is invoked in the place of
scsi_unjam_host() and it is responsible for whole recovery process.
On completion, the handler should have made lower layers forget about
all failed scmds and either ready for new commands or offline. Also,
@ -424,7 +424,7 @@ SCSI midlayer. IOW, of the steps described in [2-1-2], all steps
except for #1 must be implemented by eh_strategy_handler().
[2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions
[2-2-1] Pre transportt->eh_strategy_handler() SCSI midlayer conditions
The following conditions are true on entry to the handler.
@ -437,7 +437,7 @@ except for #1 must be implemented by eh_strategy_handler().
- shost->host_failed == shost->host_busy
[2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions
[2-2-2] Post transportt->eh_strategy_handler() SCSI midlayer conditions
The following conditions must be true on exit from the handler.

View File

@ -804,7 +804,6 @@ Summary:
eh_bus_reset_handler - issue SCSI bus reset
eh_device_reset_handler - issue SCSI device reset
eh_host_reset_handler - reset host (host bus adapter)
eh_strategy_handler - driver supplied alternate to scsi_unjam_host()
info - supply information about given host
ioctl - driver can respond to ioctls
proc_info - supports /proc/scsi/{driver_name}/{host_no}
@ -969,24 +968,6 @@ Details:
int eh_host_reset_handler(struct scsi_cmnd * scp)
/**
* eh_strategy_handler - driver supplied alternate to scsi_unjam_host()
* @shp: host on which error has occurred
*
* Returns TRUE if host unjammed, else FALSE.
*
* Locks: none
*
* Calling context: kernel thread
*
* Notes: Invoked from scsi_eh thread. LLD supplied alternate to
* scsi_unjam_host() found in scsi_error.c
*
* Optionally defined in: LLD
**/
int eh_strategy_handler(struct Scsi_Host * shp)
/**
* info - supply information about given host: driver name plus data
* to distinguish given host

View File

@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = AHCI_MAX_SG,

View File

@ -209,7 +209,6 @@ static struct scsi_host_template piix_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -294,18 +294,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
if (sht->unchecked_isa_dma && privsize)
gfp_mask |= __GFP_DMA;
/* Check to see if this host has any error handling facilities */
if (!sht->eh_strategy_handler && !sht->eh_abort_handler &&
!sht->eh_device_reset_handler && !sht->eh_bus_reset_handler &&
!sht->eh_host_reset_handler) {
printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n"
"ERROR: This is not a safe way to run your "
"SCSI host\n"
"ERROR: The error handling must be added to "
"this driver\n", sht->proc_name);
dump_stack();
}
shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
if (!shost)
return NULL;

View File

@ -4938,7 +4938,6 @@ EXPORT_SYMBOL_GPL(ata_busy_sleep);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);

View File

@ -53,6 +53,7 @@
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
static void ata_scsi_error(struct Scsi_Host *host);
enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
#define RW_RECOVERY_MPAGE 0x1
@ -99,6 +100,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
* It just needs the eh_timed_out hook.
*/
struct scsi_transport_template ata_scsi_transport_template = {
.eh_strategy_handler = ata_scsi_error,
.eh_timed_out = ata_scsi_timed_out,
};
@ -772,12 +774,9 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
*
* LOCKING:
* Inherited from SCSI layer (none, can sleep)
*
* RETURNS:
* Zero.
*/
int ata_scsi_error(struct Scsi_Host *host)
static void ata_scsi_error(struct Scsi_Host *host)
{
struct ata_port *ap;
unsigned long flags;
@ -805,7 +804,6 @@ int ata_scsi_error(struct Scsi_Host *host)
spin_unlock_irqrestore(&ap->host_set->lock, flags);
DPRINTK("EXIT\n");
return 0;
}
static void ata_eh_scsidone(struct scsi_cmnd *scmd)

View File

@ -60,7 +60,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct scsi_transport_template ata_scsi_transport_template;
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);

View File

@ -143,7 +143,6 @@ static struct scsi_host_template adma_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -378,8 +378,6 @@ static struct scsi_host_template mv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = MV_MAX_SG_CT / 2,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,

View File

@ -201,7 +201,6 @@ static struct scsi_host_template nv_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -111,7 +111,6 @@ static struct scsi_host_template pdc_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -132,7 +132,6 @@ static struct scsi_host_template qs_ata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = QS_MAX_PRD,

View File

@ -146,7 +146,6 @@ static struct scsi_host_template sil_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -281,7 +281,6 @@ static struct scsi_host_template sil24_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -87,7 +87,6 @@ static struct scsi_host_template sis_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = ATA_MAX_PRD,

View File

@ -290,7 +290,6 @@ static struct scsi_host_template k2_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -182,7 +182,6 @@ static struct scsi_host_template pdc_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -81,7 +81,6 @@ static struct scsi_host_template uli_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -94,7 +94,6 @@ static struct scsi_host_template svia_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -263,7 +263,6 @@ static struct scsi_host_template vsc_sata_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,

View File

@ -1537,8 +1537,8 @@ int scsi_error_handler(void *data)
* what we need to do to get it up and online again (if we can).
* If we fail, we end up taking the thing offline.
*/
if (shost->hostt->eh_strategy_handler)
shost->hostt->eh_strategy_handler(shost);
if (shost->transportt->eh_strategy_handler)
shost->transportt->eh_strategy_handler(shost);
else
scsi_unjam_host(shost);

View File

@ -523,7 +523,6 @@ extern void ata_host_set_remove(struct ata_host_set *host_set);
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_error(struct Scsi_Host *host);
extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
extern int ata_scsi_release(struct Scsi_Host *host);

View File

@ -140,7 +140,6 @@ struct scsi_host_template {
*
* Status: REQUIRED (at least one of them)
*/
int (* eh_strategy_handler)(struct Scsi_Host *);
int (* eh_abort_handler)(struct scsi_cmnd *);
int (* eh_device_reset_handler)(struct scsi_cmnd *);
int (* eh_bus_reset_handler)(struct scsi_cmnd *);

View File

@ -49,6 +49,11 @@ struct scsi_transport_template {
*/
unsigned int create_work_queue : 1;
/*
* Allows a transport to override the default error handler.
*/
void (* eh_strategy_handler)(struct Scsi_Host *);
/*
* This is an optional routine that allows the transport to become
* involved when a scsi io timer fires. The return value tells the