[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:
Родитель
676165a8af
Коммит
9227c33de8
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче