diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 4249e52a5592..6f4cf2dd2f4a 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -418,7 +418,6 @@ struct scsi_qla_host {
 	 * concurrently.
 	 */
 	struct mutex  mbox_sem;
-	wait_queue_head_t mailbox_wait_queue;
 
 	/* temporary mailbox status registers */
 	volatile uint8_t mbox_status_count;
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 2122967bbf0b..e021eb5db2b2 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -76,4 +76,5 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
 extern int ql4xextended_error_logging;
 extern int ql4xdiscoverywait;
 extern int ql4xdontresethba;
+extern int ql4_mod_unload;
 #endif /* _QLA4x_GBL_H */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index cc210f297a78..b907b06d72ab 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -958,25 +958,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
 	return status;
 }
 
-int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
+int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha)
 {
-#define QL4_LOCK_DRVR_WAIT	300
-#define QL4_LOCK_DRVR_SLEEP	100
+#define QL4_LOCK_DRVR_WAIT	30
+#define QL4_LOCK_DRVR_SLEEP	1
 
 	int drvr_wait = QL4_LOCK_DRVR_WAIT;
 	while (drvr_wait) {
-		if (ql4xxx_lock_drvr(a) == 0) {
-			msleep(QL4_LOCK_DRVR_SLEEP);
+		if (ql4xxx_lock_drvr(ha) == 0) {
+			ssleep(QL4_LOCK_DRVR_SLEEP);
 			if (drvr_wait) {
 				DEBUG2(printk("scsi%ld: %s: Waiting for "
-					      "Global Init Semaphore...n",
-					      a->host_no,
-					      __func__));
+					      "Global Init Semaphore(%d)...n",
+					      ha->host_no,
+					      __func__, drvr_wait));
 			}
 			drvr_wait -= QL4_LOCK_DRVR_SLEEP;
 		} else {
 			DEBUG2(printk("scsi%ld: %s: Global Init Semaphore "
-				      "acquired.n", a->host_no, __func__));
+				      "acquired.n", ha->host_no, __func__));
 			return QLA_SUCCESS;
 		}
 	}
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index ef975e0dc87f..35b9e36a0e8d 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -433,7 +433,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 					readl(&ha->reg->mailbox[i]);
 
 			set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
-			wake_up(&ha->mailbox_wait_queue);
 		}
 	} else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
 		/* Immediately process the AENs that don't require much work.
@@ -686,7 +685,8 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
 			       &ha->reg->ctrl_status);
 			readl(&ha->reg->ctrl_status);
 
-			set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
+			if (!ql4_mod_unload)
+				set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
 
 			break;
 		} else if (intr_status & INTR_PENDING) {
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index b721dc5dd711..7f28657eef3f 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -29,18 +29,30 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	u_long wait_count;
 	uint32_t intr_status;
 	unsigned long flags = 0;
-	DECLARE_WAITQUEUE(wait, current);
-
-	mutex_lock(&ha->mbox_sem);
-
-	/* Mailbox code active */
-	set_bit(AF_MBOX_COMMAND, &ha->flags);
 
 	/* Make sure that pointers are valid */
 	if (!mbx_cmd || !mbx_sts) {
 		DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
 			      "pointer\n", ha->host_no, __func__));
-		goto mbox_exit;
+		return status;
+	}
+	/* Mailbox code active */
+	wait_count = MBOX_TOV * 100;
+
+	while (wait_count--) {
+		mutex_lock(&ha->mbox_sem);
+		if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
+			set_bit(AF_MBOX_COMMAND, &ha->flags);
+			mutex_unlock(&ha->mbox_sem);
+			break;
+		}
+		mutex_unlock(&ha->mbox_sem);
+		if (!wait_count) {
+			DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
+				ha->host_no, __func__));
+			return status;
+		}
+		msleep(10);
 	}
 
 	/* To prevent overwriting mailbox registers for a command that has
@@ -73,8 +85,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	/* Wait for completion */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	add_wait_queue(&ha->mailbox_wait_queue, &wait);
 
 	/*
 	 * If we don't want status, don't wait for the mailbox command to
@@ -83,8 +93,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	 */
 	if (outCount == 0) {
 		status = QLA_SUCCESS;
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&ha->mailbox_wait_queue, &wait);
 		goto mbox_exit;
 	}
 	/* Wait for command to complete */
