diff mbox series

[12/14] scsi: NCR5380: Remove in_interrupt().

Message ID 20201126132952.2287996-13-bigeasy@linutronix.de
State New
Headers show
Series scsi: Remove in_interrupt() usage. | expand

Commit Message

Sebastian Andrzej Siewior Nov. 26, 2020, 1:29 p.m. UTC
From: "Ahmed S. Darwish" <a.darwish@linutronix.de>

NCR5380_poll_politely2() uses in_interrupt() to check if it is safe to
sleep.

The usage of in_interrupt() in drivers is phased out and Linus clearly
requested that code which changes behaviour depending on context should
either be separated, or the context be explicitly conveyed in an
argument passed by the caller.

Below is a context analysis of NCR5380_poll_politely2() uppermost
callers:

  - NCR5380_maybe_reset_bus(), task, invoked during device probe.
    -> NCR5380_poll_politely()
    -> do_abort()

  - NCR5380_select(), task, but can only sleep in the "release, then
    re-acquire" regions of the spinlock held by its caller.
    Sleeping invocations (lock released):
    -> NCR5380_poll_politely2()

    Atomic invocations (lock acquired):
    -> NCR5380_reselect()
       -> NCR5380_poll_politely()
       -> do_abort()
       -> NCR5380_transfer_pio()

  - NCR5380_intr(), interrupt handler
    -> NCR5380_dma_complete()
       -> NCR5380_transfer_pio()
	  -> NCR5380_poll_politely()
    -> NCR5380_reselect() (see above)

  - NCR5380_information_transfer(), task, but can only sleep in the
    "release, then re-acquire" regions of the caller-held spinlock.
    Sleeping invocations (lock released):
      - NCR5380_transfer_pio() -> NCR5380_poll_politely()
      - NCR5380_poll_politely()

    Atomic invocations (lock acquired):
      - NCR5380_transfer_dma()
	-> NCR5380_dma_recv_setup()
           => generic_NCR5380_precv() -> NCR5380_poll_politely()
	   => macscsi_pread() -> NCR5380_poll_politely()

	-> NCR5380_dma_send_setup()
 	   => generic_NCR5380_psend -> NCR5380_poll_politely2()
	   => macscsi_pwrite() -> NCR5380_poll_politely()

	-> NCR5380_poll_politely2()
        -> NCR5380_dma_complete()
           -> NCR5380_transfer_pio()
	      -> NCR5380_poll_politely()
      - NCR5380_transfer_pio() -> NCR5380_poll_politely

  - NCR5380_reselect(), atomic, always called with hostdata spinlock
    held.

If direct callers are purely atomic, or purely task context, change
their specifications accordingly and mark them with "Context: " tags.

For the mixed ones, trickle-down context from upper layers.

Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Finn Thain <fthain@telegraphics.com.au>
Cc: Michael Schmitz <schmitzmic@gmail.com>
Cc: <linux-m68k@lists.linux-m68k.org>
---
 drivers/scsi/NCR5380.c   | 115 ++++++++++++++++++++++-----------------
 drivers/scsi/NCR5380.h   |   9 +--
 drivers/scsi/g_NCR5380.c |  26 ++++++---
 drivers/scsi/mac_scsi.c  |  10 ++--
 4 files changed, 93 insertions(+), 67 deletions(-)

Comments

Finn Thain Nov. 27, 2020, 4:37 a.m. UTC | #1
On Thu, 26 Nov 2020, Sebastian Andrzej Siewior wrote:

> From: "Ahmed S. Darwish" <a.darwish@linutronix.de>

> 

> NCR5380_poll_politely2() uses in_interrupt() to check if it is safe to

> sleep.

> 

> The usage of in_interrupt() in drivers is phased out and Linus clearly

> requested that code which changes behaviour depending on context should

> either be separated, or the context be explicitly conveyed in an

> argument passed by the caller.

> 

> Below is a context analysis of NCR5380_poll_politely2() uppermost

> callers:

> 

>   - NCR5380_maybe_reset_bus(), task, invoked during device probe.

>     -> NCR5380_poll_politely()

>     -> do_abort()

> 

>   - NCR5380_select(), task, but can only sleep in the "release, then

>     re-acquire" regions of the spinlock held by its caller.

>     Sleeping invocations (lock released):

>     -> NCR5380_poll_politely2()

> 

>     Atomic invocations (lock acquired):

>     -> NCR5380_reselect()

>        -> NCR5380_poll_politely()

>        -> do_abort()

>        -> NCR5380_transfer_pio()

> 

>   - NCR5380_intr(), interrupt handler

>     -> NCR5380_dma_complete()

>        -> NCR5380_transfer_pio()

> 	  -> NCR5380_poll_politely()

>     -> NCR5380_reselect() (see above)

> 

>   - NCR5380_information_transfer(), task, but can only sleep in the

>     "release, then re-acquire" regions of the caller-held spinlock.

>     Sleeping invocations (lock released):

>       - NCR5380_transfer_pio() -> NCR5380_poll_politely()

>       - NCR5380_poll_politely()

