aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-10-30 12:59:29 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:00:52 -0500
commit65d430fa99cbd0e88d09a3343f697c51fc8a7009 (patch)
treed0e7f7353bb227ff7585ff77cc682611acd1680b /drivers
parent03b147083a2f9a2a3fbbd2505fa88ffa3c6ab194 (diff)
[SCSI] scsi_transport_fc: Introduce helper function for blocking scsi_eh
Move the duplicated code from FC LLDs to SCSI FC transport class. Acked-by: James Smart <james.smart@emulex.com> Acked-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Acked-by: Abhijeet Joglekar <abjoglek@cisco.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c30
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c25
-rw-r--r--drivers/scsi/scsi_transport_fc.c26
4 files changed, 36 insertions, 65 deletions
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index b5d17385939b..8d26d7a9f01b 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -1225,22 +1225,6 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
1225 1225
1226} 1226}
1227 1227
1228static void fnic_block_error_handler(struct scsi_cmnd *sc)
1229{
1230 struct Scsi_Host *shost = sc->device->host;
1231 struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
1232 unsigned long flags;
1233
1234 spin_lock_irqsave(shost->host_lock, flags);
1235 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
1236 spin_unlock_irqrestore(shost->host_lock, flags);
1237 msleep(1000);
1238 spin_lock_irqsave(shost->host_lock, flags);
1239 }
1240 spin_unlock_irqrestore(shost->host_lock, flags);
1241
1242}
1243
1244/* 1228/*
1245 * This function is exported to SCSI for sending abort cmnds. 1229 * This function is exported to SCSI for sending abort cmnds.
1246 * A SCSI IO is represented by a io_req in the driver. 1230 * A SCSI IO is represented by a io_req in the driver.
@@ -1260,7 +1244,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
1260 DECLARE_COMPLETION_ONSTACK(tm_done); 1244 DECLARE_COMPLETION_ONSTACK(tm_done);
1261 1245
1262 /* Wait for rport to unblock */ 1246 /* Wait for rport to unblock */
1263 fnic_block_error_handler(sc); 1247 fc_block_scsi_eh(sc);
1264 1248
1265 /* Get local-port, check ready and link up */ 1249 /* Get local-port, check ready and link up */
1266 lp = shost_priv(sc->device->host); 1250 lp = shost_priv(sc->device->host);
@@ -1542,7 +1526,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
1542 DECLARE_COMPLETION_ONSTACK(tm_done); 1526 DECLARE_COMPLETION_ONSTACK(tm_done);
1543 1527
1544 /* Wait for rport to unblock */ 1528 /* Wait for rport to unblock */
1545 fnic_block_error_handler(sc); 1529 fc_block_scsi_eh(sc);
1546 1530
1547 /* Get local-port, check ready and link up */ 1531 /* Get local-port, check ready and link up */
1548 lp = shost_priv(sc->device->host); 1532 lp = shost_priv(sc->device->host);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c88f59f0ce30..e25179193a82 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2917,28 +2917,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
2917} 2917}
2918 2918
2919/** 2919/**
2920 * lpfc_block_error_handler - Routine to block error handler
2921 * @cmnd: Pointer to scsi_cmnd data structure.
2922 *
2923 * This routine blocks execution till fc_rport state is not FC_PORSTAT_BLCOEKD.
2924 **/
2925static void
2926lpfc_block_error_handler(struct scsi_cmnd *cmnd)
2927{
2928 struct Scsi_Host *shost = cmnd->device->host;
2929 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
2930
2931 spin_lock_irq(shost->host_lock);
2932 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
2933 spin_unlock_irq(shost->host_lock);
2934 msleep(1000);
2935 spin_lock_irq(shost->host_lock);
2936 }
2937 spin_unlock_irq(shost->host_lock);
2938 return;
2939}
2940
2941/**
2942 * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point 2920 * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
2943 * @cmnd: Pointer to scsi_cmnd data structure. 2921 * @cmnd: Pointer to scsi_cmnd data structure.
2944 * 2922 *
@@ -2961,7 +2939,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
2961 int ret = SUCCESS; 2939 int ret = SUCCESS;
2962 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); 2940 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
2963 2941
2964 lpfc_block_error_handler(cmnd); 2942 fc_block_scsi_eh(cmnd);
2965 lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; 2943 lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
2966 BUG_ON(!lpfc_cmd); 2944 BUG_ON(!lpfc_cmd);
2967 2945
@@ -3259,7 +3237,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
3259 struct lpfc_scsi_event_header scsi_event; 3237 struct lpfc_scsi_event_header scsi_event;
3260 int status; 3238 int status;
3261 3239
3262 lpfc_block_error_handler(cmnd); 3240 fc_block_scsi_eh(cmnd);
3263 3241
3264 status = lpfc_chk_tgt_mapped(vport, cmnd); 3242 status = lpfc_chk_tgt_mapped(vport, cmnd);
3265 if (status == FAILED) { 3243 if (status == FAILED) {
@@ -3318,7 +3296,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
3318 struct lpfc_scsi_event_header scsi_event; 3296 struct lpfc_scsi_event_header scsi_event;
3319 int status; 3297 int status;
3320 3298
3321 lpfc_block_error_handler(cmnd); 3299 fc_block_scsi_eh(cmnd);
3322 3300
3323 status = lpfc_chk_tgt_mapped(vport, cmnd); 3301 status = lpfc_chk_tgt_mapped(vport, cmnd);
3324 if (status == FAILED) { 3302 if (status == FAILED) {
@@ -3384,7 +3362,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
3384 fc_host_post_vendor_event(shost, fc_get_event_number(), 3362 fc_host_post_vendor_event(shost, fc_get_event_number(),
3385 sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); 3363 sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
3386 3364
3387 lpfc_block_error_handler(cmnd); 3365 fc_block_scsi_eh(cmnd);
3388 3366
3389 /* 3367 /*
3390 * Since the driver manages a single bus device, reset all 3368 * Since the driver manages a single bus device, reset all
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d69744a62fe4..41669357b186 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -728,23 +728,6 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
728 spin_unlock_irqrestore(&ha->hardware_lock, flags); 728 spin_unlock_irqrestore(&ha->hardware_lock, flags);
729} 729}
730 730
731static void
732qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
733{
734 struct Scsi_Host *shost = cmnd->device->host;
735 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
736 unsigned long flags;
737
738 spin_lock_irqsave(shost->host_lock, flags);
739 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
740 spin_unlock_irqrestore(shost->host_lock, flags);
741 msleep(1000);
742 spin_lock_irqsave(shost->host_lock, flags);
743 }
744 spin_unlock_irqrestore(shost->host_lock, flags);
745 return;
746}
747
748/************************************************************************** 731/**************************************************************************
749* qla2xxx_eh_abort 732* qla2xxx_eh_abort
750* 733*
@@ -774,7 +757,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
774 struct req_que *req = vha->req; 757 struct req_que *req = vha->req;
775 srb_t *spt; 758 srb_t *spt;
776 759
777 qla2x00_block_error_handler(cmd); 760 fc_block_scsi_eh(cmd);
778 761
779 if (!CMD_SP(cmd)) 762 if (!CMD_SP(cmd))
780 return SUCCESS; 763 return SUCCESS;
@@ -905,7 +888,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
905 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 888 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
906 int err; 889 int err;
907 890
908 qla2x00_block_error_handler(cmd); 891 fc_block_scsi_eh(cmd);
909 892
910 if (!fcport) 893 if (!fcport)
911 return FAILED; 894 return FAILED;
@@ -985,7 +968,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
985 unsigned long serial; 968 unsigned long serial;
986 srb_t *sp = (srb_t *) CMD_SP(cmd); 969 srb_t *sp = (srb_t *) CMD_SP(cmd);
987 970
988 qla2x00_block_error_handler(cmd); 971 fc_block_scsi_eh(cmd);
989 972
990 id = cmd->device->id; 973 id = cmd->device->id;
991 lun = cmd->device->lun; 974 lun = cmd->device->lun;
@@ -1048,7 +1031,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1048 srb_t *sp = (srb_t *) CMD_SP(cmd); 1031 srb_t *sp = (srb_t *) CMD_SP(cmd);
1049 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 1032 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
1050 1033
1051 qla2x00_block_error_handler(cmd); 1034 fc_block_scsi_eh(cmd);
1052 1035
1053 id = cmd->device->id; 1036 id = cmd->device->id;
1054 lun = cmd->device->lun; 1037 lun = cmd->device->lun;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index f436e033adaf..3ce56b3b2cd7 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -27,6 +27,7 @@
27 */ 27 */
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/delay.h>
30#include <scsi/scsi_device.h> 31#include <scsi/scsi_device.h>
31#include <scsi/scsi_host.h> 32#include <scsi/scsi_host.h>
32#include <scsi/scsi_transport.h> 33#include <scsi/scsi_transport.h>
@@ -3144,6 +3145,31 @@ fc_scsi_scan_rport(struct work_struct *work)
3144 spin_unlock_irqrestore(shost->host_lock, flags); 3145 spin_unlock_irqrestore(shost->host_lock, flags);
3145} 3146}
3146 3147
3148/**
3149 * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
3150 * @cmnd: SCSI command that scsi_eh is trying to recover
3151 *
3152 * This routine can be called from a FC LLD scsi_eh callback. It
3153 * blocks the scsi_eh thread until the fc_rport leaves the
3154 * FC_PORTSTATE_BLOCKED. This is necessary to avoid the scsi_eh
3155 * failing recovery actions for blocked rports which would lead to
3156 * offlined SCSI devices.
3157 */
3158void fc_block_scsi_eh(struct scsi_cmnd *cmnd)
3159{
3160 struct Scsi_Host *shost = cmnd->device->host;
3161 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
3162 unsigned long flags;
3163
3164 spin_lock_irqsave(shost->host_lock, flags);
3165 while (rport->port_state == FC_PORTSTATE_BLOCKED) {
3166 spin_unlock_irqrestore(shost->host_lock, flags);
3167 msleep(1000);
3168 spin_lock_irqsave(shost->host_lock, flags);
3169 }
3170 spin_unlock_irqrestore(shost->host_lock, flags);
3171}
3172EXPORT_SYMBOL(fc_block_scsi_eh);
3147 3173
3148/** 3174/**
3149 * fc_vport_setup - allocates and creates a FC virtual port. 3175 * fc_vport_setup - allocates and creates a FC virtual port.