aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c201
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h21
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c36
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c122
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c69
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c399
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c523
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h22
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
14 files changed, 649 insertions, 793 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index adb95674823..3062b39fbdb 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -267,10 +267,6 @@ struct lpfc_hba {
struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
-#define LPFC_RPI_HASH_SIZE 64
-#define LPFC_RPI_HASH_FUNC(x) ((x) & (0x3f))
- /* ptr to active D_ID / RPIs */
- struct lpfc_nodelist *fc_nlplookup[LPFC_RPI_HASH_SIZE];
uint32_t wwnn[2];
uint32_t RandomData[7];
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index acae7c48ef7..89e8222bc7c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
}
-static ssize_t
-lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
+static int
+lpfc_issue_lip(struct Scsi_Host *host)
{
- struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
- int val = 0;
LPFC_MBOXQ_t *pmboxq;
int mbxstatus = MBXERR_ERROR;
- if ((sscanf(buf, "%d", &val) != 1) ||
- (val != 1))
- return -EINVAL;
-
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
(phba->hba_state != LPFC_HBA_READY))
return -EPERM;
@@ -229,12 +223,12 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
if (mbxstatus == MBX_TIMEOUT)
pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
else
- mempool_free( pmboxq, phba->mbox_mem_pool);
+ mempool_free(pmboxq, phba->mbox_mem_pool);
if (mbxstatus == MBXERR_ERROR)
return -EIO;
- return strlen(buf);
+ return 0;
}
static ssize_t
@@ -251,8 +245,6 @@ lpfc_board_online_show(struct class_device *cdev, char *buf)
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
- if (!phba) return 0;
-
if (phba->fc_flag & FC_OFFLINE_MODE)
return snprintf(buf, PAGE_SIZE, "0\n");
else
@@ -269,7 +261,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
int val=0, status=0;
if (sscanf(buf, "%d", &val) != 1)
- return 0;
+ return -EINVAL;
init_completion(&online_compl);
@@ -283,7 +275,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
if (!status)
return strlen(buf);
else
- return 0;
+ return -EIO;
}
@@ -294,47 +286,83 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \
struct Scsi_Host *host = class_to_shost(cdev);\
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
int val = 0;\
- if (phba){\
- val = phba->cfg_##attr;\
- return snprintf(buf, PAGE_SIZE, "%d\n",\
- phba->cfg_##attr);\
+ val = phba->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%d\n",\
+ phba->cfg_##attr);\
+}
+
+#define lpfc_param_hex_show(attr) \
+static ssize_t \
+lpfc_##attr##_show(struct class_device *cdev, char *buf) \
+{ \
+ struct Scsi_Host *host = class_to_shost(cdev);\
+ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
+ int val = 0;\
+ val = phba->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%#x\n",\
+ phba->cfg_##attr);\
+}
+
+#define lpfc_param_init(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ phba->cfg_##attr = val;\
+ return 0;\
}\
- return 0;\
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
+ "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", \
+ phba->brd_no, val); \
+ phba->cfg_##attr = default;\
+ return -EINVAL;\
}
-#define lpfc_param_store(attr, minval, maxval) \
+#define lpfc_param_set(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ phba->cfg_##attr = val;\
+ return 0;\
+ }\
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
+ "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", \
+ phba->brd_no, val); \
+ return -EINVAL;\
+}
+
+#define lpfc_param_store(attr) \
static ssize_t \
lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
{ \
struct Scsi_Host *host = class_to_shost(cdev);\
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
- int val = 0;\
+ int val=0;\
if (!isdigit(buf[0]))\
return -EINVAL;\
- if (sscanf(buf, "0x%x", &val) != 1)\
- if (sscanf(buf, "%d", &val) != 1)\
- return -EINVAL;\
- if (phba){\
- if (val >= minval && val <= maxval) {\
- phba->cfg_##attr = val;\
- return strlen(buf);\
- }\
- }\
- return 0;\
+ if (sscanf(buf, "%i", &val) != 1)\
+ return -EINVAL;\
+ if (lpfc_##attr##_set(phba, val) == 0) \
+ return strlen(buf);\
+ else \
+ return -EINVAL;\
}
-#define LPFC_ATTR_R_NOINIT(name, desc) \
-extern int lpfc_##name;\
+#define LPFC_ATTR(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
-lpfc_param_show(name)\
-static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+lpfc_param_init(name, defval, minval, maxval)
#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
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)
#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
@@ -342,7 +370,28 @@ static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_param_show(name)\
-lpfc_param_store(name, minval, maxval)\
+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)
+
+#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+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)
+
+#define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+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)
@@ -364,7 +413,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
NULL);
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
NULL);
-static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
lpfc_board_online_show, lpfc_board_online_store);
@@ -388,7 +436,7 @@ static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
# LOG_LIBDFC 0x2000 LIBDFC events
# LOG_ALL_MSG 0xffff LOG all messages
*/
-LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
+LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
/*
# lun_queue_depth: This parameter is used to limit the number of outstanding
@@ -419,7 +467,7 @@ LPFC_ATTR_R(scan_down, 1, 0, 1,
/*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
-# until the timer expires. Value range is [0,255]. Default value is 20.
+# until the timer expires. Value range is [0,255]. Default value is 30.
# NOTE: this MUST be less then the SCSI Layer command timeout - 1.
*/
LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
@@ -475,14 +523,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
# cr_delay is set to 0.
*/
-static int lpfc_cr_delay = 0;
-module_param(lpfc_cr_delay, int , 0);
-MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
+LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
"interrupt response is generated");
-static int lpfc_cr_count = 1;
-module_param(lpfc_cr_count, int, 0);
-MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
+LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
"interrupt response is generated");
/*
@@ -498,9 +542,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
# Specifies the maximum number of ELS cmds we can have outstanding (for
# discovery). Value range is [1,64]. Default value = 32.
*/
-static int lpfc_discovery_threads = 32;
-module_param(lpfc_discovery_threads, int, 0);
-MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
+LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
"during discovery");
/*
@@ -537,7 +579,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
&class_device_attr_lpfc_max_luns,
&class_device_attr_nport_evt_cnt,
&class_device_attr_management_version,
- &class_device_attr_issue_lip,
&class_device_attr_board_online,
NULL,
};
@@ -992,7 +1033,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
struct fc_host_statistics *hs = &phba->link_stats;
LPFC_MBOXQ_t *pmboxq;
MAILBOX_t *pmb;
- int rc=0;
+ int rc = 0;
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmboxq)
@@ -1005,18 +1046,16 @@ lpfc_get_stats(struct Scsi_Host *shost)
pmboxq->context1 = NULL;
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
- } else
+ else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- if (pmboxq) {
- if (rc == MBX_TIMEOUT)
- pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- else
- mempool_free( pmboxq, phba->mbox_mem_pool);
- }
+ if (rc == MBX_TIMEOUT)
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ else
+ mempool_free(pmboxq, phba->mbox_mem_pool);
return NULL;
}
@@ -1027,24 +1066,22 @@ lpfc_get_stats(struct Scsi_Host *shost)
hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
- memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+ memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
pmb->mbxCommand = MBX_READ_LNK_STAT;
pmb->mbxOwner = OWN_HOST;
pmboxq->context1 = NULL;
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
- (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) {
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
- } else
+ else
rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- if (pmboxq) {
- if (rc == MBX_TIMEOUT)
- pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- else
- mempool_free( pmboxq, phba->mbox_mem_pool);
- }
+ if (rc == MBX_TIMEOUT)
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ else
+ mempool_free( pmboxq, phba->mbox_mem_pool);
return NULL;
}
@@ -1234,25 +1271,27 @@ struct fc_function_template lpfc_transport_functions = {
.get_starget_port_name = lpfc_get_starget_port_name,
.show_starget_port_name = 1,
+
+ .issue_fc_host_lip = lpfc_issue_lip,
};
void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
- phba->cfg_log_verbose = lpfc_log_verbose;
- phba->cfg_cr_delay = lpfc_cr_delay;
- phba->cfg_cr_count = lpfc_cr_count;
- phba->cfg_lun_queue_depth = lpfc_lun_queue_depth;
- phba->cfg_fcp_class = lpfc_fcp_class;
- phba->cfg_use_adisc = lpfc_use_adisc;
- phba->cfg_ack0 = lpfc_ack0;
- phba->cfg_topology = lpfc_topology;
- phba->cfg_scan_down = lpfc_scan_down;
- phba->cfg_nodev_tmo = lpfc_nodev_tmo;
- phba->cfg_link_speed = lpfc_link_speed;
- phba->cfg_fdmi_on = lpfc_fdmi_on;
- phba->cfg_discovery_threads = lpfc_discovery_threads;
- phba->cfg_max_luns = lpfc_max_luns;
+ lpfc_log_verbose_init(phba, lpfc_log_verbose);
+ lpfc_cr_delay_init(phba, lpfc_cr_delay);
+ lpfc_cr_count_init(phba, lpfc_cr_count);
+ lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
+ lpfc_fcp_class_init(phba, lpfc_fcp_class);
+ lpfc_use_adisc_init(phba, lpfc_use_adisc);
+ lpfc_ack0_init(phba, lpfc_ack0);
+ lpfc_topology_init(phba, lpfc_topology);
+ lpfc_scan_down_init(phba, lpfc_scan_down);
+ lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
+ lpfc_link_speed_init(phba, lpfc_link_speed);
+ lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
+ lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
+ lpfc_max_luns_init(phba, lpfc_max_luns);
/*
* The total number of segments is the configuration value plus 2
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index bd5135d3eee..d527d05a607 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -62,10 +62,6 @@ void lpfc_disc_timeout(unsigned long);
void lpfc_scan_timeout(unsigned long);
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
-struct lpfc_nodelist *lpfc_findnode_remove_rpi(struct lpfc_hba * phba,
- uint16_t rpi);
-void lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
- uint16_t rpi);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
int lpfc_do_work(void *);
@@ -147,6 +143,9 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
int lpfc_mem_alloc(struct lpfc_hba *);
void lpfc_mem_free(struct lpfc_hba *);
+struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
+void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
+uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
int lpfc_sli_hba_setup(struct lpfc_hba *);
int lpfc_sli_hba_down(struct lpfc_hba *);
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
@@ -182,15 +181,11 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order,
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
uint32_t timeout);
-int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
- struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * piocb,
- uint32_t flag,
- struct lpfc_iocbq * prspiocbq,
- uint32_t timeout);
-void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
- struct lpfc_iocbq * queue1,
- struct lpfc_iocbq * queue2);
+int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
+ struct lpfc_sli_ring * pring,
+ struct lpfc_iocbq * piocb,
+ struct lpfc_iocbq * prspiocbq,
+ uint32_t timeout);
void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
struct lpfc_iocbq * cmdiocb,
struct lpfc_iocbq * rspiocb);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 1280f0e5463..7f427f9c468 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -224,18 +224,16 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
IOCB_t *icmd;
- struct lpfc_iocbq *geniocb = NULL;
+ struct lpfc_iocbq *geniocb;
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, geniocb, struct lpfc_iocbq, list);
+ geniocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (geniocb == NULL)
return 1;
- memset(geniocb, 0, sizeof (struct lpfc_iocbq));
icmd = &geniocb->iocb;
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
@@ -279,7 +277,7 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
spin_lock_irq(phba->host->host_lock);
if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
- list_add_tail(&geniocb->list, lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, geniocb);
spin_unlock_irq(phba->host->host_lock);
return 1;
}
@@ -487,7 +485,7 @@ out:
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -526,7 +524,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -735,7 +733,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
kfree(inp);
kfree(bmp);
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, cmdiocb);
spin_unlock_irq(phba->host->host_lock);
return;
}
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 098b8b45c7f..084e7628ce1 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -70,7 +70,6 @@ struct lpfc_nodelist {
struct timer_list nlp_tmofunc; /* Used for nodev tmo */
struct fc_rport *rport; /* Corresponding FC transport
port structure */
- struct lpfc_nodelist *nlp_rpi_hash_next;
struct lpfc_hba *nlp_phba;
struct lpfc_work_evt nodev_timeout_evt;
struct lpfc_work_evt els_retry_evt;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 63caf7fe972..08a0c00cfc3 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -102,9 +102,8 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
uint16_t cmdSize,
uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd)
{
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
struct lpfc_sli_ring *pring;
- struct lpfc_iocbq *elsiocb = NULL;
+ struct lpfc_iocbq *elsiocb;
struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
struct ulp_bde64 *bpl;
IOCB_t *icmd;
@@ -114,15 +113,13 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (phba->hba_state < LPFC_LINK_UP)
return NULL;
-
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, elsiocb, struct lpfc_iocbq, list);
+ elsiocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (elsiocb == NULL)
return NULL;
- memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
icmd = &elsiocb->iocb;
/* fill in BDEs for command */
@@ -133,7 +130,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
if (pcmd)
kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
@@ -150,7 +149,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
kfree(prsp);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
kfree(pcmd);
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
return NULL;
}
INIT_LIST_HEAD(&prsp->list);
@@ -164,7 +165,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
&pbuflist->phys);
if (pbuflist == 0 || pbuflist->virt == 0) {
- list_add_tail(&elsiocb->list, lpfc_iocb_list);
+ spin_lock_irq(phba->host->host_lock);
+ lpfc_sli_release_iocbq(phba, elsiocb);
+ spin_unlock_irq(phba->host->host_lock);
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
kfree(pcmd);
@@ -596,10 +599,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
spin_unlock_irq(phba->host->host_lock);
(iocb->iocb_cmpl) (phba, iocb, iocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, iocb);
}
}
}
@@ -1713,7 +1714,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
kfree(buf_ptr);
}
spin_lock_irq(phba->host->host_lock);
- list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, elsiocb);
spin_unlock_irq(phba->host->host_lock);
return 0;
}
@@ -2929,9 +2930,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
spin_unlock_irq(phba->host->host_lock);
(piocb->iocb_cmpl) (phba, piocb, piocb);
spin_lock_irq(phba->host->host_lock);
- } else {
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba, piocb);
}
if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2996,7 +2996,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3033,7 +3033,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
spin_lock_irq(phba->host->host_lock);
}
else
- list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+ lpfc_sli_release_iocbq(phba, piocb);
}
spin_unlock_irq(phba->host->host_lock);
return;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 56052f4510c..259eeb161b8 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -890,10 +890,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -981,10 +978,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -1028,6 +1022,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
if (ndlp->nlp_type & NLP_FCP_INITIATOR)
rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+ scsi_block_requests(phba->host);
ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
if (!rport) {
dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1044,6 +1039,23 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
}
rdata = rport->dd_data;
rdata->pnode = ndlp;
+ scsi_unblock_requests(phba->host);
+
+ return;
+}
+
+static void
+lpfc_unregister_remote_port(struct lpfc_hba * phba,
+ struct lpfc_nodelist * ndlp)
+{
+ struct fc_rport *rport = ndlp->rport;
+ struct lpfc_rport_data *rdata = rport->dd_data;
+
+ ndlp->rport = NULL;
+ rdata->pnode = NULL;
+ scsi_block_requests(phba->host);
+ fc_remote_port_delete(rport);
+ scsi_unblock_requests(phba->host);
return;
}
@@ -1260,7 +1272,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
* may have removed the remote port.
*/
if ((rport_del != none) && nlp->rport)
- fc_remote_port_block(nlp->rport);
+ lpfc_unregister_remote_port(phba, nlp);
if (rport_add != none) {
/*
@@ -1270,8 +1282,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
*/
if (!nlp->rport)
lpfc_register_remote_port(phba, nlp);
- else
- fc_remote_port_unblock(nlp->rport);
/*
* if we added to Mapped list, but the remote port
@@ -1435,10 +1445,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
iocb, iocb);
spin_lock_irq(phba->host->
host_lock);
- } else {
- list_add_tail(&iocb->list,
- &phba->lpfc_iocb_list);
- }
+ } else
+ lpfc_sli_release_iocbq(phba,
+ iocb);
}
}
spin_unlock_irq(phba->host->host_lock);
@@ -1472,7 +1481,6 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
if (rc == MBX_NOT_FINISHED)
mempool_free( mbox, phba->mbox_mem_pool);
}
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
lpfc_no_rpi(phba, ndlp);
ndlp->nlp_rpi = 0;
return 1;
@@ -1490,7 +1498,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
LPFC_MBOXQ_t *mb;
LPFC_MBOXQ_t *nextmb;
struct lpfc_dmabuf *mp;
- struct fc_rport *rport;
/* Cleanup node for NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
@@ -1507,10 +1514,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
* and flush cache's w/o generating flush errors.
*/
if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
- rport = ndlp->rport;
- ndlp->rport = NULL;
- fc_remote_port_unblock(rport);
- fc_remote_port_delete(rport);
+ lpfc_unregister_remote_port(phba, ndlp);
ndlp->nlp_sid = NLP_NO_SID;
}
@@ -2422,10 +2426,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
pmb->context1 = NULL;
- if (ndlp->nlp_rpi != 0)
- lpfc_findnode_remove_rpi(phba, ndlp->nlp_rpi);
ndlp->nlp_rpi = mb->un.varWords[0];
- lpfc_addnode_rpi(phba, ndlp, ndlp->nlp_rpi);
ndlp->nlp_type |= NLP_FABRIC;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
@@ -2451,75 +2452,28 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
}
/*
- * This routine looks up the ndlp hash
- * table for the given RPI. If rpi found
+ * This routine looks up the ndlp lists
+ * for the given RPI. If rpi found
* it return the node list pointer
- * else return 0.
+ * else return NULL.
*/
struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
{
- struct lpfc_nodelist *ret;
-
- ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)];
- while ((ret != 0) && (ret->nlp_rpi != rpi)) {
- ret = ret->nlp_rpi_hash_next;
- }
- return ret;
-}
-
-/*
- * This routine looks up the ndlp hash table for the
- * given RPI. If rpi found it return the node list
- * pointer else return 0 after deleting the entry
- * from hash table.
- */
-struct lpfc_nodelist *
-lpfc_findnode_remove_rpi(struct lpfc_hba * phba, uint16_t rpi)
-{
- struct lpfc_nodelist *ret, *temp;;
-
- ret = phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)];
- if (ret == 0)
- return NULL;
-
- if (ret->nlp_rpi == rpi) {
- phba->fc_nlplookup[LPFC_RPI_HASH_FUNC(rpi)] =
- ret->nlp_rpi_hash_next;
- ret->nlp_rpi_hash_next = NULL;
- return ret;
- }
-
- while ((ret->nlp_rpi_hash_next != 0) &&
- (ret->nlp_rpi_hash_next->nlp_rpi != rpi)) {
- ret = ret->nlp_rpi_hash_next;
- }
-
- if (ret->nlp_rpi_hash_next != 0) {
- temp = ret->nlp_rpi_hash_next;
- ret->nlp_rpi_hash_next = temp->nlp_rpi_hash_next;
- temp->nlp_rpi_hash_next = NULL;
- return temp;
- } else {
- return NULL;
- }
-}
-
-/*
- * This routine adds the node list entry to the
- * ndlp hash table.
- */
-void
-lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
- uint16_t rpi)
-{
+ struct lpfc_nodelist *ndlp;
+ struct list_head * lists[]={&phba->fc_nlpunmap_list,
+ &phba->fc_nlpmap_list,
+ &phba->fc_plogi_list,
+ &phba->fc_adisc_list,
+ &phba->fc_reglogin_list};
+ int i;
- uint32_t index;
+ for (i = 0; i < ARRAY_SIZE(lists); i++ )
+ list_for_each_entry(ndlp, lists[i], nlp_listp)
+ if (ndlp->nlp_rpi == rpi)
+ return (ndlp);
- index = LPFC_RPI_HASH_FUNC(rpi);
- ndlp->nlp_rpi_hash_next = phba->fc_nlplookup[index];
- phba->fc_nlplookup[index] = ndlp;
- return;
+ return NULL;
}
void
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0856ff7d3b3..4e04470321a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -537,12 +537,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
lpfc_offline(phba);
- /*
- * Restart all traffic to this host. Since the fc_transport
- * block functions (future) were not called in lpfc_offline,
- * don't call them here.
- */
- scsi_unblock_requests(phba->host);
}
}
@@ -772,10 +766,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
{
lpfc_vpd_t *vp;
uint32_t id;
+ uint8_t hdrtype;
char str[16];
vp = &phba->vpd;
pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
+ pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
switch ((id >> 16) & 0xffff) {
case PCI_DEVICE_ID_FIREFLY:
@@ -803,7 +799,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP9802 2");
break;
case PCI_DEVICE_ID_THOR:
- strcpy(str, "LP10000 2");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP10000DC 2");
+ else
+ strcpy(str, "LP10000 2");
break;
case PCI_DEVICE_ID_VIPER:
strcpy(str, "LPX1000 10");
@@ -812,10 +811,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP982 2");
break;
case PCI_DEVICE_ID_TFLY:
- strcpy(str, "LP1050 2");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP1050DC 2");
+ else
+ strcpy(str, "LP1050 2");
break;
case PCI_DEVICE_ID_HELIOS:
- strcpy(str, "LP11000 4");
+ if (hdrtype == 0x80)
+ strcpy(str, "LP11002 4");
+ else
+ strcpy(str, "LP11000 4");
break;
case PCI_DEVICE_ID_BMID:
strcpy(str, "LP1150 4");
@@ -824,13 +829,16 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
strcpy(str, "LP111 4");
break;
case PCI_DEVICE_ID_ZEPHYR:
- strcpy(str, "LP11000e 4");
+ if (hdrtype == 0x80)
+ strcpy(str, "LPe11002 4");
+ else
+ strcpy(str, "LPe11000 4");
break;
case PCI_DEVICE_ID_ZMID:
- strcpy(str, "LP1150e 4");
+ strcpy(str, "LPe1150 4");
break;
case PCI_DEVICE_ID_ZSMB:
- strcpy(str, "LP111e 4");
+ strcpy(str, "LPe111 4");
break;
case PCI_DEVICE_ID_LP101:
strcpy(str, "LP101 2");
@@ -862,8 +870,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
int type)
{
IOCB_t *icmd;
- struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
- struct lpfc_iocbq *iocb = NULL;
+ struct lpfc_iocbq *iocb;
struct lpfc_dmabuf *mp1, *mp2;
cnt += pring->missbufcnt;
@@ -872,13 +879,12 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
while (cnt > 0) {
/* Allocate buffer for command iocb */
spin_lock_irq(phba->host->host_lock);
- list_remove_head(lpfc_iocb_list, iocb, struct lpfc_iocbq, list);
+ iocb = lpfc_sli_get_iocbq(phba);
spin_unlock_irq(phba->host->host_lock);
if (iocb == NULL) {
pring->missbufcnt = cnt;
return cnt;
}
- memset(iocb, 0, sizeof (struct lpfc_iocbq));
icmd = &iocb->iocb;