#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
+#include <linux/blkdev.h>
 #include <asm/semaphore.h>
 #include <scsi/scsi.h>
 #include "scsi_priv.h"
 
 #define SPI_MAX_ECHO_BUFFER_SIZE       4096
 
+#define DV_LOOPS       3
+#define DV_TIMEOUT     (10*HZ)
+#define DV_RETRIES     3       /* should only need at most 
+                                * two cc/ua clears */
+
 /* Private data accessors (keep these out of the header file) */
 #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
 #define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)
        return result;
 }
 
+/* Modification of scsi_wait_req that will clear UNIT ATTENTION conditions
+ * resulting from (likely) bus and device resets */
+static void spi_wait_req(struct scsi_request *sreq, const void *cmd,
+                        void *buffer, unsigned bufflen)
+{
+       int i;
+
+       for(i = 0; i < DV_RETRIES; i++) {
+               sreq->sr_request->flags |= REQ_FAILFAST;
+
+               scsi_wait_req(sreq, cmd, buffer, bufflen,
+                             DV_TIMEOUT, /* retries */ 1);
+               if (sreq->sr_result & DRIVER_SENSE) {
+                       struct scsi_sense_hdr sshdr;
+
+                       if (scsi_request_normalize_sense(sreq, &sshdr)
+                           && sshdr.sense_key == UNIT_ATTENTION)
+                               continue;
+               }
+               break;
+       }
+}
+
 static struct {
        enum spi_signal_type    value;
        char                    *name;
        if(i->f->set_##x)               \
                i->f->set_##x(sdev->sdev_target, y)
 
-#define DV_LOOPS       3
-#define DV_TIMEOUT     (10*HZ)
-#define DV_RETRIES     3       /* should only need at most 
-                                * two cc/ua clears */
-
 enum spi_compare_returns {
        SPI_COMPARE_SUCCESS,
        SPI_COMPARE_FAILURE,
        for (r = 0; r < retries; r++) {
                sreq->sr_cmd_len = 0;   /* wait_req to fill in */
                sreq->sr_data_direction = DMA_TO_DEVICE;
-               scsi_wait_req(sreq, spi_write_buffer, buffer, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_write_buffer, buffer, len);
                if(sreq->sr_result || !scsi_device_online(sdev)) {
                        struct scsi_sense_hdr sshdr;
 
                memset(ptr, 0, len);
                sreq->sr_cmd_len = 0;   /* wait_req to fill in */
                sreq->sr_data_direction = DMA_FROM_DEVICE;
-               scsi_wait_req(sreq, spi_read_buffer, ptr, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_read_buffer, ptr, len);
                scsi_device_set_state(sdev, SDEV_QUIESCE);
 
                if (memcmp(buffer, ptr, len) != 0)
 
                memset(ptr, 0, len);
 
-               scsi_wait_req(sreq, spi_inquiry, ptr, len,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_inquiry, ptr, len);
                
                if(sreq->sr_result || !scsi_device_online(sdev)) {
                        scsi_device_set_state(sdev, SDEV_QUIESCE);
         * (reservation conflict, device not ready, etc) just
         * skip the write tests */
        for (l = 0; ; l++) {
-               scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0,
-                             DV_TIMEOUT, DV_RETRIES);
+               spi_wait_req(sreq, spi_test_unit_ready, NULL, 0);
 
                if(sreq->sr_result) {
                        if(l >= 3)
        sreq->sr_cmd_len = 0;
        sreq->sr_data_direction = DMA_FROM_DEVICE;
 
-       scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4,
-                     DV_TIMEOUT, DV_RETRIES);
+       spi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4);
 
        if (sreq->sr_result)
                /* Device has no echo buffer */