igb: move timesync init into a seperate function
[safe/jmp/linux-2.6] / drivers / scsi / bnx2i / bnx2i_init.c
index ae4b2d5..0c4210d 100644 (file)
 
 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);