> 

>     Atomic invocations (lock acquired):

>       - NCR5380_transfer_dma()

> 	-> NCR5380_dma_recv_setup()

>            => generic_NCR5380_precv() -> NCR5380_poll_politely()

> 	   => macscsi_pread() -> NCR5380_poll_politely()

> 

> 	-> NCR5380_dma_send_setup()

>  	   => generic_NCR5380_psend -> NCR5380_poll_politely2()

> 	   => macscsi_pwrite() -> NCR5380_poll_politely()

> 

> 	-> NCR5380_poll_politely2()

>         -> NCR5380_dma_complete()

>            -> NCR5380_transfer_pio()

> 	      -> NCR5380_poll_politely()

>       - NCR5380_transfer_pio() -> NCR5380_poll_politely

> 

>   - NCR5380_reselect(), atomic, always called with hostdata spinlock

>     held.

> 

> If direct callers are purely atomic, or purely task context, change

> their specifications accordingly and mark them with "Context: " tags.

> 

> For the mixed ones, trickle-down context from upper layers.

> 

> Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>

> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>


Acked-by: Finn Thain <fthain@telegraphics.com.au>


> @@ -513,9 +513,11 @@ static void wait_for_53c80_access(struct NCR5380_hostdata *hostdata)

>   * @dst: buffer to write into

>   * @len: transfer size

>   *

> + * Context: atomic. This implements NCR5380.c NCR5380_dma_recv_setup(),

> + * which is always called with @hostdata spinlock held.

> + *

>   * Perform a pseudo DMA mode receive from a 53C400 or equivalent device.

>   */

> -

>  static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,

>                                          unsigned char *dst, int len)

>  {


BTW, if I was doing this, I'd omit all of the many gratuitous whitespace 
changes and I'd avoid copying so much program logic into the comments 
where it is redundant -- here I'd have written only "Context: atomic, 
spinlock held". However, no need to revise. Looks fine otherwise.
Finn Thain Nov. 27, 2020, 9:15 p.m. UTC | #2
On Fri, 27 Nov 2020, Finn Thain wrote:

> 

> On Thu, 26 Nov 2020, Sebastian Andrzej Siewior wrote:

> 

> > From: "Ahmed S. Darwish" <a.darwish@linutronix.de>

> > 

> > NCR5380_poll_politely2() uses in_interrupt() to check if it is safe to

> > sleep.

> > 

> > The usage of in_interrupt() in drivers is phased out and Linus clearly

> > requested that code which changes behaviour depending on context should

> > either be separated, or the context be explicitly conveyed in an

> > argument passed by the caller.

> > 

> > Below is a context analysis of NCR5380_poll_politely2() uppermost

> > callers:

> > 

> >   - NCR5380_maybe_reset_bus(), task, invoked during device probe.

> >     -> NCR5380_poll_politely()

> >     -> do_abort()

> > 

> >   - NCR5380_select(), task, but can only sleep in the "release, then

> >     re-acquire" regions of the spinlock held by its caller.

> >     Sleeping invocations (lock released):

> >     -> NCR5380_poll_politely2()

> > 

> >     Atomic invocations (lock acquired):

> >     -> NCR5380_reselect()

> >        -> NCR5380_poll_politely()

> >        -> do_abort()

> >        -> NCR5380_transfer_pio()

> > 

> >   - NCR5380_intr(), interrupt handler

> >     -> NCR5380_dma_complete()

> >        -> NCR5380_transfer_pio()

> > 	  -> NCR5380_poll_politely()

> >     -> NCR5380_reselect() (see above)

> > 

> >   - NCR5380_information_transfer(), task, but can only sleep in the

> >     "release, then re-acquire" regions of the caller-held spinlock.

> >     Sleeping invocations (lock released):

> >       - NCR5380_transfer_pio() -> NCR5380_poll_politely()

> >       - NCR5380_poll_politely()

> > 

> >     Atomic invocations (lock acquired):

> >       - NCR5380_transfer_dma()

> > 	-> NCR5380_dma_recv_setup()

> >            => generic_NCR5380_precv() -> NCR5380_poll_politely()

> > 	   => macscsi_pread() -> NCR5380_poll_politely()

> > 

> > 	-> NCR5380_dma_send_setup()

> >  	   => generic_NCR5380_psend -> NCR5380_poll_politely2()

> > 	   => macscsi_pwrite() -> NCR5380_poll_politely()

> > 

> > 	-> NCR5380_poll_politely2()

> >         -> NCR5380_dma_complete()

> >            -> NCR5380_transfer_pio()

> > 	      -> NCR5380_poll_politely()

> >       - NCR5380_transfer_pio() -> NCR5380_poll_politely

> > 

> >   - NCR5380_reselect(), atomic, always called with hostdata spinlock

> >     held.

> > 

> > If direct callers are purely atomic, or purely task context, change

> > their specifications accordingly and mark them with "Context: " tags.

> > 

> > For the mixed ones, trickle-down context from upper layers.

> > 

> > Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>

> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

> 

> Acked-by: Finn Thain <fthain@telegraphics.com.au>

> 


On second thoughts, have you considered this patch instead?

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d654a6cc4162..739def70cffb 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
 		cpu_relax();
 	} while (n--);
 
