static u32 adapter_count;
 
 #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 \
 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);
        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;
 }
 {
        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;
 }
 
 {
        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);
 }
 
 
 {
        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);
 }
 
 
  * @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);
+       mutex_lock(&bnx2i_dev_lock);
        rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
        if (!rc) {
                hba->age++;
                set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
+               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);
                printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI);
        else
                printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc);
-       read_unlock(&bnx2i_dev_lock);
 
-       if (!rc) {
-               write_lock(&bnx2i_dev_lock);
-               list_add_tail(&hba->link, &adapter_list);
-               adapter_count++;
-               write_unlock(&bnx2i_dev_lock);
-       }
+       mutex_unlock(&bnx2i_dev_lock);
 
        return rc;
 }
                                 "found, dev 0x%p\n", dev);
                return;
        }
-       write_lock(&bnx2i_dev_lock);
+       mutex_lock(&bnx2i_dev_lock);
        list_del_init(&hba->link);
        adapter_count--;
 
                hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
                clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
        }
-       write_unlock(&bnx2i_dev_lock);
+       mutex_unlock(&bnx2i_dev_lock);
 
        bnx2i_free_hba(hba);
 }
        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) {
 {
        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);
                        clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
                }
 
-               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);