--- vhba-module/vhba.c	2008-04-04 00:51:16.000000000 +0200
+++ vhba-module/vhba.c	2008-10-31 19:25:02.000000000 +0100
@@ -118,7 +118,7 @@
 static struct vhba_device *vhba_device_alloc(void)
 {
 	struct vhba_device *vdev;
-
+	
 	vdev = kzalloc(sizeof(struct vhba_device), GFP_KERNEL);
 	if (!vdev)
 		return NULL;
@@ -148,16 +148,17 @@
 static int vhba_device_queue(struct vhba_device *vdev, struct scsi_cmnd *cmd)
 {
 	struct vhba_command *vcmd;
-
+	unsigned long flags;
+	
 	vcmd = vhba_alloc_command();
 	if (!vcmd)
 		return SCSI_MLQUEUE_HOST_BUSY;
 
 	vcmd->cmd = cmd;
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	list_add_tail(&vcmd->entry, &vdev->cmd_list);
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	wake_up_interruptible(&vdev->cmd_wq);
 
@@ -168,8 +169,9 @@
 {
 	struct vhba_command *vcmd;
 	int retval;
-
-	spin_lock_bh(&vdev->cmd_lock);
+	unsigned long flags;
+	
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	list_for_each_entry(vcmd, &vdev->cmd_list, entry)
 	{
 		if (vcmd->cmd == cmd)
@@ -183,24 +185,24 @@
 	/* command not found */
 	if (&vcmd->entry == &vdev->cmd_list)
 	{
-		spin_unlock_bh(&vdev->cmd_lock);
+		spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 		return SUCCESS;
 	}
 
 	while (vcmd->status == VHBA_REQ_READING || vcmd->status == VHBA_REQ_WRITING)
 	{
-		spin_unlock_bh(&vdev->cmd_lock);
+		spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 		scmd_dbg(cmd, "wait for I/O before aborting\n");
 		schedule_timeout(1);
-		spin_lock_bh(&vdev->cmd_lock);
+		spin_lock_irqsave(&vdev->cmd_lock, flags);
 	}
 
 	retval = (vcmd->status == VHBA_REQ_SENT) ? FAILED : SUCCESS;
 
 	vhba_free_command(vcmd);
 
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	return retval;
 }
@@ -209,16 +211,17 @@
 {
 	struct vhba_host *vhost = container_of(work, struct vhba_host, scan_devices);
 	int id;
+	unsigned long flags;
 
 	/* no need to lock here; it'll be scheduled and run again if some device missed */
 	while ((id = find_first_bit(vhost->chgmap, vhost->shost->max_id)) < vhost->shost->max_id)
 	{
 		int remove;
 
-		spin_lock_bh(&vhost->dev_lock);
+		spin_lock_irqsave(&vhost->dev_lock, flags);
 		clear_bit(id, vhost->chgmap);
 		remove = !(vhost->devices[id]);
-		spin_unlock_bh(&vhost->dev_lock);
+		spin_unlock_irqrestore(&vhost->dev_lock, flags);
 
 		dev_dbg(&vhost->shost->shost_gendev, "try to %s target 0:%d:0\n",
 				(remove) ? "remove" : "add", id);
@@ -243,15 +246,16 @@
 {
 	struct vhba_host *vhost;
 	int i;
+	unsigned long flags;
 
 	vhost = platform_get_drvdata(&vhba_platform_device);
 
 	vhba_device_get(vdev);
 
-	spin_lock_bh(&vhost->dev_lock);
+	spin_lock_irqsave(&vhost->dev_lock, flags);
 	if (vhost->num_devices >= vhost->shost->max_id)
 	{
-		spin_unlock_bh(&vhost->dev_lock);
+		spin_unlock_irqrestore(&vhost->dev_lock, flags);
 		vhba_device_put(vdev);
 
 		return -EBUSY;
@@ -269,7 +273,7 @@
 			break;
 		}
 	}
-	spin_unlock_bh(&vhost->dev_lock);
+	spin_unlock_irqrestore(&vhost->dev_lock, flags);
 
 	schedule_work(&vhost->scan_devices);
 
@@ -279,15 +283,16 @@
 static int vhba_remove_device(struct vhba_device *vdev)
 {
 	struct vhba_host *vhost;
+	unsigned long flags;
 
 	vhost = platform_get_drvdata(&vhba_platform_device);
 
-	spin_lock_bh(&vhost->dev_lock);
+	spin_lock_irqsave(&vhost->dev_lock, flags);
 	set_bit(vdev->id, vhost->chgmap);
 	vhost->devices[vdev->id] = NULL;
 	vhost->num_devices--;
 	vdev->id = VHBA_INVALID_ID;
-	spin_unlock_bh(&vhost->dev_lock);
+	spin_unlock_irqrestore(&vhost->dev_lock, flags);
 
 	vhba_device_put(vdev);
 
@@ -298,6 +303,7 @@
 
 static struct vhba_device *vhba_lookup_device(int id)
 {
+	unsigned long flags;
 	struct vhba_host *vhost;
 	struct vhba_device *vdev = NULL;
 
@@ -305,11 +311,11 @@
 
 	if (likely(id < vhost->shost->max_id))
 	{
-		spin_lock_bh(&vhost->dev_lock);
+		spin_lock_irqsave(&vhost->dev_lock, flags);
 		vdev = vhost->devices[id];
 		if (vdev)
 			vdev = vhba_device_get(vdev);
-		spin_unlock_bh(&vhost->dev_lock);
+		spin_unlock_irqrestore(&vhost->dev_lock, flags);
 	}
 
 	return vdev;
@@ -320,10 +326,11 @@
 	struct vhba_host *vhost;
 	struct vhba_command *vcmd;
 	int i;
-
+	unsigned long flags;
+	
 	vhost = platform_get_drvdata(&vhba_platform_device);
 
-	spin_lock_bh(&vhost->cmd_lock);
+	spin_lock_irqsave(&vhost->cmd_lock, flags);
 
 	vcmd = vhost->commands + vhost->cmd_next++;
 	if (vcmd->status != VHBA_REQ_FREE)
@@ -348,20 +355,21 @@
 		vcmd->status = VHBA_REQ_PENDING;
 	vhost->cmd_next %= vhost->shost->can_queue;
 
-	spin_unlock_bh(&vhost->cmd_lock);
+	spin_unlock_irqrestore(&vhost->cmd_lock, flags);
 
 	return vcmd;
 }
 
 static void vhba_free_command(struct vhba_command *vcmd)
 {
+	unsigned long flags;
 	struct vhba_host *vhost;
 
 	vhost = platform_get_drvdata(&vhba_platform_device);
 
-	spin_lock_bh(&vhost->cmd_lock);
+	spin_lock_irqsave(&vhost->cmd_lock, flags);
 	vcmd->status = VHBA_REQ_FREE;
-	spin_unlock_bh(&vhost->cmd_lock);
+	spin_unlock_irqrestore(&vhost->cmd_lock, flags);
 }
 
 static int vhba_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
@@ -591,6 +599,7 @@
 {
 	struct vhba_command *vcmd;
 	DEFINE_WAIT(wait);
+	unsigned long flags;
 
 	while (!(vcmd = next_command(vdev)))
 	{
@@ -599,11 +608,11 @@
 
 		prepare_to_wait(&vdev->cmd_wq, &wait, TASK_INTERRUPTIBLE);
 
-		spin_unlock_bh(&vdev->cmd_lock);
+		spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 		schedule();
 
-		spin_lock_bh(&vdev->cmd_lock);
+		spin_lock_irqsave(&vdev->cmd_lock, flags);
 	}
 
 	finish_wait(&vdev->cmd_wq, &wait);
@@ -615,22 +624,23 @@
 
 static ssize_t vhba_ctl_read(struct file *file, char __user *buf, size_t buf_len, loff_t *offset)
 {
+	unsigned long flags;
 	struct vhba_device *vdev;
 	struct vhba_command *vcmd;
 	ssize_t ret;
 
 	vdev = file->private_data;
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	vcmd = wait_command(vdev);
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	if (!vcmd)
 		return -ERESTARTSYS;
 
 	ret = do_request(vcmd->cmd, buf, buf_len);
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	if (ret >= 0)
 	{
 		vcmd->status = VHBA_REQ_SENT;
@@ -638,13 +648,14 @@
 	}
 	else
 		vcmd->status = VHBA_REQ_PENDING;
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	return ret;
 }
 
 static ssize_t vhba_ctl_write(struct file *file, const char __user *buf, size_t buf_len, loff_t *offset)
 {
+	unsigned long flags;
 	struct vhba_device *vdev;
 	struct vhba_command *vcmd;
 	struct vhba_response res;
@@ -658,21 +669,21 @@
 
 	vdev = file->private_data;
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	vcmd = match_command(vdev, res.tag);
 	if (!vcmd || vcmd->status != VHBA_REQ_SENT)
 	{
-		spin_unlock_bh(&vdev->cmd_lock);
+		spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 		DPRINTK("not expecting response\n");
 
 		return -EIO;
 	}
 	vcmd->status = VHBA_REQ_WRITING;
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	ret = do_response(vcmd->cmd, buf + sizeof(res), buf_len - sizeof(res), &res);
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	if (ret >= 0)
 	{
 		vcmd->cmd->scsi_done(vcmd->cmd);
@@ -687,22 +698,23 @@
 	}
 	else
 		vcmd->status = VHBA_REQ_SENT;
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	return ret;
 }
 
 static unsigned int vhba_ctl_poll(struct file *file, poll_table *wait)
 {
+	unsigned long flags;
 	struct vhba_device *vdev = file->private_data;
 	unsigned int mask = 0;
 
 	poll_wait(file, &vdev->cmd_wq, wait);
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	if (next_command(vdev))
 		mask |= POLLIN | POLLRDNORM;
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	return mask;
 }
@@ -732,6 +744,7 @@
 
 static int vhba_ctl_release(struct inode *inode, struct file *file)
 {
+	unsigned long flags;
 	struct vhba_device *vdev;
 	struct vhba_command *vcmd;
 
@@ -742,7 +755,7 @@
 	vhba_device_get(vdev);
 	vhba_remove_device(vdev);
 
-	spin_lock_bh(&vdev->cmd_lock);
+	spin_lock_irqsave(&vdev->cmd_lock, flags);
 	list_for_each_entry(vcmd, &vdev->cmd_list, entry)
 	{
 		WARN_ON(vcmd->status == VHBA_REQ_READING || vcmd->status == VHBA_REQ_WRITING);
@@ -754,7 +767,7 @@
 		vhba_free_command(vcmd);
 	}
 	INIT_LIST_HEAD(&vdev->cmd_list);
-	spin_unlock_bh(&vdev->cmd_lock);
+	spin_unlock_irqrestore(&vdev->cmd_lock, flags);
 
 	vhba_device_put(vdev);
 