-	if (irqs_disabled() || in_interrupt())
+	/* We can't sleep when local irqs are disabled and callers ensure
+	 * that local irqs are disabled whenever we can't sleep.
+	 */
+	if (irqs_disabled())
 		return -ETIMEDOUT;
 
 	/* Repeatedly sleep for 1 ms until deadline */

> > @@ -513,9 +513,11 @@ static void wait_for_53c80_access(struct NCR5380_hostdata *hostdata)

> >   * @dst: buffer to write into

> >   * @len: transfer size

> >   *

> > + * Context: atomic. This implements NCR5380.c NCR5380_dma_recv_setup(),

> > + * which is always called with @hostdata spinlock held.

> > + *

> >   * Perform a pseudo DMA mode receive from a 53C400 or equivalent device.

> >   */

> > -

> >  static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,

> >                                          unsigned char *dst, int len)

> >  {

> 

> BTW, if I was doing this, I'd omit all of the many gratuitous whitespace 

> changes and I'd avoid copying so much program logic into the comments 

> where it is redundant -- here I'd have written only "Context: atomic, 

> spinlock held". However, no need to revise. Looks fine otherwise.

> 


Also BTW, the phrase "may sleep" expresses that the caller permits the 
callee to sleep. Whereas, "can sleep" expresses that the callee is put on 
notice by the caller that sleeping is a possibility. And since the caller 
determines the actual true or false value, and the callee determines 
whether sleeping actually takes place, only the former phrase makes sense.
Finn Thain Nov. 27, 2020, 9:48 p.m. UTC | #3
On Sat, 28 Nov 2020, Finn Thain wrote:

> 

> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

> index d654a6cc4162..739def70cffb 100644

> --- a/drivers/scsi/NCR5380.c

> +++ b/drivers/scsi/NCR5380.c

> @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

>  		cpu_relax();

>  	} while (n--);

>  

> -	if (irqs_disabled() || in_interrupt())

> +	/* We can't sleep when local irqs are disabled and callers ensure

> +	 * that local irqs are disabled whenever we can't sleep.

> +	 */

> +	if (irqs_disabled())

>  		return -ETIMEDOUT;

>  

>  	/* Repeatedly sleep for 1 ms until deadline */

> 


Michael, Andreas, would you please confirm that this is workable on Atari? 
The driver could sleep when IPL == 2 because arch_irqs_disabled_flags() 
would return false (on Atari). I'm wondering whether that would deadlock.
Ahmed S. Darwish Nov. 28, 2020, 7:28 a.m. UTC | #4
On Sat, Nov 28, 2020 at 08:48:00AM +1100, Finn Thain wrote:
>

> On Sat, 28 Nov 2020, Finn Thain wrote:

>

> >

> > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

> > index d654a6cc4162..739def70cffb 100644

> > --- a/drivers/scsi/NCR5380.c

> > +++ b/drivers/scsi/NCR5380.c

> > @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

> >  		cpu_relax();

> >  	} while (n--);

> >

> > -	if (irqs_disabled() || in_interrupt())

> > +	/* We can't sleep when local irqs are disabled and callers ensure

> > +	 * that local irqs are disabled whenever we can't sleep.

> > +	 */

> > +	if (irqs_disabled())

> >  		return -ETIMEDOUT;

> >

> >  	/* Repeatedly sleep for 1 ms until deadline */

> >

>

> Michael, Andreas, would you please confirm that this is workable on Atari?

> The driver could sleep when IPL == 2 because arch_irqs_disabled_flags()

> would return false (on Atari). I'm wondering whether that would deadlock.


Please re-check the commit log:

  "Linus clearly requested that code which changes behaviour depending
   on context should either be separated, or the context be explicitly
   conveyed in an argument passed by the caller."

So, sorry, drivers shouldn't do context-dependent dances anymore.

For more context (no pun intended), please check the thread mentioned in
the cover letter, and also below message:

  https://lkml.kernel.org/r/CAKMK7uHAk9-Vy2cof0ws=DrcD52GHiCDiyHbjLd19CgpBU2rKQ@mail.gmail.com

Kind regards,

--
Ahmed S. Darwish
Linutronix GmbH
Michael Schmitz Nov. 29, 2020, 6:54 a.m. UTC | #5
Hi Finn,

Am 28.11.20 um 10:48 schrieb Finn Thain:
> On Sat, 28 Nov 2020, Finn Thain wrote:

>

>> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

>> index d654a6cc4162..739def70cffb 100644

>> --- a/drivers/scsi/NCR5380.c

>> +++ b/drivers/scsi/NCR5380.c

>> @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

>>  		cpu_relax();

>>  	} while (n--);

>>  

>> -	if (irqs_disabled() || in_interrupt())

>> +	/* We can't sleep when local irqs are disabled and callers ensure

>> +	 * that local irqs are disabled whenever we can't sleep.

>> +	 */