@@ -108,8 +116,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		msleep(10);
 	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&ha->mailbox_wait_queue, &wait);
 
 	/* Check for mailbox timeout. */
 	if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
@@ -155,9 +161,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 mbox_exit:
+	mutex_lock(&ha->mbox_sem);
 	clear_bit(AF_MBOX_COMMAND, &ha->flags);
-	clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
 	mutex_unlock(&ha->mbox_sem);
+	clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
 
 	return status;
 }
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 9ef693c8809a..81fb7bd44f01 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -40,6 +40,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging,
 		 "Option to enable extended error logging, "
 		 "Default is 0 - no logging, 1 - debug logging");
 
+int ql4_mod_unload = 0;
+
 /*
  * SCSI host template entry points
  */
@@ -422,6 +424,9 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
 		goto qc_host_busy;
 	}
 
+	if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags))
+		goto qc_host_busy;
+
 	spin_unlock_irq(ha->host->host_lock);
 
 	srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done);
@@ -707,16 +712,12 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
 	return stat;
 }
 
-/**
- * qla4xxx_soft_reset - performs soft reset.
- * @ha: Pointer to host adapter structure.
- **/
-int qla4xxx_soft_reset(struct scsi_qla_host *ha)
+static void qla4xxx_hw_reset(struct scsi_qla_host *ha)
 {
-	uint32_t max_wait_time;
-	unsigned long flags = 0;
-	int status = QLA_ERROR;
 	uint32_t ctrl_status;
+	unsigned long flags = 0;
+
+	DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__));
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -733,6 +734,20 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha)
 	readl(&ha->reg->ctrl_status);
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+/**
+ * qla4xxx_soft_reset - performs soft reset.
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_soft_reset(struct scsi_qla_host *ha)
+{
+	uint32_t max_wait_time;
+	unsigned long flags = 0;
+	int status = QLA_ERROR;
+	uint32_t ctrl_status;
+
+	qla4xxx_hw_reset(ha);
 
 	/* Wait until the Network Reset Intr bit is cleared */
 	max_wait_time = RESET_INTR_TOV;
@@ -966,10 +981,12 @@ static void qla4xxx_do_dpc(struct work_struct *work)
 	struct scsi_qla_host *ha =
 		container_of(work, struct scsi_qla_host, dpc_work);
 	struct ddb_entry *ddb_entry, *dtemp;
+	int status = QLA_ERROR;
 
 	DEBUG2(printk("scsi%ld: %s: DPC handler waking up."
-		"flags = 0x%08lx, dpc_flags = 0x%08lx\n",
-		ha->host_no, __func__, ha->flags, ha->dpc_flags));
+		"flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n",
+		ha->host_no, __func__, ha->flags, ha->dpc_flags,
+		readw(&ha->reg->ctrl_status)));
 
 	/* Initialization not yet finished. Don't do anything yet. */
 	if (!test_bit(AF_INIT_DONE, &ha->flags))
@@ -983,31 +1000,28 @@ static void qla4xxx_do_dpc(struct work_struct *work)
 			test_bit(DPC_RESET_HA, &ha->dpc_flags))
 			qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
 
-		if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
+		if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
 			uint8_t wait_time = RESET_INTR_TOV;
-			unsigned long flags = 0;
 
-			qla4xxx_flush_active_srbs(ha);
-
-			spin_lock_irqsave(&ha->hardware_lock, flags);
 			while ((readw(&ha->reg->ctrl_status) &
 				(CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) {
 				if (--wait_time == 0)
 					break;
-
-				spin_unlock_irqrestore(&ha->hardware_lock,
-						       flags);
-
 				msleep(1000);
-
-				spin_lock_irqsave(&ha->hardware_lock, flags);
 			}
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
 			if (wait_time == 0)
 				DEBUG2(printk("scsi%ld: %s: SR|FSR "
 					      "bit not cleared-- resetting\n",
 					      ha->host_no, __func__));
+			qla4xxx_flush_active_srbs(ha);
+			if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) {
+				qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
+				status = qla4xxx_initialize_adapter(ha,
+						PRESERVE_DDB_LIST);
+			}
+			clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
+			if (status == QLA_SUCCESS)
+				qla4xxx_enable_intrs(ha);
 		}
 	}
 
