static unsigned int disconnect_mask = ~0;
 module_param(disconnect_mask, int, 0444);
 
-static int do_abort(struct Scsi_Host *);
+static int do_abort(struct Scsi_Host *, unsigned int);
 static void do_reset(struct Scsi_Host *);
 static void bus_reset_cleanup(struct Scsi_Host *);
 
  * @reg2: Second 5380 register to poll
  * @bit2: Second bitmask to check
  * @val2: Second expected value
- * @wait: Time-out in jiffies
+ * @wait: Time-out in jiffies, 0 if sleeping is not allowed
  *
  * Polls the chip in a reasonably efficient manner waiting for an
  * event to occur. After a short quick poll we begin to yield the CPU
                cpu_relax();
        } while (n--);
 
-       if (irqs_disabled() || in_interrupt())
+       if (!wait)
                return -ETIMEDOUT;
 
        /* Repeatedly sleep for 1 ms until deadline */
                        break;
                case 2:
                        shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
-                       do_abort(instance);
+                       do_abort(instance, 1);
                        break;
                case 4:
                        shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
                        if (toPIO > 0) {
                                dsprintk(NDEBUG_DMA, instance,
                                         "Doing %d byte PIO to 0x%p\n", cnt, *data);
-                               NCR5380_transfer_pio(instance, &p, &cnt, data);
+                               NCR5380_transfer_pio(instance, &p, &cnt, data, 0);
                                *count -= toPIO - cnt;
                        }
                }
                goto out;
        }
        if (!hostdata->selecting) {
-               do_abort(instance);
+               do_abort(instance, 0);
                return false;
        }
 
        len = 1;
        data = tmp;
        phase = PHASE_MSGOUT;
-       NCR5380_transfer_pio(instance, &phase, &len, &data);
+       NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
        if (len) {
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                cmd->result = DID_ERROR << 16;
  *
  * Inputs : instance - instance of driver, *phase - pointer to
  * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
+ * bytes to transfer, **data - pointer to data pointer,
+ * can_sleep - 1 or 0 when sleeping is permitted or not, respectively.
  *
  * Returns : -1 when different phase is entered without transferring
  * maximum number of bytes, 0 if all bytes are transferred or exit
 
 static int NCR5380_transfer_pio(struct Scsi_Host *instance,
                                unsigned char *phase, int *count,
-                               unsigned char **data)
+                               unsigned char **data, unsigned int can_sleep)
 {
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char p = *phase, tmp;
                 * valid
                 */
 
-               if (NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
+               if (NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ,
+                                         HZ * can_sleep) < 0)
                        break;
 
                dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
                }
 
                if (NCR5380_poll_politely(hostdata,
-                                         STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+                                         STATUS_REG, SR_REQ, 0, 5 * HZ * can_sleep) < 0)
                        break;
 
                dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
  * do_abort - abort the currently established nexus by going to
  * MESSAGE OUT phase and sending an ABORT message.
  * @instance: relevant scsi host instance
+ * @can_sleep: 1 or 0 when sleeping is permitted or not, respectively
  *
  * Returns 0 on success, negative error code on failure.
  */
 
-static int do_abort(struct Scsi_Host *instance)
+static int do_abort(struct Scsi_Host *instance, unsigned int can_sleep)
 {
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char *msgptr, phase, tmp;
         * the target sees, so we just handshake.
         */
 
-       rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
+       rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ,
+                                  10 * HZ * can_sleep);
        if (rc < 0)
                goto out;
 
        if (tmp != PHASE_MSGOUT) {
                NCR5380_write(INITIATOR_COMMAND_REG,
                              ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-               rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, 0, 3 * HZ);
+               rc = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, 0,
+                                          3 * HZ * can_sleep);
                if (rc < 0)
                        goto out;
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        msgptr = &tmp;
        len = 1;
        phase = PHASE_MSGOUT;
-       NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
+       NCR5380_transfer_pio(instance, &phase, &len, &msgptr, can_sleep);
        if (len)
                rc = -ENXIO;
 
                         */
 
                        if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
-                                                 BASR_DRQ, BASR_DRQ, HZ) < 0) {
+                                                 BASR_DRQ, BASR_DRQ, 0) < 0) {
                                result = -1;
                                shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
                        }
                        if (NCR5380_poll_politely(hostdata, STATUS_REG,
-                                                 SR_REQ, 0, HZ) < 0) {
+                                                 SR_REQ, 0, 0) < 0) {
                                result = -1;
                                shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
                        }
                         */
                        if (NCR5380_poll_politely2(hostdata,
                             BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
-                            BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) {
+                            BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, 0) < 0) {
                                result = -1;
                                shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
                        }
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
                                shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
                                sink = 1;