>> +	if (irqs_disabled())

>>  		return -ETIMEDOUT;

>>  

>>  	/* Repeatedly sleep for 1 ms until deadline */

>>

> Michael, Andreas, would you please confirm that this is workable on Atari? 

> The driver could sleep when IPL == 2 because arch_irqs_disabled_flags() 

> would return false (on Atari). I'm wondering whether that would deadlock.


Pretty sure this would deadlock when in interrupt context here.
Otherwise, IPL 2 is perfectly OK (which is why
arch_irqs_disabled_flags() returns false in that case).

If you want to be 100% certain, I can give this one a spin.

Cheers,

    Michael
Finn Thain Nov. 30, 2020, 12:15 a.m. UTC | #6
On Sun, 29 Nov 2020, Michael Schmitz wrote:

> Am 28.11.20 um 10:48 schrieb Finn Thain:

> > On Sat, 28 Nov 2020, Finn Thain wrote:

> >

> >> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

> >> index d654a6cc4162..739def70cffb 100644

> >> --- a/drivers/scsi/NCR5380.c

> >> +++ b/drivers/scsi/NCR5380.c

> >> @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

> >>  		cpu_relax();

> >>  	} while (n--);

> >>  

> >> -	if (irqs_disabled() || in_interrupt())

> >> +	/* We can't sleep when local irqs are disabled and callers ensure

> >> +	 * that local irqs are disabled whenever we can't sleep.

> >> +	 */

> >> +	if (irqs_disabled())

> >>  		return -ETIMEDOUT;

> >>  

> >>  	/* Repeatedly sleep for 1 ms until deadline */

> >>

> > Michael, Andreas, would you please confirm that this is workable on 

> > Atari? The driver could sleep when IPL == 2 because 

> > arch_irqs_disabled_flags() would return false (on Atari). I'm 

> > wondering whether that would deadlock.

> 

> Pretty sure this would deadlock when in interrupt context here.


When in interrupt context, irqs_disabled() is true due to 
spinlock_irqsave/restore() in NCR5380_intr().

My question was really about what would happen if we sleep with IPL == 2.

> Otherwise, IPL 2 is perfectly OK (which is why 

> arch_irqs_disabled_flags() returns false in that case).

> 

> If you want to be 100% certain, I can give this one a spin.

> 


Please only test it if you think it will work.

> Cheers,

> 

>     Michael

> 

>
Finn Thain Nov. 30, 2020, 12:21 a.m. UTC | #7
On Sat, 28 Nov 2020, Ahmed S. Darwish wrote:

> On Sat, Nov 28, 2020 at 08:48:00AM +1100, Finn Thain wrote:

> >

> > On Sat, 28 Nov 2020, Finn Thain wrote:

> >

> > >

> > > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

> > > index d654a6cc4162..739def70cffb 100644

> > > --- a/drivers/scsi/NCR5380.c

> > > +++ b/drivers/scsi/NCR5380.c

> > > @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

> > >  		cpu_relax();

> > >  	} while (n--);

> > >

> > > -	if (irqs_disabled() || in_interrupt())

> > > +	/* We can't sleep when local irqs are disabled and callers ensure

> > > +	 * that local irqs are disabled whenever we can't sleep.

> > > +	 */

> > > +	if (irqs_disabled())

> > >  		return -ETIMEDOUT;

> > >

> > >  	/* Repeatedly sleep for 1 ms until deadline */

> > >

> >

> > Michael, Andreas, would you please confirm that this is workable on Atari?

> > The driver could sleep when IPL == 2 because arch_irqs_disabled_flags()

> > would return false (on Atari). I'm wondering whether that would deadlock.

> 

> Please re-check the commit log:

> 

>   "Linus clearly requested that code which changes behaviour depending

>    on context should either be separated, or the context be explicitly

>    conveyed in an argument passed by the caller."

> 


Yes, I knew about the discussion around the issues with preempt_count() 
and CONFIG_PREEMPT. And I don't have any problem with removing 
in_interrupt(), as you can see from my patch.

> So, sorry, drivers shouldn't do context-dependent dances anymore.

> 


I don't know what is meant by 'context-dependent'. I suspect that it's 
left ill-defined because there are many cases where global state is 
needed, such as those mentioned in the thread you cited, like the 
memalloc_no*() calls. See also, in_compat_syscall().

> For more context (no pun intended), please check the thread mentioned in

> the cover letter, and also below message:

> 

>   https://lkml.kernel.org/r/CAKMK7uHAk9-Vy2cof0ws=DrcD52GHiCDiyHbjLd19CgpBU2rKQ@mail.gmail.com

> 


Are you also planning to remove spin_lock_irqsave/restore() and replace 
these with spin_lock_irq/unlock_irq()? And if not, why do you object to 
irqs_disabled()?

Please also compare your patch and mine with regard to stack usage, 
readability and code size. Also consider that adding a new argument to all 
those functions creates new opportunities for mistakes in new callers.

> Kind regards,

> 

> --

> Ahmed S. Darwish

