diff options
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_init.c | 100 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_iscsi.c | 13 |
2 files changed, 50 insertions, 63 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index ae4b2d588fd3..0c4210d48ee8 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -15,11 +15,10 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); static u32 adapter_count; -static int bnx2i_reg_device; #define DRV_MODULE_NAME "bnx2i" -#define DRV_MODULE_VERSION "2.0.1d" -#define DRV_MODULE_RELDATE "Mar 25, 2009" +#define DRV_MODULE_VERSION "2.0.1e" +#define DRV_MODULE_RELDATE "June 22, 2009" static char version[] __devinitdata = "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ @@ -31,7 +30,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 iSCSI Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -static DEFINE_RWLOCK(bnx2i_dev_lock); +static DEFINE_MUTEX(bnx2i_dev_lock); unsigned int event_coal_div = 1; module_param(event_coal_div, int, 0664); @@ -100,14 +99,14 @@ struct bnx2i_hba *get_adapter_list_head(void) if (!adapter_count) goto hba_not_found; - read_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); list_for_each_entry(tmp_hba, &adapter_list, link) { if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) { hba = tmp_hba; break; } } - read_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); hba_not_found: return hba; } @@ -122,14 +121,14 @@ struct bnx2i_hba *bnx2i_find_hba_for_cnic(struct cnic_dev *cnic) { struct bnx2i_hba *hba, *temp; - read_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); list_for_each_entry_safe(hba, temp, &adapter_list, link) { if (hba->cnic == cnic) { - read_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); return hba; } } - read_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); return NULL; } @@ -186,18 +185,17 @@ void bnx2i_stop(void *handle) */ void bnx2i_register_device(struct bnx2i_hba *hba) { + int rc; + if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) || test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { return; } - hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba); + rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba); - spin_lock(&hba->lock); - bnx2i_reg_device++; - spin_unlock(&hba->lock); - - set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); + if (!rc) + set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); } @@ -211,10 +209,10 @@ void bnx2i_reg_dev_all(void) { struct bnx2i_hba *hba, *temp; - read_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); list_for_each_entry_safe(hba, temp, &adapter_list, link) bnx2i_register_device(hba); - read_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); } @@ -234,10 +232,6 @@ static void bnx2i_unreg_one_device(struct bnx2i_hba *hba) hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); - spin_lock(&hba->lock); - bnx2i_reg_device--; - spin_unlock(&hba->lock); - /* ep_disconnect could come before NETDEV_DOWN, driver won't * see NETDEV_DOWN as it already unregistered itself. */ @@ -255,10 +249,10 @@ void bnx2i_unreg_dev_all(void) { struct bnx2i_hba *hba, *temp; - read_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); list_for_each_entry_safe(hba, temp, &adapter_list, link) bnx2i_unreg_one_device(hba); - read_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); } @@ -267,35 +261,34 @@ void bnx2i_unreg_dev_all(void) * @hba: bnx2i adapter instance * @cnic: cnic device handle * - * Global resource lock and host adapter lock is held during critical sections - * below. This routine is called from cnic_register_driver() context and - * work horse thread which does majority of device specific initialization + * Global resource lock is held during critical sections below. This routine is + * called from either cnic_register_driver() or device hot plug context and + * and does majority of device specific initialization */ static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) { int rc; - read_lock(&bnx2i_dev_lock); - if (bnx2i_reg_device && - !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { - rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba); - if (rc) /* duplicate registration */ - printk(KERN_ERR "bnx2i- dev reg failed\n"); - - spin_lock(&hba->lock); - bnx2i_reg_device++; + mutex_lock(&bnx2i_dev_lock); + rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba); + if (!rc) { hba->age++; - spin_unlock(&hba->lock); - set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); - } - read_unlock(&bnx2i_dev_lock); - - write_lock(&bnx2i_dev_lock); - list_add_tail(&hba->link, &adapter_list); - adapter_count++; - write_unlock(&bnx2i_dev_lock); - return 0; + list_add_tail(&hba->link, &adapter_list); + adapter_count++; + } else if (rc == -EBUSY) /* duplicate registration */ + printk(KERN_ALERT "bnx2i, duplicate registration" + "hba=%p, cnic=%p\n", hba, cnic); + else if (rc == -EAGAIN) + printk(KERN_ERR "bnx2i, driver not registered\n"); + else if (rc == -EINVAL) + printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI); + else + printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc); + + mutex_unlock(&bnx2i_dev_lock); + + return rc; } @@ -343,19 +336,15 @@ void bnx2i_ulp_exit(struct cnic_dev *dev) "found, dev 0x%p\n", dev); return; } - write_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); list_del_init(&hba->link); adapter_count--; if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); - - spin_lock(&hba->lock); - bnx2i_reg_device--; - spin_unlock(&hba->lock); } - write_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); bnx2i_free_hba(hba); } @@ -377,6 +366,8 @@ static int __init bnx2i_mod_init(void) if (!is_power_of_2(sq_size)) sq_size = roundup_pow_of_two(sq_size); + mutex_init(&bnx2i_dev_lock); + bnx2i_scsi_xport_template = iscsi_register_transport(&bnx2i_iscsi_transport); if (!bnx2i_scsi_xport_template) { @@ -412,7 +403,7 @@ static void __exit bnx2i_mod_exit(void) { struct bnx2i_hba *hba; - write_lock(&bnx2i_dev_lock); + mutex_lock(&bnx2i_dev_lock); while (!list_empty(&adapter_list)) { hba = list_entry(adapter_list.next, struct bnx2i_hba, link); list_del(&hba->link); @@ -421,14 +412,11 @@ static void __exit bnx2i_mod_exit(void) if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); - bnx2i_reg_device--; } - write_unlock(&bnx2i_dev_lock); bnx2i_free_hba(hba); - write_lock(&bnx2i_dev_lock); } - write_unlock(&bnx2i_dev_lock); + mutex_unlock(&bnx2i_dev_lock); iscsi_unregister_transport(&bnx2i_iscsi_transport); cnic_unregister_driver(CNIC_ULP_ISCSI); diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index f7412196f2f8..9a7ba71f1af4 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -387,6 +387,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba) bnx2i_ep = ep->dd_data; INIT_LIST_HEAD(&bnx2i_ep->link); bnx2i_ep->state = EP_STATE_IDLE; + bnx2i_ep->ep_iscsi_cid = (u16) -1; bnx2i_ep->hba = hba; bnx2i_ep->hba_age = hba->age; hba->ofld_conns_active++; @@ -1160,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task) struct bnx2i_cmd *cmd = task->dd_data; struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; - if (test_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state)) - return -ENOTCONN; - if (!bnx2i_conn->is_bound) return -ENOTCONN; @@ -1653,15 +1651,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost, struct iscsi_endpoint *ep; int rc = 0; - if (shost) + if (shost) { /* driver is given scsi host to work with */ hba = iscsi_host_priv(shost); - else + /* Register the device with cnic if not already done so */ + bnx2i_register_device(hba); + } else /* * check if the given destination can be reached through * a iscsi capable NetXtreme2 device */ hba = bnx2i_check_route(dst_addr); + if (!hba) { rc = -ENOMEM; goto check_busy; @@ -1681,8 +1682,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost, goto net_if_down; } - bnx2i_ep->state = EP_STATE_IDLE; - bnx2i_ep->ep_iscsi_cid = (u16) -1; bnx2i_ep->num_active_cmds = 0; iscsi_cid = bnx2i_alloc_iscsi_cid(hba); if (iscsi_cid == -1) { |