-                               do_abort(instance);
+                               do_abort(instance, 0);
                                cmd->result = DID_ERROR << 16;
                                complete_cmd(instance, cmd);
                                hostdata->connected = NULL;
                                                           NCR5380_PIO_CHUNK_SIZE);
                                        len = transfersize;
                                        NCR5380_transfer_pio(instance, &phase, &len,
-                                                            (unsigned char **)&cmd->SCp.ptr);
+                                                            (unsigned char **)&cmd->SCp.ptr,
+                                                            0);
                                        cmd->SCp.this_residual -= transfersize - len;
                                }
 #ifdef CONFIG_SUN3
                        case PHASE_MSGIN:
                                len = 1;
                                data = &tmp;
-                               NCR5380_transfer_pio(instance, &phase, &len, &data);
+                               NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
                                cmd->SCp.Message = tmp;
 
                                switch (tmp) {
                                        len = 2;
                                        data = extended_msg + 1;
                                        phase = PHASE_MSGIN;
-                                       NCR5380_transfer_pio(instance, &phase, &len, &data);
+                                       NCR5380_transfer_pio(instance, &phase, &len, &data, 1);
                                        dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
                                                 (int)extended_msg[1],
                                                 (int)extended_msg[2]);
                                                data = extended_msg + 3;
                                                phase = PHASE_MSGIN;
 
-                                               NCR5380_transfer_pio(instance, &phase, &len, &data);
+                                               NCR5380_transfer_pio(instance, &phase, &len, &data, 1);
                                                dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
                                                         len);
 
                                len = 1;
                                data = &msgout;
                                hostdata->last_message = msgout;
-                               NCR5380_transfer_pio(instance, &phase, &len, &data);
+                               NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
                                if (msgout == ABORT) {
                                        hostdata->connected = NULL;
                                        hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
                                 * PSEUDO-DMA architecture we should probably
                                 * use the dma transfer function.
                                 */
-                               NCR5380_transfer_pio(instance, &phase, &len, &data);
+                               NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
                                break;
                        case PHASE_STATIN:
                                len = 1;
                                data = &tmp;
-                               NCR5380_transfer_pio(instance, &phase, &len, &data);
+                               NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
                                cmd->SCp.Status = tmp;
                                break;
                        default:
 
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
        if (NCR5380_poll_politely(hostdata,
-                                 STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
+                                 STATUS_REG, SR_SEL, 0, 0) < 0) {
                shost_printk(KERN_ERR, instance, "reselect: !SEL timeout\n");
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                return;
         */
 
        if (NCR5380_poll_politely(hostdata,
-                                 STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+                                 STATUS_REG, SR_REQ, SR_REQ, 0) < 0) {
                if ((NCR5380_read(STATUS_REG) & (SR_BSY | SR_SEL)) == 0)
                        /* BUS FREE phase */
                        return;
                shost_printk(KERN_ERR, instance, "reselect: REQ timeout\n");
-               do_abort(instance);
+               do_abort(instance, 0);
                return;
        }
 
                unsigned char *data = msg;
                unsigned char phase = PHASE_MSGIN;
 
-               NCR5380_transfer_pio(instance, &phase, &len, &data);
+               NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
 
                if (len) {
-                       do_abort(instance);
+                       do_abort(instance, 0);
                        return;
                }
        }
                shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
                spi_print_msg(msg);
                printk("\n");
-               do_abort(instance);
+               do_abort(instance, 0);
                return;
        }
        lun = msg[0] & 0x07;
                 * Since we have an established nexus that we can't do anything
                 * with, we must abort it.
                 */
-               if (do_abort(instance) == 0)
+               if (do_abort(instance, 0) == 0)
                        hostdata->busy[target] &= ~(1 << lun);
                return;
        }
                dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
                hostdata->connected = NULL;
                hostdata->dma_len = 0;
-               if (do_abort(instance) < 0) {
+               if (do_abort(instance, 0) < 0) {
                        set_host_byte(cmd, DID_ERROR);
                        complete_cmd(instance, cmd);
                        result = FAILED;