> Linutronix GmbH

>
Michael Schmitz Nov. 30, 2020, 2:42 a.m. UTC | #8
Hi Finn,

Am 30.11.2020 um 13:15 schrieb Finn Thain:
> On Sun, 29 Nov 2020, Michael Schmitz wrote:

>

>> Am 28.11.20 um 10:48 schrieb Finn Thain:

>>> On Sat, 28 Nov 2020, Finn Thain wrote:

>>>

>>>> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c

>>>> index d654a6cc4162..739def70cffb 100644

>>>> --- a/drivers/scsi/NCR5380.c

>>>> +++ b/drivers/scsi/NCR5380.c

>>>> @@ -223,7 +223,10 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,

>>>>  		cpu_relax();

>>>>  	} while (n--);

>>>>

>>>> -	if (irqs_disabled() || in_interrupt())

>>>> +	/* We can't sleep when local irqs are disabled and callers ensure

>>>> +	 * that local irqs are disabled whenever we can't sleep.

>>>> +	 */

>>>> +	if (irqs_disabled())

>>>>  		return -ETIMEDOUT;

>>>>

>>>>  	/* Repeatedly sleep for 1 ms until deadline */

>>>>

>>> Michael, Andreas, would you please confirm that this is workable on

>>> Atari? The driver could sleep when IPL == 2 because

>>> arch_irqs_disabled_flags() would return false (on Atari). I'm

>>> wondering whether that would deadlock.

>>

>> Pretty sure this would deadlock when in interrupt context here.

>

> When in interrupt context, irqs_disabled() is true due to

> spinlock_irqsave/restore() in NCR5380_intr().


OK.

> My question was really about what would happen if we sleep with IPL == 2.


All relevant system interrupts are at higher priority (5 or 6). Both 
timer and SCSI / DMA completion interrupt in particular are at IPL 6 and 
won't be blocked when sleeping with IPL == 2. That's what I meant by 
'IPL 2 is perfectly OK' below.

>> Otherwise, IPL 2 is perfectly OK (which is why

>> arch_irqs_disabled_flags() returns false in that case).

>>

>> If you want to be 100% certain, I can give this one a spin.

>>

>

> Please only test it if you think it will work.


With your explanation above, I'm now quite certain your patch will work. 
I've not seen deadlocks in softirq context since you rewrote the driver 
so it will no more sleep waiting for the ST-DMA lock.

Cheers,

	Michael
diff mbox series

Patch

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d597d7493a627..51a80f3330faa 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -132,7 +132,7 @@ 
 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 *, bool);
 static void do_reset(struct Scsi_Host *);
 static void bus_reset_cleanup(struct Scsi_Host *);
 
@@ -198,6 +198,7 @@  static inline void set_resid_from_SCp(struct scsi_cmnd *cmd)
  * @bit2: Second bitmask to check
  * @val2: Second expected value
  * @wait: Time-out in jiffies
+ * @can_sleep: True if the function can sleep
  *
  * 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
@@ -210,7 +211,7 @@  static inline void set_resid_from_SCp(struct scsi_cmnd *cmd)
 static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
                                   unsigned int reg1, u8 bit1, u8 val1,
                                   unsigned int reg2, u8 bit2, u8 val2,
-                                  unsigned long wait)
+                                  unsigned long wait, bool can_sleep)
 {
 	unsigned long n = hostdata->poll_loops;
 	unsigned long deadline = jiffies + wait;
@@ -223,7 +224,7 @@  static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata,
 		cpu_relax();
 	} while (n--);
 
-	if (irqs_disabled() || in_interrupt())
+	if (!can_sleep)
 		return -ETIMEDOUT;
 
 	/* Repeatedly sleep for 1 ms until deadline */
@@ -467,9 +468,10 @@  static int NCR5380_init(struct Scsi_Host *instance, int flags)
  *
  * Note that a bus reset will cause the chip to assert IRQ.
  *
+ * Context: task, can sleep
+ *
  * Returns 0 if successful, otherwise -ENXIO.
  */
-
 static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
@@ -482,11 +484,11 @@  static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
 		case 5:
 			shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
 			NCR5380_poll_politely(hostdata,
-			                      STATUS_REG, SR_BSY, 0, 5 * HZ);
+			                      STATUS_REG, SR_BSY, 0, 5 * HZ, true);
 			break;
 		case 2:
 			shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
-			do_abort(instance);
+			do_abort(instance, true);
 			break;
 		case 4:
 			shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
@@ -690,7 +692,6 @@  static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
  * NCR5380_queue_command() and NCR5380_intr() will try to start it
  * in case it is not running.
  */
-
 static void NCR5380_main(struct work_struct *work)
 {
 	struct NCR5380_hostdata *hostdata =
@@ -750,10 +751,9 @@  static void NCR5380_main(struct work_struct *work)
  * NCR5380_dma_complete - finish DMA transfer
  * @instance: the scsi host instance
  *
- * Called by the interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would end the DMA transfer).
+ * Context: atomic. Called by the interrupt handler when DMA finishes
+ * or a phase mismatch occurs (which would end the DMA transfer).
  */