@@ -1062,7 +1076,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
 
 	/* Issue Soft Reset to put firmware in unknown state */
 	if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
-		qla4xxx_soft_reset(ha);
+		qla4xxx_hw_reset(ha);
 
 	/* Remove timer thread, if present */
 	if (ha->timer_active)
@@ -1198,7 +1212,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 	INIT_LIST_HEAD(&ha->free_srb_q);
 
 	mutex_init(&ha->mbox_sem);
-	init_waitqueue_head(&ha->mailbox_wait_queue);
 
 	spin_lock_init(&ha->hardware_lock);
 
@@ -1665,6 +1678,7 @@ no_srp_cache:
 
 static void __exit qla4xxx_module_exit(void)
 {
+	ql4_mod_unload = 1;
 	pci_unregister_driver(&qla4xxx_pci_driver);
 	iscsi_unregister_transport(&qla4xxx_iscsi_transport);
 	kmem_cache_destroy(srb_cachep);
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index 454e19c8ad68..e5183a697d1f 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION	"5.00.07-k"
+#define QLA4XXX_DRIVER_VERSION	"5.00.07-k1"
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index b83d03c4deef..96b7cbd746a8 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1453,6 +1453,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
 	struct device *parent = &shost->shost_gendev;
 	struct scsi_target *starget;
 
+	if (strncmp(scsi_scan_type, "none", 4) == 0)
+		return ERR_PTR(-ENODEV);
+
+	if (!shost->async_scan)
+		scsi_complete_async_scans();
+
 	starget = scsi_alloc_target(parent, channel, id);
 	if (!starget)
 		return ERR_PTR(-ENOMEM);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 978bfc1e0c6a..b781a90d6699 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1647,16 +1647,6 @@ static int sd_probe(struct device *dev)
 	if (error)
 		goto out_put;
 
-	class_device_initialize(&sdkp->cdev);
-	sdkp->cdev.dev = &sdp->sdev_gendev;
-	sdkp->cdev.class = &sd_disk_class;
-	strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
-
-	if (class_device_add(&sdkp->cdev))
-		goto out_put;
-
-	get_device(&sdp->sdev_gendev);
-
 	sdkp->device = sdp;
 	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
@@ -1670,6 +1660,16 @@ static int sd_probe(struct device *dev)
 			sdp->timeout = SD_MOD_TIMEOUT;
 	}
 
+	class_device_initialize(&sdkp->cdev);
+	sdkp->cdev.dev = &sdp->sdev_gendev;
+	sdkp->cdev.class = &sd_disk_class;
+	strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
+
+	if (class_device_add(&sdkp->cdev))
+		goto out_put;
+
+	get_device(&sdp->sdev_gendev);
+
 	gd->major = sd_major((index & 0xf0) >> 4);
 	gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
 	gd->minors = 16;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index e016e0906e1a..488ec7948a57 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -2816,15 +2816,18 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
 
 		if (cmd_in == MTWEOF &&
 		    cmdstatp->have_sense &&
-		    (cmdstatp->flags & SENSE_EOM) &&
-		    (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
-		     cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
-		    undone == 0) {
-			ioctl_result = 0;	/* EOF written successfully at EOM */
-			if (fileno >= 0)
-				fileno++;
+		    (cmdstatp->flags & SENSE_EOM)) {
+			if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
+			    cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
+				ioctl_result = 0;	/* EOF(s) written successfully at EOM */
+				STps->eof = ST_NOEOF;
+			} else {  /* Writing EOF(s) failed */
+				if (fileno >= 0)
+					fileno -= undone;
+				if (undone < arg)
+					STps->eof = ST_NOEOF;
+			}
 			STps->drv_file = fileno;
-			STps->eof = ST_NOEOF;
 		} else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
 			if (fileno >= 0)
 				STps->drv_file = fileno - undone;