diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 494 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 48 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 121 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 73 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 98 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 40 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 34 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 112 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 3 |
13 files changed, 519 insertions, 517 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2ab2d24dcc15..ec0b0f6e5e1a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -23,7 +23,7 @@ struct lpfc_sli2_slim; -#define LPFC_MAX_TARGET 256 /* max number of targets supported */ +#define LPFC_MAX_TARGET 4096 /* max number of targets supported */ #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els requests */ #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact @@ -268,7 +268,6 @@ struct lpfc_vport { #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ #define FC_FABRIC 0x100 /* We are fabric attached */ -#define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ @@ -433,8 +432,6 @@ struct lpfc_hba { uint32_t fc_eventTag; /* event tag for link attention */ - - struct timer_list fc_estabtmo; /* link establishment timer */ /* These fields used to be binfo */ uint32_t fc_pref_DID; /* preferred D_ID */ uint8_t fc_pref_ALPA; /* preferred AL_PA */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b12a841703ca..a9fbb3f88659 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -66,23 +66,26 @@ lpfc_jedec_to_ascii(int incr, char hdw[]) } static ssize_t -lpfc_drvr_version_show(struct class_device *cdev, char *buf) +lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, + char *buf) { return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); } static ssize_t -lpfc_info_show(struct class_device *cdev, char *buf) +lpfc_info_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); + struct Scsi_Host *host = class_to_shost(dev); return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); } static ssize_t -lpfc_serialnum_show(struct class_device *cdev, char *buf) +lpfc_serialnum_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -90,18 +93,20 @@ lpfc_serialnum_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_temp_sensor_show(struct class_device *cdev, char *buf) +lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; return snprintf(buf, PAGE_SIZE, "%d\n",phba->temp_sensor_support); } static ssize_t -lpfc_modeldesc_show(struct class_device *cdev, char *buf) +lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -109,9 +114,10 @@ lpfc_modeldesc_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_modelname_show(struct class_device *cdev, char *buf) +lpfc_modelname_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -119,9 +125,10 @@ lpfc_modelname_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_programtype_show(struct class_device *cdev, char *buf) +lpfc_programtype_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -129,9 +136,10 @@ lpfc_programtype_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_vportnum_show(struct class_device *cdev, char *buf) +lpfc_vportnum_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -139,9 +147,10 @@ lpfc_vportnum_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_fwrev_show(struct class_device *cdev, char *buf) +lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; char fwrev[32]; @@ -151,10 +160,10 @@ lpfc_fwrev_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_hdw_show(struct class_device *cdev, char *buf) +lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf) { char hdw[9]; - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; lpfc_vpd_t *vp = &phba->vpd; @@ -163,18 +172,20 @@ lpfc_hdw_show(struct class_device *cdev, char *buf) return snprintf(buf, PAGE_SIZE, "%s\n", hdw); } static ssize_t -lpfc_option_rom_version_show(struct class_device *cdev, char *buf) +lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); } static ssize_t -lpfc_state_show(struct class_device *cdev, char *buf) +lpfc_state_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; int len = 0; @@ -243,9 +254,10 @@ lpfc_state_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) +lpfc_num_discovered_ports_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; return snprintf(buf, PAGE_SIZE, "%d\n", @@ -367,9 +379,10 @@ lpfc_selective_reset(struct lpfc_hba *phba) } static ssize_t -lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) +lpfc_issue_reset(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -385,9 +398,10 @@ lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) } static ssize_t -lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) +lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -395,9 +409,10 @@ lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_board_mode_show(struct class_device *cdev, char *buf) +lpfc_board_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; char * state; @@ -415,9 +430,10 @@ lpfc_board_mode_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) +lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct completion online_compl; @@ -509,9 +525,10 @@ lpfc_get_hba_info(struct lpfc_hba *phba, } static ssize_t -lpfc_max_rpi_show(struct class_device *cdev, char *buf) +lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt; @@ -522,9 +539,10 @@ lpfc_max_rpi_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_used_rpi_show(struct class_device *cdev, char *buf) +lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt, acnt; @@ -535,9 +553,10 @@ lpfc_used_rpi_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_max_xri_show(struct class_device *cdev, char *buf) +lpfc_max_xri_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt; @@ -548,9 +567,10 @@ lpfc_max_xri_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_used_xri_show(struct class_device *cdev, char *buf) +lpfc_used_xri_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt, acnt; @@ -561,9 +581,10 @@ lpfc_used_xri_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_max_vpi_show(struct class_device *cdev, char *buf) +lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt; @@ -574,9 +595,10 @@ lpfc_max_vpi_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_used_vpi_show(struct class_device *cdev, char *buf) +lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t cnt, acnt; @@ -587,9 +609,10 @@ lpfc_used_vpi_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_npiv_info_show(struct class_device *cdev, char *buf) +lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -601,9 +624,10 @@ lpfc_npiv_info_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_poll_show(struct class_device *cdev, char *buf) +lpfc_poll_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -611,10 +635,10 @@ lpfc_poll_show(struct class_device *cdev, char *buf) } static ssize_t -lpfc_poll_store(struct class_device *cdev, const char *buf, - size_t count) +lpfc_poll_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; uint32_t creg_val; @@ -670,9 +694,10 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, #define lpfc_param_show(attr) \ static ssize_t \ -lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_hba *phba = vport->phba;\ int val = 0;\ @@ -683,9 +708,10 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ #define lpfc_param_hex_show(attr) \ static ssize_t \ -lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_hba *phba = vport->phba;\ int val = 0;\ @@ -725,9 +751,10 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ #define lpfc_param_store(attr) \ static ssize_t \ -lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ +lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_hba *phba = vport->phba;\ int val=0;\ @@ -743,9 +770,10 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ #define lpfc_vport_param_show(attr) \ static ssize_t \ -lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ int val = 0;\ val = vport->cfg_##attr;\ @@ -754,9 +782,10 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ #define lpfc_vport_param_hex_show(attr) \ static ssize_t \ -lpfc_##attr##_show(struct class_device *cdev, char *buf) \ +lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ int val = 0;\ val = vport->cfg_##attr;\ @@ -794,9 +823,10 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ #define lpfc_vport_param_store(attr) \ static ssize_t \ -lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ +lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ - struct Scsi_Host *shost = class_to_shost(cdev);\ + struct Scsi_Host *shost = class_to_shost(dev);\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ int val=0;\ if (!isdigit(buf[0]))\ @@ -822,7 +852,7 @@ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_param_show(name)\ lpfc_param_init(name, defval, minval, maxval)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) +static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -832,8 +862,8 @@ lpfc_param_show(name)\ lpfc_param_init(name, defval, minval, maxval)\ lpfc_param_set(name, defval, minval, maxval)\ lpfc_param_store(name)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ - lpfc_##name##_show, lpfc_##name##_store) +static DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) #define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -841,7 +871,7 @@ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_param_hex_show(name)\ lpfc_param_init(name, defval, minval, maxval)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) +static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) #define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -851,8 +881,8 @@ lpfc_param_hex_show(name)\ lpfc_param_init(name, defval, minval, maxval)\ lpfc_param_set(name, defval, minval, maxval)\ lpfc_param_store(name)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ - lpfc_##name##_show, lpfc_##name##_store) +static DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) #define LPFC_VPORT_ATTR(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -866,7 +896,7 @@ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_vport_param_show(name)\ lpfc_vport_param_init(name, defval, minval, maxval)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) +static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) #define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -876,8 +906,8 @@ lpfc_vport_param_show(name)\ lpfc_vport_param_init(name, defval, minval, maxval)\ lpfc_vport_param_set(name, defval, minval, maxval)\ lpfc_vport_param_store(name)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ - lpfc_##name##_show, lpfc_##name##_store) +static DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) #define LPFC_VPORT_ATTR_HEX_R(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -885,7 +915,7 @@ module_param(lpfc_##name, int, 0);\ MODULE_PARM_DESC(lpfc_##name, desc);\ lpfc_vport_param_hex_show(name)\ lpfc_vport_param_init(name, defval, minval, maxval)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) +static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) #define LPFC_VPORT_ATTR_HEX_RW(name, defval, minval, maxval, desc) \ static int lpfc_##name = defval;\ @@ -895,46 +925,44 @@ lpfc_vport_param_hex_show(name)\ lpfc_vport_param_init(name, defval, minval, maxval)\ lpfc_vport_param_set(name, defval, minval, maxval)\ lpfc_vport_param_store(name)\ -static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ - lpfc_##name##_show, lpfc_##name##_store) - -static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); -static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); -static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); -static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); -static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); -static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL); -static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); -static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); -static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL); -static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO, - lpfc_option_rom_version_show, NULL); -static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO, - lpfc_num_discovered_ports_show, NULL); -static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); -static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, - NULL); -static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, - lpfc_board_mode_show, lpfc_board_mode_store); -static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); -static CLASS_DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL); -static CLASS_DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL); -static CLASS_DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL); -static CLASS_DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL); -static CLASS_DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); -static CLASS_DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); -static CLASS_DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); -static CLASS_DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, - NULL); +static DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ + lpfc_##name##_show, lpfc_##name##_store) + +static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); +static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); +static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); +static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); +static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); +static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL); +static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); +static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); +static DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL); +static DEVICE_ATTR(option_rom_version, S_IRUGO, + lpfc_option_rom_version_show, NULL); +static DEVICE_ATTR(num_discovered_ports, S_IRUGO, + lpfc_num_discovered_ports_show, NULL); +static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); +static DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); +static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, + lpfc_board_mode_show, lpfc_board_mode_store); +static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); +static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL); +static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL); +static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL); +static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL); +static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); +static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); +static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); +static DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, NULL); static char *lpfc_soft_wwn_key = "C99G71SL8032A"; static ssize_t -lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, - size_t count) +lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; unsigned int cnt = count; @@ -963,13 +991,14 @@ lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, phba->soft_wwn_enable = 1; return count; } -static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, - lpfc_soft_wwn_enable_store); +static DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, + lpfc_soft_wwn_enable_store); static ssize_t -lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) +lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -979,9 +1008,10 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) static ssize_t -lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) +lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct completion online_compl; @@ -1047,13 +1077,14 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) "reinit adapter - %d\n", stat2); return (stat1 || stat2) ? -EIO : count; } -static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ - lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); +static DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ + lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); static ssize_t -lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) +lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)phba->cfg_soft_wwnn); @@ -1061,9 +1092,10 @@ lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) static ssize_t -lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) +lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; unsigned int i, j, cnt=count; u8 wwnn[8]; @@ -1107,8 +1139,8 @@ lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) return count; } -static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ - lpfc_soft_wwnn_show, lpfc_soft_wwnn_store); +static DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ + lpfc_soft_wwnn_show, lpfc_soft_wwnn_store); static int lpfc_poll = 0; @@ -1118,8 +1150,8 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" " 1 - poll with interrupts enabled" " 3 - poll and disable FCP ring interrupts"); -static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, - lpfc_poll_show, lpfc_poll_store); +static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, + lpfc_poll_show, lpfc_poll_store); int lpfc_sli_mode = 0; module_param(lpfc_sli_mode, int, 0); @@ -1133,7 +1165,7 @@ module_param(lpfc_enable_npiv, int, 0); MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); lpfc_param_show(enable_npiv); lpfc_param_init(enable_npiv, 0, 0, 1); -static CLASS_DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, +static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, lpfc_enable_npiv_show, NULL); /* @@ -1147,9 +1179,10 @@ MODULE_PARM_DESC(lpfc_nodev_tmo, "Seconds driver will hold I/O waiting " "for a device to come back"); static ssize_t -lpfc_nodev_tmo_show(struct class_device *cdev, char *buf) +lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; int val = 0; val = vport->cfg_devloss_tmo; @@ -1221,8 +1254,8 @@ lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) lpfc_vport_param_store(nodev_tmo) -static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR, - lpfc_nodev_tmo_show, lpfc_nodev_tmo_store); +static DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR, + lpfc_nodev_tmo_show, lpfc_nodev_tmo_store); /* # lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that @@ -1255,8 +1288,8 @@ lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val) } lpfc_vport_param_store(devloss_tmo) -static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, - lpfc_devloss_tmo_show, lpfc_devloss_tmo_store); +static DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, + lpfc_devloss_tmo_show, lpfc_devloss_tmo_store); /* # lpfc_log_verbose: Only turn this flag on if you are willing to risk being @@ -1374,8 +1407,8 @@ lpfc_restrict_login_set(struct lpfc_vport *vport, int val) return 0; } lpfc_vport_param_store(restrict_login); -static CLASS_DEVICE_ATTR(lpfc_restrict_login, S_IRUGO | S_IWUSR, - lpfc_restrict_login_show, lpfc_restrict_login_store); +static DEVICE_ATTR(lpfc_restrict_login, S_IRUGO | S_IWUSR, + lpfc_restrict_login_show, lpfc_restrict_login_store); /* # Some disk devices have a "select ID" or "select Target" capability. @@ -1433,7 +1466,7 @@ MODULE_PARM_DESC(lpfc_topology, "Select Fibre Channel topology"); lpfc_param_show(topology) lpfc_param_init(topology, 0, 0, 6) lpfc_param_store(topology) -static CLASS_DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, lpfc_topology_show, lpfc_topology_store); /* @@ -1497,7 +1530,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val) } lpfc_param_store(link_speed) -static CLASS_DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, lpfc_link_speed_show, lpfc_link_speed_store); /* @@ -1623,82 +1656,81 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count"); -struct class_device_attribute *lpfc_hba_attrs[] = { - &class_device_attr_info, - &class_device_attr_serialnum, - &class_device_attr_modeldesc, - &class_device_attr_modelname, - &class_device_attr_programtype, - &class_device_attr_portnum, - &class_device_attr_fwrev, - &class_device_attr_hdw, - &class_device_attr_option_rom_version, - &class_device_attr_state, - &class_device_attr_num_discovered_ports, - &class_device_attr_lpfc_drvr_version, - &class_device_attr_lpfc_temp_sensor, - &class_device_attr_lpfc_log_verbose, - &class_device_attr_lpfc_lun_queue_depth, - &class_device_attr_lpfc_hba_queue_depth, - &class_device_attr_lpfc_peer_port_login, - &class_device_attr_lpfc_nodev_tmo, - &class_device_attr_lpfc_devloss_tmo, - &class_device_attr_lpfc_fcp_class, - &class_device_attr_lpfc_use_adisc, - &class_device_attr_lpfc_ack0, - &class_device_attr_lpfc_topology, - &class_device_attr_lpfc_scan_down, - &class_device_attr_lpfc_link_speed, - &class_device_attr_lpfc_cr_delay, - &class_device_attr_lpfc_cr_count, - &class_device_attr_lpfc_multi_ring_support, - &class_device_attr_lpfc_multi_ring_rctl, - &class_device_attr_lpfc_multi_ring_type, - &class_device_attr_lpfc_fdmi_on, - &class_device_attr_lpfc_max_luns, - &class_device_attr_lpfc_enable_npiv, - &class_device_attr_nport_evt_cnt, - &class_device_attr_board_mode, - &class_device_attr_max_vpi, - &class_device_attr_used_vpi, - &class_device_attr_max_rpi, - &class_device_attr_used_rpi, - &class_device_attr_max_xri, - &class_device_attr_used_xri, - &class_device_attr_npiv_info, - &class_device_attr_issue_reset, - &class_device_attr_lpfc_poll, - &class_device_attr_lpfc_poll_tmo, - &class_device_attr_lpfc_use_msi, - &class_device_attr_lpfc_soft_wwnn, - &class_device_attr_lpfc_soft_wwpn, - &class_device_attr_lpfc_soft_wwn_enable, - &class_device_attr_lpfc_enable_hba_reset, - &class_device_attr_lpfc_enable_hba_heartbeat, - &class_device_attr_lpfc_sg_seg_cnt, +struct device_attribute *lpfc_hba_attrs[] = { + &dev_attr_info, + &dev_attr_serialnum, + &dev_attr_modeldesc, + &dev_attr_modelname, + &dev_attr_programtype, + &dev_attr_portnum, + &dev_attr_fwrev, + &dev_attr_hdw, + &dev_attr_option_rom_version, + &dev_attr_state, + &dev_attr_num_discovered_ports, + &dev_attr_lpfc_drvr_version, + &dev_attr_lpfc_temp_sensor, + &dev_attr_lpfc_log_verbose, + &dev_attr_lpfc_lun_queue_depth, + &dev_attr_lpfc_hba_queue_depth, + &dev_attr_lpfc_peer_port_login, + &dev_attr_lpfc_nodev_tmo, + &dev_attr_lpfc_devloss_tmo, + &dev_attr_lpfc_fcp_class, + &dev_attr_lpfc_use_adisc, + &dev_attr_lpfc_ack0, + &dev_attr_lpfc_topology, + &dev_attr_lpfc_scan_down, + &dev_attr_lpfc_link_speed, + &dev_attr_lpfc_cr_delay, + &dev_attr_lpfc_cr_count, + &dev_attr_lpfc_multi_ring_support, + &dev_attr_lpfc_multi_ring_rctl, + &dev_attr_lpfc_multi_ring_type, + &dev_attr_lpfc_fdmi_on, + &dev_attr_lpfc_max_luns, + &dev_attr_lpfc_enable_npiv, + &dev_attr_nport_evt_cnt, + &dev_attr_board_mode, + &dev_attr_max_vpi, + &dev_attr_used_vpi, + &dev_attr_max_rpi, + &dev_attr_used_rpi, + &dev_attr_max_xri, + &dev_attr_used_xri, + &dev_attr_npiv_info, + &dev_attr_issue_reset, + &dev_attr_lpfc_poll, + &dev_attr_lpfc_poll_tmo, + &dev_attr_lpfc_use_msi, + &dev_attr_lpfc_soft_wwnn, + &dev_attr_lpfc_soft_wwpn, + &dev_attr_lpfc_soft_wwn_enable, + &dev_attr_lpfc_enable_hba_reset, + &dev_attr_lpfc_enable_hba_heartbeat, + &dev_attr_lpfc_sg_seg_cnt, NULL, }; -struct class_device_attribute *lpfc_vport_attrs[] = { - &class_device_attr_info, - &class_device_attr_state, - &class_device_attr_num_discovered_ports, - &class_device_attr_lpfc_drvr_version, - - &class_device_attr_lpfc_log_verbose, - &class_device_attr_lpfc_lun_queue_depth, - &class_device_attr_lpfc_nodev_tmo, - &class_device_attr_lpfc_devloss_tmo, - &class_device_attr_lpfc_hba_queue_depth, - &class_device_attr_lpfc_peer_port_login, - &class_device_attr_lpfc_restrict_login, - &class_device_attr_lpfc_fcp_class, - &class_device_attr_lpfc_use_adisc, - &class_device_attr_lpfc_fdmi_on, - &class_device_attr_lpfc_max_luns, - &class_device_attr_nport_evt_cnt, - &class_device_attr_npiv_info, - &class_device_attr_lpfc_enable_da_id, +struct device_attribute *lpfc_vport_attrs[] = { + &dev_attr_info, + &dev_attr_state, + &dev_attr_num_discovered_ports, + &dev_attr_lpfc_drvr_version, + &dev_attr_lpfc_log_verbose, + &dev_attr_lpfc_lun_queue_depth, + &dev_attr_lpfc_nodev_tmo, + &dev_attr_lpfc_devloss_tmo, + &dev_attr_lpfc_hba_queue_depth, + &dev_attr_lpfc_peer_port_login, + &dev_attr_lpfc_restrict_login, + &dev_attr_lpfc_fcp_class, + &dev_attr_lpfc_use_adisc, + &dev_attr_lpfc_fdmi_on, + &dev_attr_lpfc_max_luns, + &dev_attr_nport_evt_cnt, + &dev_attr_npiv_info, + &dev_attr_lpfc_enable_da_id, NULL, }; @@ -1707,9 +1739,8 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { size_t buf_off; - struct class_device *cdev = container_of(kobj, struct class_device, - kobj); - struct Scsi_Host *shost = class_to_shost(cdev); + struct device *dev = container_of(kobj, struct device, kobj); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -1741,9 +1772,8 @@ sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr, { size_t buf_off; uint32_t * tmp_ptr; - struct class_device *cdev = container_of(kobj, struct class_device, - kobj); - struct Scsi_Host *shost = class_to_shost(cdev); + struct device *dev = container_of(kobj, struct device, kobj); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; @@ -1798,9 +1828,8 @@ static ssize_t sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct class_device *cdev = container_of(kobj, struct class_device, - kobj); - struct Scsi_Host *shost = class_to_shost(cdev); + struct device *dev = container_of(kobj, struct device, kobj); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct lpfcMboxq *mbox = NULL; @@ -1853,9 +1882,8 @@ static ssize_t sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct class_device *cdev = container_of(kobj, struct class_device, - kobj); - struct Scsi_Host *shost = class_to_shost(cdev); + struct device *dev = container_of(kobj, struct device, kobj); + struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; int rc; @@ -1954,7 +1982,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, (phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY && phba->sysfs_mbox.mbox->mb.mbxCommand != - MBX_RESTART)) { + MBX_RESTART && + phba->sysfs_mbox.mbox->mb.mbxCommand != + MBX_WRITE_VPARMS)) { sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EPERM; @@ -1962,7 +1992,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, phba->sysfs_mbox.mbox->vport = vport; - if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { + /* Don't allow mailbox commands to be sent when blocked + * or when in the middle of discovery + */ + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || + vport->fc_flag & FC_NDISC_ACTIVE) { sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EAGAIN; @@ -2032,19 +2066,19 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) struct Scsi_Host *shost = lpfc_shost_from_vport(vport); int error; - error = sysfs_create_bin_file(&shost->shost_classdev.kobj, + error = sysfs_create_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); if (error) goto out; - error = sysfs_create_bin_file(&shost->shost_classdev.kobj, + error = sysfs_create_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); if (error) goto out_remove_ctlreg_attr; return 0; out_remove_ctlreg_attr: - sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); + sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); out: return error; } @@ -2054,8 +2088,8 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); - sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); + sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); + sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); } @@ -2437,9 +2471,11 @@ lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) #define lpfc_rport_show_function(field, format_string, sz, cast) \ static ssize_t \ -lpfc_show_rport_##field (struct class_device *cdev, char *buf) \ +lpfc_show_rport_##field (struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ { \ - struct fc_rport *rport = transport_class_to_rport(cdev); \ + struct fc_rport *rport = transport_class_to_rport(dev); \ struct lpfc_rport_data *rdata = rport->hostdata; \ return snprintf(buf, sz, format_string, \ (rdata->target) ? cast rdata->target->field : 0); \ diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 0819f5f39de5..7c9f8317d972 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -253,8 +253,8 @@ void lpfc_get_cfgparam(struct lpfc_hba *); void lpfc_get_vport_cfgparam(struct lpfc_vport *); int lpfc_alloc_sysfs_attr(struct lpfc_vport *); void lpfc_free_sysfs_attr(struct lpfc_vport *); -extern struct class_device_attribute *lpfc_hba_attrs[]; -extern struct class_device_attribute *lpfc_vport_attrs[]; +extern struct device_attribute *lpfc_hba_attrs[]; +extern struct device_attribute *lpfc_vport_attrs[]; extern struct scsi_host_template lpfc_template; extern struct scsi_host_template lpfc_vport_template; extern struct fc_function_template lpfc_transport_functions; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 3d0ccd9b341d..153afae567b5 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, { if (!mp) { lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "0146 Ignoring unsolicted CT No HBQ " + "0146 Ignoring unsolicited CT No HBQ " "status = x%x\n", piocbq->iocb.ulpStatus); } @@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) (!(vport->ct_flags & FC_CT_RFF_ID)) || (!vport->cfg_restrict_login)) { ndlp = lpfc_setup_disc_node(vport, Did); - if (ndlp) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, "Parse GID_FTrsp: " @@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *outp; struct lpfc_sli_ct_request *CTrsp; struct lpfc_nodelist *ndlp; - int rc, retry; + int rc; /* First save ndlp, before we overwrite it */ ndlp = cmdiocb->context_un.ndlp; @@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (vport->load_flag & FC_UNLOADING) goto out; - if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { + if (lpfc_els_chk_latt(vport)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0216 Link event during NS query\n"); lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } - + if (lpfc_error_lost_link(irsp)) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "0226 NS query failed due to link event\n"); + goto out; + } if (irsp->ulpStatus) { /* Check for retry */ if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { - retry = 1; - if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { - switch (irsp->un.ulpWord[4]) { - case IOERR_NO_RESOURCES: - /* We don't increment the retry - * count for this case. - */ - break; - case IOERR_LINK_DOWN: - case IOERR_SLI_ABORTED: - case IOERR_SLI_DOWN: - retry = 0; - break; - default: - vport->fc_ns_retry++; - } - } - else + if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || + irsp->un.ulpWord[4] != IOERR_NO_RESOURCES) vport->fc_ns_retry++; - if (retry) { - /* CT command is being retried */ - rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, + /* CT command is being retried */ + rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, vport->fc_ns_retry, 0); - if (rc == 0) { - /* success */ - goto out; - } - } + if (rc == 0) + goto out; } lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, @@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* This is a target port, unregistered port, or the GFF_ID failed */ ndlp = lpfc_setup_disc_node(vport, did); - if (ndlp) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0242 Process x%x GFF " "NameServer Rsp Data: x%x x%x x%x\n", diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 783d1eea13ef..90272e65957a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) ndlp->nlp_sid); if (ndlp->nlp_type & NLP_FCP_INITIATOR) len += snprintf(buf+len, size-len, "FCP_INITIATOR "); + len += snprintf(buf+len, size-len, "usgmap:%x ", + ndlp->nlp_usg_map); len += snprintf(buf+len, size-len, "refcnt:%x", atomic_read(&ndlp->kref.refcount)); len += snprintf(buf+len, size-len, "\n"); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cbb68a942255..886c5f1b11d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && icmd->un.elsreq64.bdl.ulpIoTag32) { ndlp = (struct lpfc_nodelist *)(iocb->context1); - if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp) && + (ndlp->nlp_DID == Fabric_DID)) lpfc_sli_issue_abort_iotag(phba, pring, iocb); - } } } spin_unlock_irq(&phba->hbalock); @@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, struct fc_rport *rport; struct serv_parm *sp; uint8_t name[sizeof(struct lpfc_name)]; - uint32_t rc; + uint32_t rc, keepDID = 0; /* Fabric nodes can have the same WWPN so we don't bother searching * by WWPN. Just return the ndlp that was given to us. @@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, return ndlp; lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { + rc = memcmp(&ndlp->nlp_portname, name, + sizeof(struct lpfc_name)); + if (!rc) + return ndlp; new_ndlp = lpfc_enable_node(vport, new_ndlp, NLP_STE_UNUSED_NODE); if (!new_ndlp) return ndlp; - } + keepDID = new_ndlp->nlp_DID; + } else + keepDID = new_ndlp->nlp_DID; lpfc_unreg_rpi(vport, new_ndlp); new_ndlp->nlp_DID = ndlp->nlp_DID; @@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, } new_ndlp->nlp_type = ndlp->nlp_type; } + /* We shall actually free the ndlp with both nlp_DID and + * nlp_portname fields equals 0 to avoid any ndlp on the + * nodelist never to be used. + */ + if (ndlp->nlp_DID == 0) { + spin_lock_irq(&phba->ndlp_lock); + NLP_SET_FREE_REQ(ndlp); + spin_unlock_irq(&phba->ndlp_lock); + } + /* Two ndlps cannot have the same did on the nodelist */ + ndlp->nlp_DID = keepDID; lpfc_drop_node(vport, ndlp); } else { lpfc_unreg_rpi(vport, ndlp); - ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ + /* Two ndlps cannot have the same did */ + ndlp->nlp_DID = keepDID; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); } return new_ndlp; @@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } phba->fc_stat.elsXmitRetry++; - if (ndlp && delay) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) { phba->fc_stat.elsDelayRetry++; ndlp->nlp_retry = cmdiocb->retry; @@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); return 1; case ELS_CMD_PLOGI: - if (ndlp) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); @@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); - if (ndlp) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { lpfc_nlp_put(ndlp); /* This is the end of the default RPI cleanup logic for this * ndlp. If no other discovery threads are using this ndlp. @@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * function can have cmdiocb->contest1 (ndlp) field set to NULL. */ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); - if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp) && + (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { /* A LS_RJT associated with Default RPI cleanup has its own * seperate code path. */ @@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } /* Check to see if link went down during discovery */ - if (!ndlp || lpfc_els_chk_latt(vport)) { + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) { if (mbox) { mp = (struct lpfc_dmabuf *) mbox->context1; if (mp) { @@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } mempool_free(mbox, phba->mbox_mem_pool); } - if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) + if (ndlp && NLP_CHK_NODE_ACT(ndlp) && + (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) if (lpfc_nlp_not_used(ndlp)) { ndlp = NULL; /* Indicate the node has already released, @@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, mempool_free(mbox, phba->mbox_mem_pool); } out: - if (ndlp) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); spin_unlock_irq(shost->host_lock); @@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, /* Another thread is walking fc_rscn_id_list on this vport */ spin_unlock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_DISCOVERY; + /* Send back ACC */ + lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); return 0; } /* Indicate we are walking fc_rscn_id_list on this vport */ @@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) else { struct lpfc_nodelist *ndlp; ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); - if (ndlp) + if (ndlp && NLP_CHK_NODE_ACT(ndlp)) remote_ID = ndlp->nlp_DID; } lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, @@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, newnode = 1; if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) ndlp->nlp_type |= NLP_FABRIC; - } else { - if (!NLP_CHK_NODE_ACT(ndlp)) { - ndlp = lpfc_enable_node(vport, ndlp, - NLP_STE_UNUSED_NODE); - if (!ndlp) - goto dropit; - } - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { - /* This is simular to the new node path */ - ndlp = lpfc_nlp_get(ndlp); - if (!ndlp) - goto dropit; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); - newnode = 1; - } + } else if (!NLP_CHK_NODE_ACT(ndlp)) { + ndlp = lpfc_enable_node(vport, ndlp, + NLP_STE_UNUSED_NODE); + if (!ndlp) + goto dropit; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); + newnode = 1; + if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) + ndlp->nlp_type |= NLP_FABRIC; + } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { + /* This is similar to the new node path */ + ndlp = lpfc_nlp_get(ndlp); + if (!ndlp) + goto dropit; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); + newnode = 1; } phba->fc_stat.elsRcvFrame++; @@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } lpfc_nlp_init(vport, ndlp, NameServer_DID); - ndlp->nlp_type |= NLP_FABRIC; } else if (!NLP_CHK_NODE_ACT(ndlp)) { ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); if (!ndlp) { @@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) return; } } + ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); @@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) if (ndlp_fdmi) { lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); ndlp_fdmi->nlp_type |= NLP_FABRIC; - ndlp_fdmi->nlp_state = - NLP_STE_PLOGI_ISSUE; + lpfc_nlp_set_state(vport, ndlp_fdmi, + NLP_STE_PLOGI_ISSUE); lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0); } @@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) (piocb->iocb_cmpl) (phba, piocb, piocb); } } - - -#if 0 -void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) -{ - LIST_HEAD(completions); - struct lpfc_iocbq *tmp_iocb, *piocb; - IOCB_t *cmd; - struct lpfc_nodelist *ndlp; - - spin_lock_irq(&phba->hbalock); - list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list, - list) { - - cmd = &piocb->iocb; - ndlp = (struct lpfc_nodelist *) piocb->context1; - if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR && - ndlp != NULL && - ndlp->nlp_DID == Fabric_DID) - list_move_tail(&piocb->list, &completions); - } - spin_unlock_irq(&phba->hbalock); - - while (!list_empty(&completions)) { - piocb = list_get_first(&completions, struct lpfc_iocbq, list); - list_del_init(&piocb->list); - - cmd = &piocb->iocb; - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - (piocb->iocb_cmpl) (phba, piocb, piocb); - } -} -#endif /* 0 */ - - diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 976653440fba..7cb68feb04fd 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport) rdata = rport->dd_data; ndlp = rdata->pnode; - if (!ndlp) { + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) printk(KERN_ERR "Cannot find remote node" " to terminate I/O Data x%x\n", @@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) rdata = rport->dd_data; ndlp = rdata->pnode; - if (!ndlp) + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) return; vport = ndlp->vport; @@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) if (warn_on) { lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, "0203 Devloss timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", + "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " + "NPort x%06x Data: x%x x%x x%x\n", *name, *(name+1), *(name+2), *(name+3), *(name+4), *(name+5), *(name+6), *(name+7), ndlp->nlp_DID, ndlp->nlp_flag, @@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) } else { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0204 Devloss timeout on " - "WWPN %x:%x:%x:%x:%x:%x:%x:%x " - "NPort x%x Data: x%x x%x x%x\n", + "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " + "NPort x%06x Data: x%x x%x x%x\n", *name, *(name+1), *(name+2), *(name+3), *(name+4), *(name+5), *(name+6), *(name+7), ndlp->nlp_DID, ndlp->nlp_flag, @@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba) vport = vports[i]; if (vport == NULL) break; + spin_lock_irq(&vport->work_port_lock); work_port_events = vport->work_port_events; + vport->work_port_events &= ~work_port_events; + spin_unlock_irq(&vport->work_port_lock); if (work_port_events & WORKER_DISC_TMO) lpfc_disc_timeout_handler(vport); if (work_port_events & WORKER_ELS_TMO) @@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba) lpfc_ramp_down_queue_handler(phba); if (work_port_events & WORKER_RAMP_UP_QUEUE) lpfc_ramp_up_queue_handler(phba); - spin_lock_irq(&vport->work_port_lock); - vport->work_port_events &= ~work_port_events; - spin_unlock_irq(&vport->work_port_lock); } lpfc_destroy_vport_work_array(phba, vports); @@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba) if (pring->flag & LPFC_STOP_IOCB_EVENT) { pring->flag |= LPFC_DEFERRED_RING_EVENT; } else { + pring->flag &= ~LPFC_DEFERRED_RING_EVENT; lpfc_sli_handle_slow_ring_event(phba, pring, (status & HA_RXMASK)); - pring->flag &= ~LPFC_DEFERRED_RING_EVENT; } /* * Turn on Ring interrupts @@ -519,7 +519,9 @@ lpfc_do_work(void *p) schedule(); } } + spin_lock_irq(&phba->hbalock); phba->work_wait = NULL; + spin_unlock_irq(&phba->hbalock); return 0; } @@ -809,11 +811,9 @@ out: mempool_free(pmb, phba->mbox_mem_pool); spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); + vport->fc_flag &= ~FC_ABORT_DISCOVERY; spin_unlock_irq(shost->host_lock); - del_timer_sync(&phba->fc_estabtmo); - lpfc_can_disctmo(vport); /* turn on Link Attention interrupts */ @@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) i++) { if (vports[i]->port_type == LPFC_PHYSICAL_PORT) continue; + if (phba->fc_topology == TOPOLOGY_LOOP) { + lpfc_vport_set_state(vports[i], + FC_VPORT_LINKDOWN); + continue; + } if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) lpfc_initial_fdisc(vports[i]); - else if (phba->sli3_options & - LPFC_SLI3_NPIV_ENABLED) { + else { lpfc_vport_set_state(vports[i], FC_VPORT_NO_FABRIC_SUPP); lpfc_printf_vlog(vport, KERN_ERR, @@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (did == Bcast_DID) return 0; - if (ndlp->nlp_DID == 0) { - return 0; - } - /* First check for Direct match */ if (ndlp->nlp_DID == did) return 1; @@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) return ndlp; } - if (vport->fc_flag & FC_RSCN_MODE) { + if ((vport->fc_flag & FC_RSCN_MODE) && + !(vport->fc_flag & FC_NDISC_ACTIVE)) { if (lpfc_rscn_payload_check(vport, did)) { /* If we've already recieved a PLOGI from this NPort * we don't need to try to discover it again. @@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) return NULL; } -#if 0 -/* - * Search node lists for a remote port matching filter criteria - * Caller needs to hold host_lock before calling this routine. - */ -struct lpfc_nodelist * -lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) -{ - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_nodelist *ndlp; - - spin_lock_irq(shost->host_lock); - ndlp = __lpfc_find_node(vport, filter, param); - spin_unlock_irq(shost->host_lock); - return ndlp; -} -#endif /* 0 */ - /* * This routine looks up the ndlp lists for the given RPI. If rpi found it * returns the node list element pointer else return NULL. @@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); } -#if 0 -struct lpfc_nodelist * -lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) -{ - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - struct lpfc_nodelist *ndlp; - - spin_lock_irq(shost->host_lock); - ndlp = __lpfc_findnode_rpi(vport, rpi); - spin_unlock_irq(shost->host_lock); - return ndlp; -} -#endif /* 0 */ - /* * This routine looks up the ndlp lists for the given WWPN. If WWPN found it * returns the node element list pointer else return NULL. diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 22843751c2ca..fa757b251f82 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr) phba->pport->work_port_events |= WORKER_HB_TMO; spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); + spin_lock_irqsave(&phba->hbalock, iflag); if (phba->work_wait) wake_up(phba->work_wait); + spin_unlock_irqrestore(&phba->hbalock, iflag); return; } @@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba) struct lpfc_vport *vport = phba->pport; struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; - struct lpfc_vport **vports; uint32_t event_data; unsigned long temperature; struct temp_event temp_event_data; struct Scsi_Host *shost; - int i; /* If the pci channel is offline, ignore possible errors, * since we cannot communicate with the pci card anyway. */ @@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) if (!phba->cfg_enable_hba_reset) return; - if (phba->work_hs & HS_FFER6 || - phba->work_hs & HS_FFER5) { + if (phba->work_hs & HS_FFER6) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, "1301 Re-establishing Link " "Data: x%x x%x x%x\n", phba->work_hs, phba->work_status[0], phba->work_status[1]); - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) - for(i = 0; - i <= phba->max_vpi && vports[i] != NULL; - i++){ - shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); - vports[i]->fc_flag |= FC_ESTABLISH_LINK; - spin_unlock_irq(shost->host_lock); - } - lpfc_destroy_vport_work_array(phba, vports); + spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); @@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) pring = &psli->ring[psli->fcp_ring]; lpfc_sli_abort_iocb_ring(phba, pring); - /* * There was a firmware error. Take the hba offline and then * attempt to restart it. @@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) lpfc_offline(phba); lpfc_sli_brdrestart(phba); if (lpfc_online(phba) == 0) { /* Initialize the HBA */ - mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); lpfc_unblock_mgmt_io(phba); return; } @@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport) NLP_SET_FREE_REQ(ndlp); spin_unlock_irq(&phba->ndlp_lock); + if (vport->port_type != LPFC_PHYSICAL_PORT && + ndlp->nlp_DID == Fabric_DID) { + /* Just free up ndlp with Fabric_DID for vports */ + lpfc_nlp_put(ndlp); + continue; + } + if (ndlp->nlp_type & NLP_FABRIC) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); @@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport) return; } -static void -lpfc_establish_link_tmo(unsigned long ptr) -{ - struct lpfc_hba *phba = (struct lpfc_hba *) ptr; - struct lpfc_vport **vports; - unsigned long iflag; - int i; - - /* Re-establishing Link, timer expired */ - lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "1300 Re-establishing Link, timer expired " - "Data: x%x x%x\n", - phba->pport->fc_flag, phba->pport->port_state); - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) - for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - struct Scsi_Host *shost; - shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irqsave(shost->host_lock, iflag); - vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; - spin_unlock_irqrestore(shost->host_lock, iflag); - } - lpfc_destroy_vport_work_array(phba, vports); -} - void lpfc_stop_vport_timers(struct lpfc_vport *vport) { @@ -1529,7 +1498,6 @@ static void lpfc_stop_phba_timers(struct lpfc_hba *phba) { del_timer_sync(&phba->fcp_poll_timer); - del_timer_sync(&phba->fc_estabtmo); lpfc_stop_vport_timers(phba->pport); del_timer_sync(&phba->sli.mbox_tmo); del_timer_sync(&phba->fabric_block_timer); @@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->max_vpi = LPFC_MAX_VPI; /* Initialize timers used by driver */ - init_timer(&phba->fc_estabtmo); - phba->fc_estabtmo.function = lpfc_establish_link_tmo; - phba->fc_estabtmo.data = (unsigned long)phba; - init_timer(&phba->hb_tmofunc); phba->hb_tmofunc.function = lpfc_hb_timeout; phba->hb_tmofunc.data = (unsigned long)phba; @@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; struct lpfc_sli *psli = &phba->sli; + int error, retval; dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); if (pci_enable_device_mem(pdev)) { @@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) pci_set_master(pdev); - /* Re-establishing Link */ - spin_lock_irq(shost->host_lock); - phba->pport->fc_flag |= FC_ESTABLISH_LINK; - spin_unlock_irq(shost->host_lock); - spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); + /* Enable configured interrupt method */ + phba->intr_type = NONE; + if (phba->cfg_use_msi == 2) { + error = lpfc_enable_msix(phba); + if (!error) + phba->intr_type = MSIX; + } + + /* Fallback to MSI if MSI-X initialization failed */ + if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { + retval = pci_enable_msi(phba->pcidev); + if (!retval) + phba->intr_type = MSI; + else + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "0470 Enable MSI failed, continuing " + "with IRQ\n"); + } + + /* MSI-X is the only case the doesn't need to call request_irq */ + if (phba->intr_type != MSIX) { + retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, + IRQF_SHARED, LPFC_DRIVER_NAME, phba); + if (retval) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "0471 Enable interrupt handler " + "failed\n"); + } else if (phba->intr_type != MSI) + phba->intr_type = INTx; + } /* Take device offline; this will perform cleanup */ lpfc_offline(phba); @@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; - if (lpfc_online(phba) == 0) { - mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); - } + lpfc_online(phba); } static struct pci_device_id lpfc_id_table[] = { diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d513813f6697..d08c4c890744 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_unlock_irq(shost->host_lock); if ((ndlp->nlp_flag & NLP_ADISC_SND) && - (vport->num_disc_nodes)) { + (vport->num_disc_nodes)) { /* Check to see if there are more * ADISCs to be sent */ @@ -469,20 +469,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_end_rscn(vport); } } - else if (vport->num_disc_nodes) { - /* Check to see if there are more - * PLOGIs to be sent - */ - lpfc_more_plogi(vport); - - if (vport->num_disc_nodes == 0) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(shost->host_lock); - lpfc_can_disctmo(vport); - lpfc_end_rscn(vport); - } - } + } + } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && + (ndlp->nlp_flag & NLP_NPR_2B_DISC) && + (vport->num_disc_nodes)) { + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + spin_unlock_irq(shost->host_lock); + /* Check to see if there are more + * PLOGIs to be sent + */ + lpfc_more_plogi(vport); + if (vport->num_disc_nodes == 0) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(shost->host_lock); + lpfc_can_disctmo(vport); + lpfc_end_rscn(vport); } } @@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, lp = (uint32_t *) prsp->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); - if (wwn_to_u64(sp->portName.u.wwn) == 0 || - wwn_to_u64(sp->nodeName.u.wwn) == 0) { + + /* Some switches have FDMI servers returning 0 for WWN */ + if ((ndlp->nlp_DID != FDMI_DID) && + (wwn_to_u64(sp->portName.u.wwn) == 0 || + wwn_to_u64(sp->nodeName.u.wwn) == 0)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "0142 PLOGI RSP: Invalid WWN.\n"); goto out; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 70255c11d3ad..0910a9ab76a5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); shost_for_each_device(sdev, shost) { + if (vports[i]->cfg_lun_queue_depth <= + sdev->queue_depth) + continue; if (sdev->ordered_tags) scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, @@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, lpfc_cmd->result == IOERR_NO_RESOURCES || lpfc_cmd->result == RJT_LOGIN_REQUIRED) { cmd->result = ScsiResult(DID_REQUEUE, 0); - break; - } /* else: fall through */ + break; + } /* else: fall through */ default: cmd->result = ScsiResult(DID_ERROR, 0); break; } - if ((pnode == NULL ) + if (!pnode || !NLP_CHK_NODE_ACT(pnode) || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); } else { @@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, result = cmd->result; sdev = cmd->device; lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); + spin_lock_irqsave(sdev->host->host_lock, flags); + lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */ + spin_unlock_irqrestore(sdev->host->host_lock, flags); cmd->scsi_done(cmd); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { @@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * wake up the thread. */ spin_lock_irqsave(sdev->host->host_lock, flags); - lpfc_cmd->pCmd = NULL; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock_irqrestore(sdev->host->host_lock, flags); @@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, if (!result) lpfc_rampup_queue_depth(vport, sdev); - if (!result && pnode != NULL && + if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && ((jiffies - pnode->last_ramp_up_time) > LPFC_Q_RAMP_UP_INTERVAL * HZ) && ((jiffies - pnode->last_q_full_time) > @@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * Check for queue full. If the lun is reporting queue full, then * back off the lun queue depth to prevent target overloads. */ - if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { + if (result == SAM_STAT_TASK_SET_FULL && pnode && + NLP_CHK_NODE_ACT(pnode)) { pnode->last_q_full_time = jiffies; shost_for_each_device(tmp_sdev, sdev->host) { @@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * wake up the thread. */ spin_lock_irqsave(sdev->host->host_lock, flags); - lpfc_cmd->pCmd = NULL; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock_irqrestore(sdev->host->host_lock, flags); @@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, int datadir = scsi_cmnd->sc_data_direction; char tag[2]; + if (!pnode || !NLP_CHK_NODE_ACT(pnode)) + return; + lpfc_cmd->fcp_rsp->rspSnsLen = 0; /* clear task management bits */ lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; @@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, struct lpfc_rport_data *rdata = lpfc_cmd->rdata; struct lpfc_nodelist *ndlp = rdata->pnode; - if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || + ndlp->nlp_state != NLP_STE_MAPPED_NODE) return 0; - } piocbq = &(lpfc_cmd->cur_iocbq); piocbq->vport = vport; @@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, struct lpfc_iocbq *iocbqrsp; int ret; - if (!rdata->pnode) + if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) return FAILED; lpfc_cmd->rdata = rdata; @@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) * Catch race where our node has transitioned, but the * transport is still transitioning. */ - if (!ndlp) { + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { cmnd->result = ScsiResult(DID_BUS_BUSY, 0); goto out_fail_command; } @@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) * target is rediscovered or devloss timeout expires. */ while (1) { - if (!pnode) + if (!pnode || !NLP_CHK_NODE_ACT(pnode)) goto out; if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { @@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) goto out; } pnode = rdata->pnode; - if (!pnode) + if (!pnode || !NLP_CHK_NODE_ACT(pnode)) goto out; } if (pnode->nlp_state == NLP_STE_MAPPED_NODE) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fc0d9501aba6..70a0a9eab211 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) spin_unlock_irq(&phba->pport->work_port_lock); spin_lock_irq(&phba->hbalock); phba->link_state = LPFC_LINK_UNKNOWN; - phba->pport->fc_flag |= FC_ESTABLISH_LINK; psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(&phba->hbalock); @@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) lpfc_offline_prep(phba); lpfc_offline(phba); lpfc_sli_brdrestart(phba); - if (lpfc_online(phba) == 0) /* Initialize the HBA */ - mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); + lpfc_online(phba); lpfc_unblock_mgmt_io(phba); return; } @@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) unsigned long drvr_flag = 0; volatile uint32_t word0, ldata; void __iomem *to_slim; + int processing_queue = 0; + + spin_lock_irqsave(&phba->hbalock, drvr_flag); + if (!pmbox) { + /* processing mbox queue from intr_handler */ + processing_queue = 1; + phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; + pmbox = lpfc_mbox_get(phba); + if (!pmbox) { + spin_unlock_irqrestore(&phba->hbalock, drvr_flag); + return MBX_SUCCESS; + } + } if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { if(!pmbox->vport) { + spin_unlock_irqrestore(&phba->hbalock, drvr_flag); lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT, "1806 Mbox x%x failed. No vport\n", pmbox->mb.mbxCommand); dump_stack(); - return MBX_NOT_FINISHED; + goto out_not_finished; } } - /* If the PCI channel is in offline state, do not post mbox. */ - if (unlikely(pci_channel_offline(phba->pcidev))) - return MBX_NOT_FINISHED; + if (unlikely(pci_channel_offline(phba->pcidev))) { + spin_unlock_irqrestore(&phba->hbalock, drvr_flag); + goto out_not_finished; + } - spin_lock_irqsave(&phba->hbalock, drvr_flag); psli = &phba->sli; - mb = &pmbox->mb; status = MBX_SUCCESS; @@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) /* Mbox command <mbxCommand> cannot issue */ LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { spin_unlock_irqrestore(&phba->hbalock, drvr_flag); LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { @@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) /* Mbox command <mbxCommand> cannot issue */ LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { spin_unlock_irqrestore(&phba->hbalock, drvr_flag); /* Mbox command <mbxCommand> cannot issue */ LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } /* Another mailbox command is still being processed, queue this @@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) spin_unlock_irqrestore(&phba->hbalock, drvr_flag); /* Mbox command <mbxCommand> cannot issue */ LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } /* timeout active mbox command */ mod_timer(&psli->mbox_tmo, (jiffies + @@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; spin_unlock_irqrestore(&phba->hbalock, drvr_flag); - return MBX_NOT_FINISHED; + goto out_not_finished; } /* Check if we took a mbox interrupt while we were @@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) spin_unlock_irqrestore(&phba->hbalock, drvr_flag); return status; + +out_not_finished: + if (processing_queue) { + pmbox->mb.mbxStatus = MBX_NOT_FINISHED; + lpfc_mbox_cmpl_put(phba, pmbox); + } + return MBX_NOT_FINISHED; } /* @@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) phba->pport->work_port_events &= ~WORKER_MBOX_TMO; spin_unlock(&phba->pport->work_port_lock); + /* Return any pending or completed mbox cmds */ + list_splice_init(&phba->sli.mboxq, &completions); if (psli->mbox_active) { list_add_tail(&psli->mbox_active->list, &completions); psli->mbox_active = NULL; psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; } - - /* Return any pending or completed mbox cmds */ - list_splice_init(&phba->sli.mboxq, &completions); list_splice_init(&phba->sli.mboxq_cmpl, &completions); - INIT_LIST_HEAD(&psli->mboxq); - INIT_LIST_HEAD(&psli->mboxq_cmpl); - spin_unlock_irqrestore(&phba->hbalock, flags); while (!list_empty(&completions)) { list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); pmb->mb.mbxStatus = MBX_NOT_FINISHED; - if (pmb->mbox_cmpl) { + if (pmb->mbox_cmpl) pmb->mbox_cmpl(phba,pmb); - } } return 1; } @@ -3613,6 +3626,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4]); /* + * If the iocb is not found in Firmware queue the iocb + * might have completed already. Do not free it again. + */ + if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { + spin_unlock_irq(&phba->hbalock); + lpfc_sli_release_iocbq(phba, cmdiocb); + return; + } + /* * make sure we have the right iocbq before taking it * off the txcmplq and try to call completion routine. */ @@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id) phba->pport->stopped = 1; } + spin_lock(&phba->hbalock); if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { pmb = phba->sli.mbox_active; @@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id) /* First check out the status word */ lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); if (pmbox->mbxOwner != OWN_HOST) { + spin_unlock(&phba->hbalock); /* * Stray Mailbox Interrupt, mbxCommand <cmd> * mbxStatus <status> @@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id) /* clear mailbox attention bit */ work_ha_copy &= ~HA_MBATT; } else { + phba->sli.mbox_active = NULL; + spin_unlock(&phba->hbalock); phba->last_completion_time = jiffies; del_timer(&phba->sli.mbox_tmo); - - phba->sli.mbox_active = NULL; if (pmb->mbox_cmpl) { lpfc_sli_pcimem_bcopy(mbox, pmbox, MAILBOX_CMD_SIZE); @@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id) pmb->context1 = mp; pmb->context2 = ndlp; pmb->vport = vport; - spin_lock(&phba->hbalock); - phba->sli.sli_flag &= - ~LPFC_SLI_MBOX_ACTIVE; - spin_unlock(&phba->hbalock); + rc = lpfc_sli_issue_mbox(phba, + pmb, + MBX_NOWAIT); + if (rc != MBX_BUSY) + lpfc_printf_log(phba, + KERN_ERR, + LOG_MBOX | LOG_SLI, + "0306 rc should have" + "been MBX_BUSY"); goto send_current_mbox; } } @@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id) spin_unlock(&phba->pport->work_port_lock); lpfc_mbox_cmpl_put(phba, pmb); } - } + } else + spin_unlock(&phba->hbalock); if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active == NULL)) { -send_next_mbox: - spin_lock(&phba->hbalock); - phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - pmb = lpfc_mbox_get(phba); - spin_unlock(&phba->hbalock); send_current_mbox: /* Process next mailbox command if there is one */ - if (pmb != NULL) { - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - pmb->mb.mbxStatus = MBX_NOT_FINISHED; - lpfc_mbox_cmpl_put(phba, pmb); - goto send_next_mbox; - } - } - + do { + rc = lpfc_sli_issue_mbox(phba, NULL, + MBX_NOWAIT); + } while (rc == MBX_NOT_FINISHED); + if (rc != MBX_SUCCESS) + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | + LOG_SLI, "0349 rc should be " + "MBX_SUCCESS"); } spin_lock(&phba->hbalock); diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ca540d1d041e..b22b893019f4 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.2.5" +#define LPFC_DRIVER_VERSION "8.2.6" #define LPFC_DRIVER_NAME "lpfc" diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 86d05beb00b8..6feaf59b0b1b 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) /* Otherwise, we will perform fabric logo as needed */ if (ndlp && NLP_CHK_NODE_ACT(ndlp) && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && - phba->link_state >= LPFC_LINK_UP) { + phba->link_state >= LPFC_LINK_UP && + phba->fc_topology != TOPOLOGY_LOOP) { if (vport->cfg_enable_da_id) { timeout = msecs_to_jiffies(phba->fc_ratov * 2000); if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) |