-
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
@@ -822,7 +822,7 @@  static void NCR5380_dma_complete(struct Scsi_Host *instance)
 			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, false);
 				*count -= toPIO - cnt;
 			}
 		}
@@ -962,8 +962,11 @@  static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
  *
  * If failed (no target) : cmd->scsi_done() will be called, and the
  * cmd->result host byte set to DID_BAD_TARGET.
+ *
+ * Context: task context, with @instance hostdata spinlock held by
+ * caller.  That is, this function can sleep in the areas between
+ * releasing and re-acquring that spinlock.
  */
-
 static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 	__releases(&hostdata->lock) __acquires(&hostdata->lock)
 {
@@ -1010,8 +1013,10 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
 	spin_unlock_irq(&hostdata->lock);
 	err = NCR5380_poll_politely2(hostdata, MODE_REG, MR_ARBITRATE, 0,
-	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
-	                                       ICR_ARBITRATION_PROGRESS, HZ);
+				     INITIATOR_COMMAND_REG,
+				     ICR_ARBITRATION_PROGRESS,
+				     ICR_ARBITRATION_PROGRESS,
+				     HZ, true);
 	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
@@ -1136,7 +1141,7 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 	 */
 
 	err = NCR5380_poll_politely(hostdata, STATUS_REG, SR_BSY, SR_BSY,
-	                            msecs_to_jiffies(250));
+	                            msecs_to_jiffies(250), true);
 
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		spin_lock_irq(&hostdata->lock);
@@ -1181,7 +1186,7 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
 	/* Wait for start of REQ/ACK handshake */
 
-	err = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ);
+	err = NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ, true);
 	spin_lock_irq(&hostdata->lock);
 	if (err < 0) {
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
@@ -1189,7 +1194,7 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 		goto out;
 	}
 	if (!hostdata->selecting) {
-		do_abort(instance);
+		do_abort(instance, false);
 		return false;
 	}
 
@@ -1200,7 +1205,7 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 	len = 1;
 	data = tmp;
 	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
+	NCR5380_transfer_pio(instance, &phase, &len, &data, false);
 	if (len) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_ERROR << 16;
@@ -1238,7 +1243,8 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
  *
  * 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 - whether it is safe to sleep.
  *
  * Returns : -1 when different phase is entered without transferring
  * maximum number of bytes, 0 if all bytes are transferred or exit
@@ -1257,7 +1263,7 @@  static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
 static int NCR5380_transfer_pio(struct Scsi_Host *instance,
 				unsigned char *phase, int *count,
-				unsigned char **data)
+				unsigned char **data, bool can_sleep)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char p = *phase, tmp;
@@ -1278,7 +1284,8 @@  static int NCR5380_transfer_pio(struct Scsi_Host *instance,
 		 * 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");
@@ -1324,7 +1331,7 @@  static int NCR5380_transfer_pio(struct Scsi_Host *instance,
 		}
 
 		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");
@@ -1399,11 +1406,12 @@  static void do_reset(struct Scsi_Host *instance)
  * 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: true if the function can sleep
  *
  * 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, bool can_sleep)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char *msgptr, phase, tmp;
@@ -1423,7 +1431,8 @@  static int do_abort(struct Scsi_Host *instance)
 	 * 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;
 
@@ -1434,7 +1443,8 @@  static int do_abort(struct Scsi_Host *instance)
 	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);
@@ -1444,7 +1454,7 @@  static int do_abort(struct Scsi_Host *instance)
 	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;
 
@@ -1474,9 +1484,9 @@  static int do_abort(struct Scsi_Host *instance)
  * is in same phase.
  *
  * Also, *phase, *count, *data are modified in place.
+ *
+ * Context: atomic, @instance hostdata spinlock held
  */
-
-
 static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 				unsigned char *phase, int *count,
 				unsigned char **data)
@@ -1623,12 +1633,12 @@  static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 			 */
 
 			if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
-			                          BASR_DRQ, BASR_DRQ, HZ) < 0) {
+			                          BASR_DRQ, BASR_DRQ, HZ, false) < 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, HZ, false) < 0) {
 				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
@@ -1640,7 +1650,7 @@  static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 			 */
 			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, HZ, false) < 0) {
 				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
 			}
@@ -1666,8 +1676,11 @@  static int NCR5380_transfer_dma(struct Scsi_Host *instance,
  *
  * XXX Note : we need to watch for bus free or a reset condition here
  * to recover from an unexpected bus free condition.
+ *
+ * Context: task context, with @instance hostdata spinlock held by
+ * caller.  That is, this function can sleep in the areas between
+ * releasing and re-acquring that spinlock.
  */
-
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 	__releases(&hostdata->lock) __acquires(&hostdata->lock)
 {
@@ -1737,7 +1750,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 #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, false);
 				cmd->result = DID_ERROR << 16;
 				complete_cmd(instance, cmd);
 				hostdata->connected = NULL;
@@ -1793,7 +1806,8 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 							   NCR5380_PIO_CHUNK_SIZE);
 					len = transfersize;
 					NCR5380_transfer_pio(instance, &phase, &len,
-					                     (unsigned char **)&cmd->SCp.ptr);
+					                     (unsigned char **)&cmd->SCp.ptr,
+							     false);
 					cmd->SCp.this_residual -= transfersize - len;
 				}
 #ifdef CONFIG_SUN3
