summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2fc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-23 11:13:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-23 11:13:11 -0700
commitd4e06701b89286a306b31e20ec69a904fae374a1 (patch)
treef6adefd65b021ccddb7655109ea8b9ab4e714292 /drivers/scsi/bnx2fc
parente4980371059ca4a81ccdcb4381c41af8869ca711 (diff)
parent87045b033a62777337ae4aa62834876da09b5fb5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (77 commits) [SCSI] fix crash in scsi_dispatch_cmd() [SCSI] sr: check_events() ignore GET_EVENT when TUR says otherwise [SCSI] bnx2i: Fixed kernel panic due to illegal usage of sc->request->cpu [SCSI] bfa: Update the driver version to 3.0.2.1 [SCSI] bfa: Driver and BSG enhancements. [SCSI] bfa: Added support to query PHY. [SCSI] bfa: Added HBA diagnostics support. [SCSI] bfa: Added support for flash configuration [SCSI] bfa: Added support to obtain SFP info. [SCSI] bfa: Added support for CEE info and stats query. [SCSI] bfa: Extend BSG interface. [SCSI] bfa: FCS bug fixes. [SCSI] bfa: DMA memory allocation enhancement. [SCSI] bfa: Brocade-1860 Fabric Adapter vHBA support. [SCSI] bfa: Brocade-1860 Fabric Adapter PLL init fixes. [SCSI] bfa: Added Fabric Assigned Address(FAA) support [SCSI] bfa: IOC bug fixes. [SCSI] bfa: Enable ASIC block configuration and query. [SCSI] bnx2i: Updated copyright and bump version [SCSI] bnx2i: Modified to skip CNIC registration if iSCSI is not supported ... Fix up some trivial conflicts in: - drivers/scsi/bnx2fc/{bnx2fc.h,bnx2fc_fcoe.c}: Crazy broadcom version number conflicts - drivers/target/tcm_fc/tfc_cmd.c Just trivial cleanups done on adjacent lines
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h8
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c31
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_hwi.c24
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c2
4 files changed, 61 insertions, 4 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 907672e8606..d924236e1b9 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -152,7 +152,6 @@ struct bnx2fc_percpu_s {
spinlock_t fp_work_lock;
};
-
struct bnx2fc_hba {
struct list_head link;
struct cnic_dev *cnic;
@@ -179,6 +178,7 @@ struct bnx2fc_hba {
#define BNX2FC_CTLR_INIT_DONE 1
#define BNX2FC_CREATE_DONE 2
struct fcoe_ctlr ctlr;
+ struct list_head vports;
u8 vlan_enabled;
int vlan_id;
u32 next_conn_id;
@@ -232,6 +232,11 @@ struct bnx2fc_hba {
#define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_hba, ctlr)
+struct bnx2fc_lport {
+ struct list_head list;
+ struct fc_lport *lport;
+};
+
struct bnx2fc_cmd_mgr {
struct bnx2fc_hba *hba;
u16 next_idx;
@@ -428,6 +433,7 @@ struct bnx2fc_work {
struct bnx2fc_unsol_els {
struct fc_lport *lport;
struct fc_frame *fp;
+ struct bnx2fc_hba *hba;
struct work_struct unsol_els_work;
};
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 9eebaebdaa7..a97aff3a066 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -679,6 +679,9 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
break;
+ case SPEED_2500:
+ lport->link_speed = FC_PORTSPEED_2GBIT;
+ break;
case SPEED_10000:
lport->link_speed = FC_PORTSPEED_10GBIT;
break;
@@ -1231,6 +1234,7 @@ static int bnx2fc_interface_setup(struct bnx2fc_hba *hba,
hba->ctlr.get_src_addr = bnx2fc_get_src_mac;
set_bit(BNX2FC_CTLR_INIT_DONE, &hba->init_done);
+ INIT_LIST_HEAD(&hba->vports);
rc = bnx2fc_netdev_setup(hba);
if (rc)
goto setup_err;
@@ -1267,8 +1271,15 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba,
struct fcoe_port *port;
struct Scsi_Host *shost;
struct fc_vport *vport = dev_to_vport(parent);
+ struct bnx2fc_lport *blport;
int rc = 0;
+ blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL);
+ if (!blport) {
+ BNX2FC_HBA_DBG(hba->ctlr.lp, "Unable to alloc bnx2fc_lport\n");
+ return NULL;
+ }
+
/* Allocate Scsi_Host structure */
if (!npiv)
lport = libfc_host_alloc(&bnx2fc_shost_template, sizeof(*port));
@@ -1277,7 +1288,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba,
if (!lport) {
printk(KERN_ERR PFX "could not allocate scsi host structure\n");
- return NULL;
+ goto free_blport;
}
shost = lport->host;
port = lport_priv(lport);
@@ -1333,12 +1344,20 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba,
}
bnx2fc_interface_get(hba);
+
+ spin_lock_bh(&hba->hba_lock);
+ blport->lport = lport;
+ list_add_tail(&blport->list, &hba->vports);
+ spin_unlock_bh(&hba->hba_lock);
+
return lport;
shost_err:
scsi_remove_host(shost);
lp_config_err:
scsi_host_put(lport->host);
+free_blport:
+ kfree(blport);
return NULL;
}
@@ -1354,6 +1373,7 @@ static void bnx2fc_if_destroy(struct fc_lport *lport)
{
struct fcoe_port *port = lport_priv(lport);
struct bnx2fc_hba *hba = port->priv;
+ struct bnx2fc_lport *blport, *tmp;
BNX2FC_HBA_DBG(hba->ctlr.lp, "ENTERED bnx2fc_if_destroy\n");
/* Stop the transmit retry timer */
@@ -1378,6 +1398,15 @@ static void bnx2fc_if_destroy(struct fc_lport *lport)
/* Free memory used by statistical counters */
fc_lport_free_stats(lport);
+ spin_lock_bh(&hba->hba_lock);
+ list_for_each_entry_safe(blport, tmp, &hba->vports, list) {
+ if (blport->lport == lport) {
+ list_del(&blport->list);
+ kfree(blport);
+ }
+ }
+ spin_unlock_bh(&hba->hba_lock);
+
/* Release Scsi_Host */
scsi_host_put(lport->host);
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index d8e8a825560..09bdd9b88d1 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -486,16 +486,36 @@ int bnx2fc_send_session_destroy_req(struct bnx2fc_hba *hba,
return rc;
}
+static bool is_valid_lport(struct bnx2fc_hba *hba, struct fc_lport *lport)
+{
+ struct bnx2fc_lport *blport;
+
+ spin_lock_bh(&hba->hba_lock);
+ list_for_each_entry(blport, &hba->vports, list) {
+ if (blport->lport == lport) {
+ spin_unlock_bh(&hba->hba_lock);
+ return true;
+ }
+ }
+ spin_unlock_bh(&hba->hba_lock);
+ return false;
+
+}
+
+
static void bnx2fc_unsol_els_work(struct work_struct *work)
{
struct bnx2fc_unsol_els *unsol_els;
struct fc_lport *lport;
+ struct bnx2fc_hba *hba;
struct fc_frame *fp;
unsol_els = container_of(work, struct bnx2fc_unsol_els, unsol_els_work);
lport = unsol_els->lport;
fp = unsol_els->fp;
- fc_exch_recv(lport, fp);
+ hba = unsol_els->hba;
+ if (is_valid_lport(hba, lport))
+ fc_exch_recv(lport, fp);
kfree(unsol_els);
}
@@ -505,6 +525,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt,
{
struct fcoe_port *port = tgt->port;
struct fc_lport *lport = port->lport;
+ struct bnx2fc_hba *hba = port->priv;
struct bnx2fc_unsol_els *unsol_els;
struct fc_frame_header *fh;
struct fc_frame *fp;
@@ -565,6 +586,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt,
fr_eof(fp) = FC_EOF_T;
fr_crc(fp) = cpu_to_le32(~crc);
unsol_els->lport = lport;
+ unsol_els->hba = hba;
unsol_els->fp = fp;
INIT_WORK(&unsol_els->unsol_els_work, bnx2fc_unsol_els_work);
queue_work(bnx2fc_wq, &unsol_els->unsol_els_work);
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 5dc4205ed8a..45eba6d609c 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1743,7 +1743,6 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
printk(KERN_ERR PFX "SCp.ptr is NULL\n");
return;
}
- io_req->sc_cmd = NULL;
if (io_req->on_active_queue) {
list_del_init(&io_req->link);
@@ -1763,6 +1762,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
}
bnx2fc_unmap_sg_list(io_req);
+ io_req->sc_cmd = NULL;
switch (io_req->fcp_status) {
case FC_GOOD: