Commit 65d430fa99cbd0e88d09a3343f697c51fc8a7009

Authored by Christof Schmitt
Committed by James Bottomley
1 parent 03b147083a

[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>

Showing 5 changed files with 37 additions and 65 deletions Side-by-side Diff

drivers/scsi/fnic/fnic_scsi.c
... ... @@ -1225,22 +1225,6 @@
1225 1225  
1226 1226 }
1227 1227  
1228   -static 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 1229 * This function is exported to SCSI for sending abort cmnds.
1246 1230 * A SCSI IO is represented by a io_req in the driver.
... ... @@ -1260,7 +1244,7 @@
1260 1244 DECLARE_COMPLETION_ONSTACK(tm_done);
1261 1245  
1262 1246 /* Wait for rport to unblock */
1263   - fnic_block_error_handler(sc);
  1247 + fc_block_scsi_eh(sc);
1264 1248  
1265 1249 /* Get local-port, check ready and link up */
1266 1250 lp = shost_priv(sc->device->host);
... ... @@ -1542,7 +1526,7 @@
1542 1526 DECLARE_COMPLETION_ONSTACK(tm_done);
1543 1527  
1544 1528 /* Wait for rport to unblock */
1545   - fnic_block_error_handler(sc);
  1529 + fc_block_scsi_eh(sc);
1546 1530  
1547 1531 /* Get local-port, check ready and link up */
1548 1532 lp = shost_priv(sc->device->host);
drivers/scsi/lpfc/lpfc_scsi.c
... ... @@ -2917,28 +2917,6 @@
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   - **/
2925   -static void
2926   -lpfc_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 2920 * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
2943 2921 * @cmnd: Pointer to scsi_cmnd data structure.
2944 2922 *
... ... @@ -2961,7 +2939,7 @@
2961 2939 int ret = SUCCESS;
2962 2940 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
2963 2941  
2964   - lpfc_block_error_handler(cmnd);
  2942 + fc_block_scsi_eh(cmnd);
2965 2943 lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
2966 2944 BUG_ON(!lpfc_cmd);
2967 2945  
... ... @@ -3259,7 +3237,7 @@
3259 3237 struct lpfc_scsi_event_header scsi_event;
3260 3238 int status;
3261 3239  
3262   - lpfc_block_error_handler(cmnd);
  3240 + fc_block_scsi_eh(cmnd);
3263 3241  
3264 3242 status = lpfc_chk_tgt_mapped(vport, cmnd);
3265 3243 if (status == FAILED) {
... ... @@ -3318,7 +3296,7 @@
3318 3296 struct lpfc_scsi_event_header scsi_event;
3319 3297 int status;
3320 3298  
3321   - lpfc_block_error_handler(cmnd);
  3299 + fc_block_scsi_eh(cmnd);
3322 3300  
3323 3301 status = lpfc_chk_tgt_mapped(vport, cmnd);
3324 3302 if (status == FAILED) {
... ... @@ -3384,7 +3362,7 @@
3384 3362 fc_host_post_vendor_event(shost, fc_get_event_number(),
3385 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 3368 * Since the driver manages a single bus device, reset all
drivers/scsi/qla2xxx/qla_os.c
... ... @@ -728,23 +728,6 @@
728 728 spin_unlock_irqrestore(&ha->hardware_lock, flags);
729 729 }
730 730  
731   -static void
732   -qla2x00_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 732 * qla2xxx_eh_abort
750 733 *
... ... @@ -774,7 +757,7 @@
774 757 struct req_que *req = vha->req;
775 758 srb_t *spt;
776 759  
777   - qla2x00_block_error_handler(cmd);
  760 + fc_block_scsi_eh(cmd);
778 761  
779 762 if (!CMD_SP(cmd))
780 763 return SUCCESS;
... ... @@ -905,7 +888,7 @@
905 888 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
906 889 int err;
907 890  
908   - qla2x00_block_error_handler(cmd);
  891 + fc_block_scsi_eh(cmd);
909 892  
910 893 if (!fcport)
911 894 return FAILED;
... ... @@ -985,7 +968,7 @@
985 968 unsigned long serial;
986 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 973 id = cmd->device->id;
991 974 lun = cmd->device->lun;
... ... @@ -1048,7 +1031,7 @@
1048 1031 srb_t *sp = (srb_t *) CMD_SP(cmd);
1049 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 1036 id = cmd->device->id;
1054 1037 lun = cmd->device->lun;
drivers/scsi/scsi_transport_fc.c
... ... @@ -27,6 +27,7 @@
27 27 */
28 28 #include <linux/module.h>
29 29 #include <linux/init.h>
  30 +#include <linux/delay.h>
30 31 #include <scsi/scsi_device.h>
31 32 #include <scsi/scsi_host.h>
32 33 #include <scsi/scsi_transport.h>
... ... @@ -3144,6 +3145,31 @@
3144 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 + */
  3158 +void 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 +}
  3172 +EXPORT_SYMBOL(fc_block_scsi_eh);
3147 3173  
3148 3174 /**
3149 3175 * fc_vport_setup - allocates and creates a FC virtual port.
include/scsi/scsi_transport_fc.h
... ... @@ -807,6 +807,7 @@
807 807 struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
808 808 struct fc_vport_identifiers *);
809 809 int fc_vport_terminate(struct fc_vport *vport);
  810 +void fc_block_scsi_eh(struct scsi_cmnd *cmnd);
810 811  
811 812 #endif /* SCSI_TRANSPORT_FC_H */