@@ -1804,7 +1818,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 			case PHASE_MSGIN:
 				len = 1;
 				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
+				NCR5380_transfer_pio(instance, &phase, &len, &data, false);
 				cmd->SCp.Message = tmp;
 
 				switch (tmp) {
@@ -1910,7 +1924,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 					len = 2;
 					data = extended_msg + 1;
 					phase = PHASE_MSGIN;
-					NCR5380_transfer_pio(instance, &phase, &len, &data);
+					NCR5380_transfer_pio(instance, &phase, &len, &data, true);
 					dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
 					         (int)extended_msg[1],
 					         (int)extended_msg[2]);
@@ -1923,7 +1937,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 						data = extended_msg + 3;
 						phase = PHASE_MSGIN;
 
-						NCR5380_transfer_pio(instance, &phase, &len, &data);
+						NCR5380_transfer_pio(instance, &phase, &len, &data, true);
 						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
 						         len);
 
@@ -1970,7 +1984,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 				len = 1;
 				data = &msgout;
 				hostdata->last_message = msgout;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
+				NCR5380_transfer_pio(instance, &phase, &len, &data, false);
 				if (msgout == ABORT) {
 					hostdata->connected = NULL;
 					hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
@@ -1988,12 +2002,12 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 				 * 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, false);
 				break;
 			case PHASE_STATIN:
 				len = 1;
 				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
+				NCR5380_transfer_pio(instance, &phase, &len, &data, false);
 				cmd->SCp.Status = tmp;
 				break;
 			default:
@@ -2002,7 +2016,7 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
 			} /* switch(phase) */
 		} else {
 			spin_unlock_irq(&hostdata->lock);
-			NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ);
+			NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ, true);
 			spin_lock_irq(&hostdata->lock);
 		}
 	}
@@ -2016,8 +2030,9 @@  static void NCR5380_information_transfer(struct Scsi_Host *instance)
  * nexus has been reestablished,
  *
  * Inputs : instance - this instance of the NCR5380.
+ *
+ * Context: atomic, with @instance hostdata spinlock held
  */
-
 static void NCR5380_reselect(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
@@ -2052,7 +2067,7 @@  static void NCR5380_reselect(struct Scsi_Host *instance)
 
 	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, 2 * HZ, false) < 0) {
 		shost_printk(KERN_ERR, instance, "reselect: !SEL timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		return;
@@ -2064,12 +2079,12 @@  static void NCR5380_reselect(struct Scsi_Host *instance)
 	 */
 
 	if (NCR5380_poll_politely(hostdata,
-	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ, false) < 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, false);
 		return;
 	}
 
@@ -2085,10 +2100,10 @@  static void NCR5380_reselect(struct Scsi_Host *instance)
 		unsigned char *data = msg;
 		unsigned char phase = PHASE_MSGIN;
 
-		NCR5380_transfer_pio(instance, &phase, &len, &data);
+		NCR5380_transfer_pio(instance, &phase, &len, &data, false);
 
 		if (len) {
-			do_abort(instance);
+			do_abort(instance, false);
 			return;
 		}
 	}
@@ -2098,7 +2113,7 @@  static void NCR5380_reselect(struct Scsi_Host *instance)
 		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
 		spi_print_msg(msg);
 		printk("\n");
-		do_abort(instance);
+		do_abort(instance, false);
 		return;
 	}
 	lun = msg[0] & 0x07;
@@ -2138,7 +2153,7 @@  static void NCR5380_reselect(struct Scsi_Host *instance)
 		 * 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, false) == 0)
 			hostdata->busy[target] &= ~(1 << lun);
 		return;
 	}
