diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_disc.c')
| -rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 41 | 
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 911b2736caf..880a9068ca1 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -35,6 +35,7 @@  #include <linux/timer.h>  #include <linux/slab.h>  #include <linux/err.h> +#include <linux/export.h>  #include <asm/unaligned.h>  #include <scsi/fc/fc_gs.h> @@ -60,7 +61,7 @@ static void fc_disc_restart(struct fc_disc *);   * Locking Note: This function expects that the lport mutex is locked before   * calling it.   */ -void fc_disc_stop_rports(struct fc_disc *disc) +static void fc_disc_stop_rports(struct fc_disc *disc)  {  	struct fc_lport *lport;  	struct fc_rport_priv *rdata; @@ -205,6 +206,7 @@ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp)  	default:  		FC_DISC_DBG(disc, "Received an unsupported request, "  			    "the opcode is (%x)\n", op); +		fc_frame_free(fp);  		break;  	}  } @@ -335,6 +337,13 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)  			schedule_delayed_work(&disc->disc_work, delay);  		} else  			fc_disc_done(disc, DISC_EV_FAILED); +	} else if (PTR_ERR(fp) == -FC_EX_CLOSED) { +		/* +		 * if discovery fails due to lport reset, clear +		 * pending flag so that subsequent discovery can +		 * continue +		 */ +		disc->pending = 0;  	}  } @@ -680,7 +689,7 @@ static int fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp)   * fc_disc_stop() - Stop discovery for a given lport   * @lport: The local port that discovery should stop on   */ -void fc_disc_stop(struct fc_lport *lport) +static void fc_disc_stop(struct fc_lport *lport)  {  	struct fc_disc *disc = &lport->disc; @@ -696,19 +705,20 @@ void fc_disc_stop(struct fc_lport *lport)   * This function will block until discovery has been   * completely stopped and all rports have been deleted.   */ -void fc_disc_stop_final(struct fc_lport *lport) +static void fc_disc_stop_final(struct fc_lport *lport)  {  	fc_disc_stop(lport);  	lport->tt.rport_flush_queue();  }  /** - * fc_disc_init() - Initialize the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be initialized + * fc_disc_config() - Configure the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be configured + * @priv: Private data structre for users of the discovery layer   */ -int fc_disc_init(struct fc_lport *lport) +void fc_disc_config(struct fc_lport *lport, void *priv)  { -	struct fc_disc *disc; +	struct fc_disc *disc = &lport->disc;  	if (!lport->tt.disc_start)  		lport->tt.disc_start = fc_disc_start; @@ -723,12 +733,21 @@ int fc_disc_init(struct fc_lport *lport)  		lport->tt.disc_recv_req = fc_disc_recv_req;  	disc = &lport->disc; + +	disc->priv = priv; +} +EXPORT_SYMBOL(fc_disc_config); + +/** + * fc_disc_init() - Initialize the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be initialized + */ +void fc_disc_init(struct fc_lport *lport) +{ +	struct fc_disc *disc = &lport->disc; +  	INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);  	mutex_init(&disc->disc_mutex);  	INIT_LIST_HEAD(&disc->rports); - -	disc->priv = lport; - -	return 0;  }  EXPORT_SYMBOL(fc_disc_init);  | 
