--- /dev/null
+From chrisw@osdl.org Wed Dec 21 09:28:06 2005
+Message-Id: <200512180326.jBI3QTj1029647@shell0.pdx.osdl.net>
+To: torvalds@osdl.org
+From: akpm@osdl.org
+Date: Sat, 17 Dec 2005 19:26:30 -0800
+Cc: James.Bottomley@steeleye.com, miquels@cistron.nl, aacraid@adaptec.com,
+ stable@kernel.org, mark_salyzyn@adaptec.com
+Subject: [PATCH] dpt_i2o fix for deadlock condition
+
+From: "Salyzyn, Mark" <mark_salyzyn@adaptec.com>
+
+Miquel van Smoorenburg <miquels@cistron.nl> forwarded me this fix to
+resolve a deadlock condition that occurs due to the API change in 2.6.13+
+kernels dropping the host locking when entering the error handling. They
+all end up calling adpt_i2o_post_wait(), which if you call it unlocked,
+might return with host_lock locked anyway and that causes a deadlock.
+
+Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
+Cc: James Bottomley <James.Bottomley@steeleye.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Chris Wright <chrisw@redhat.com>
+---
+
+ drivers/scsi/dpt_i2o.c | 25 ++++++++++++++++++++-----
+ 1 files changed, 20 insertions(+), 5 deletions(-)
+
+Index: linux-2.6.14.y/drivers/scsi/dpt_i2o.c
+===================================================================
+--- linux-2.6.14.y.orig/drivers/scsi/dpt_i2o.c
++++ linux-2.6.14.y/drivers/scsi/dpt_i2o.c
+@@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd *
+ msg[2] = 0;
+ msg[3]= 0;
+ msg[4] = (u32)cmd;
+- if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
++ if (pHba->host)
++ spin_lock_irq(pHba->host->host_lock);
++ rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
++ if (pHba->host)
++ spin_unlock_irq(pHba->host->host_lock);
++ if (rcode != 0) {
+ if(rcode == -EOPNOTSUPP ){
+ printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
+ return FAILED;
+@@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi
+ msg[2] = 0;
+ msg[3] = 0;
+
++ if (pHba->host)
++ spin_lock_irq(pHba->host->host_lock);
+ old_state = d->state;
+ d->state |= DPTI_DEV_RESET;
+- if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
+- d->state = old_state;
++ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
++ d->state = old_state;
++ if (pHba->host)
++ spin_unlock_irq(pHba->host->host_lock);
++ if (rcode != 0) {
+ if(rcode == -EOPNOTSUPP ){
+ printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+ return FAILED;
+@@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi
+ printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+ return FAILED;
+ } else {
+- d->state = old_state;
+ printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+ return SUCCESS;
+ }
+@@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cm
+ {
+ adpt_hba* pHba;
+ u32 msg[4];
++ u32 rcode;
+
+ pHba = (adpt_hba*)cmd->device->host->hostdata[0];
+ memset(msg, 0, sizeof(msg));
+@@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cm
+ msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
+ msg[2] = 0;
+ msg[3] = 0;
+- if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
++ if (pHba->host)
++ spin_lock_irq(pHba->host->host_lock);
++ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
++ if (pHba->host)
++ spin_unlock_irq(pHba->host->host_lock);
++ if (rcode != 0) {
+ printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
+ return FAILED;
+ } else {