@@ -2285,7 +2300,7 @@  static int NCR5380_abort(struct scsi_cmnd *cmd)
 		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, false) < 0) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
 			result = FAILED;
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 5935fd6d1a058..7c569e92ca58e 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -277,20 +277,21 @@  static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static bool NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
-static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
+static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase,
+				int *count, unsigned char **data, bool can_sleep);
 static int NCR5380_poll_politely2(struct NCR5380_hostdata *,
                                   unsigned int, u8, u8,
-                                  unsigned int, u8, u8, unsigned long);
+                                  unsigned int, u8, u8, unsigned long, bool);
 
 static inline int NCR5380_poll_politely(struct NCR5380_hostdata *hostdata,
                                         unsigned int reg, u8 bit, u8 val,
-                                        unsigned long wait)
+                                        unsigned long wait, bool can_sleep)
 {
 	if ((NCR5380_read(reg) & bit) == val)
 		return 0;
 
 	return NCR5380_poll_politely2(hostdata, reg, bit, val,
-						reg, bit, val, wait);
+				      reg, bit, val, wait, can_sleep);
 }
 
 static int NCR5380_dma_xfer_len(struct NCR5380_hostdata *,
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 29e4cdcade720..06b1fcfd33cc9 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -513,9 +513,11 @@  static void wait_for_53c80_access(struct NCR5380_hostdata *hostdata)
  * @dst: buffer to write into
  * @len: transfer size
  *
+ * Context: atomic. This implements NCR5380.c NCR5380_dma_recv_setup(),
+ * which is always called with @hostdata spinlock held.
+ *
  * Perform a pseudo DMA mode receive from a 53C400 or equivalent device.
  */
-
 static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
                                         unsigned char *dst, int len)
 {
@@ -529,14 +531,16 @@  static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
 		if (start == len - 128) {
 			/* Ignore End of DMA interrupt for the final buffer */
 			if (NCR5380_poll_politely(hostdata, hostdata->c400_ctl_status,
-			                          CSR_HOST_BUF_NOT_RDY, 0, HZ / 64) < 0)
+			                          CSR_HOST_BUF_NOT_RDY, 0, HZ / 64,
+						  false) < 0)
 				break;
 		} else {
 			if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
 			                           CSR_HOST_BUF_NOT_RDY, 0,
 			                           hostdata->c400_ctl_status,
 			                           CSR_GATED_53C80_IRQ,
-			                           CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
+			                           CSR_GATED_53C80_IRQ, HZ / 64,
+						   false) < 0 ||
 			    NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 				break;
 		}
@@ -565,7 +569,8 @@  static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
 	if (residual == 0 && NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
 	                                           BASR_END_DMA_TRANSFER,
 	                                           BASR_END_DMA_TRANSFER,
-	                                           HZ / 64) < 0)
+	                                           HZ / 64,
+						   false) < 0)
 		scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
 		            __func__);
 
@@ -580,9 +585,11 @@  static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
  * @src: buffer to read from
  * @len: transfer size
  *
+ * Context: atomic. This implements NCR5380.c NCR5380_dma_send_setup(),
+ * which is always called with @hostdata spinlock held.
+ *
  * Perform a pseudo DMA mode send to a 53C400 or equivalent device.
  */
-
 static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
                                         unsigned char *src, int len)
 {
@@ -597,7 +604,8 @@  static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
 		                           CSR_HOST_BUF_NOT_RDY, 0,
 		                           hostdata->c400_ctl_status,
 		                           CSR_GATED_53C80_IRQ,
-		                           CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
+		                           CSR_GATED_53C80_IRQ, HZ / 64,
+					   false) < 0 ||
 		    NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) {
 			/* Both 128 B buffers are in use */
 			if (start >= 128)
@@ -644,13 +652,15 @@  static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
 	if (residual == 0) {
 		if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
 		                          TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT,
-		                          HZ / 64) < 0)
+		                          HZ / 64,
+					  false) < 0)
 			scmd_printk(KERN_ERR, hostdata->connected,
 			            "%s: Last Byte Sent timeout\n", __func__);
 
 		if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
 		                          BASR_END_DMA_TRANSFER, BASR_END_DMA_TRANSFER,
-		                          HZ / 64) < 0)
+		                          HZ / 64,
+					  false) < 0)
 			scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
 			            __func__);
 	}
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index b5dde9d0d0545..3c39db74fd847 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -285,7 +285,7 @@  static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
 
 	while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
 	                              BASR_DRQ | BASR_PHASE_MATCH,
-	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64, false)) {
 		int bytes;
 
 		if (macintosh_config->ident == MAC_MODEL_IIFX)
@@ -304,7 +304,7 @@  static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
 
 		if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
 		                           BUS_AND_STATUS_REG, BASR_ACK,
-		                           BASR_ACK, HZ / 64) < 0)
+		                           BASR_ACK, HZ / 64, false) < 0)
 			scmd_printk(KERN_DEBUG, hostdata->connected,
 			            "%s: !REQ and !ACK\n", __func__);
 		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
@@ -344,7 +344,7 @@  static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
 
 	while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
 	                              BASR_DRQ | BASR_PHASE_MATCH,
-	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64, false)) {
 		int bytes;
 
 		if (macintosh_config->ident == MAC_MODEL_IIFX)
@@ -362,7 +362,7 @@  static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
 			if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
 			                          TCR_LAST_BYTE_SENT,
 			                          TCR_LAST_BYTE_SENT,
-			                          HZ / 64) < 0) {
+			                          HZ / 64, false) < 0) {
 				scmd_printk(KERN_ERR, hostdata->connected,
 				            "%s: Last Byte Sent timeout\n", __func__);
 				result = -1;
@@ -372,7 +372,7 @@  static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
 
 		if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
 		                           BUS_AND_STATUS_REG, BASR_ACK,
-		                           BASR_ACK, HZ / 64) < 0)
+		                           BASR_ACK, HZ / 64, false) < 0)
 			scmd_printk(KERN_DEBUG, hostdata->connected,
 			            "%s: !REQ and !ACK\n", __func__);
 		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))