Commit a53a21e4 authored by Finn Thain's avatar Finn Thain Committed by Christoph Hellwig

atari_NCR5380: Move static co-routine variables to host data

Unlike NCR5380.c, the atari_NCR5380.c core driver is limited to a single
instance because co-routine state is stored globally.

Fix this by removing the static scsi host pointer. For the co-routine,
obtain this pointer from the work_struct pointer instead. For the interrupt
handler, obtain it from the dev_id argument.
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 61d739a4
...@@ -283,6 +283,8 @@ struct NCR5380_hostdata { ...@@ -283,6 +283,8 @@ struct NCR5380_hostdata {
int read_overruns; /* number of bytes to cut from a int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */ * transfer to handle chip overruns */
int retain_dma_intr; int retain_dma_intr;
struct work_struct main_task;
volatile int main_running;
#ifdef SUPPORT_TAGS #ifdef SUPPORT_TAGS
struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */ struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */
#endif #endif
......
...@@ -221,9 +221,6 @@ ...@@ -221,9 +221,6 @@
* possible) function may be used. * possible) function may be used.
*/ */
static struct Scsi_Host *first_instance = NULL;
static struct scsi_host_template *the_template = NULL;
/* Macros ease life... :-) */ /* Macros ease life... :-) */
#define SETUP_HOSTDATA(in) \ #define SETUP_HOSTDATA(in) \
struct NCR5380_hostdata *hostdata = \ struct NCR5380_hostdata *hostdata = \
...@@ -595,32 +592,19 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) ...@@ -595,32 +592,19 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
static volatile int main_running; static inline void queue_main(struct NCR5380_hostdata *hostdata)
static DECLARE_WORK(NCR5380_tqueue, NCR5380_main);
static inline void queue_main(void)
{ {
if (!main_running) { if (!hostdata->main_running) {
/* If in interrupt and NCR5380_main() not already running, /* If in interrupt and NCR5380_main() not already running,
queue it on the 'immediate' task queue, to be processed queue it on the 'immediate' task queue, to be processed
immediately after the current interrupt processing has immediately after the current interrupt processing has
finished. */ finished. */
schedule_work(&NCR5380_tqueue); schedule_work(&hostdata->main_task);
} }
/* else: nothing to do: the running NCR5380_main() will pick up /* else: nothing to do: the running NCR5380_main() will pick up
any newly queued command. */ any newly queued command. */
} }
static inline void NCR5380_all_init(void)
{
static int done = 0;
if (!done) {
dprintk(NDEBUG_INIT, "scsi : NCR5380_all_init()\n");
done = 1;
}
}
/** /**
* NCR58380_info - report driver and host information * NCR58380_info - report driver and host information
* @instance: relevant scsi host instance * @instance: relevant scsi host instance
...@@ -703,7 +687,7 @@ static void NCR5380_print_status(struct Scsi_Host *instance) ...@@ -703,7 +687,7 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
local_irq_save(flags); local_irq_save(flags);
printk("NCR5380: coroutine is%s running.\n", printk("NCR5380: coroutine is%s running.\n",
main_running ? "" : "n't"); hostdata->main_running ? "" : "n't");
if (!hostdata->connected) if (!hostdata->connected)
printk("scsi%d: no currently connected command\n", HOSTNO); printk("scsi%d: no currently connected command\n", HOSTNO);
else else
...@@ -746,7 +730,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, ...@@ -746,7 +730,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m,
local_irq_save(flags); local_irq_save(flags);
seq_printf(m, "NCR5380: coroutine is%s running.\n", seq_printf(m, "NCR5380: coroutine is%s running.\n",
main_running ? "" : "n't"); hostdata->main_running ? "" : "n't");
if (!hostdata->connected) if (!hostdata->connected)
seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
else else
...@@ -783,8 +767,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) ...@@ -783,8 +767,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
int i; int i;
SETUP_HOSTDATA(instance); SETUP_HOSTDATA(instance);
NCR5380_all_init(); hostdata->host = instance;
hostdata->aborted = 0; hostdata->aborted = 0;
hostdata->id_mask = 1 << instance->this_id; hostdata->id_mask = 1 << instance->this_id;
hostdata->id_higher_mask = 0; hostdata->id_higher_mask = 0;
...@@ -805,10 +788,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) ...@@ -805,10 +788,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
hostdata->disconnected_queue = NULL; hostdata->disconnected_queue = NULL;
hostdata->flags = flags; hostdata->flags = flags;
if (!the_template) { INIT_WORK(&hostdata->main_task, NCR5380_main);
the_template = instance->hostt;
first_instance = instance;
}
prepare_info(instance); prepare_info(instance);
...@@ -829,7 +809,9 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) ...@@ -829,7 +809,9 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
static void NCR5380_exit(struct Scsi_Host *instance) static void NCR5380_exit(struct Scsi_Host *instance)
{ {
cancel_work_sync(&NCR5380_tqueue); struct NCR5380_hostdata *hostdata = shost_priv(instance);
cancel_work_sync(&hostdata->main_task);
} }
/** /**
...@@ -924,9 +906,9 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, ...@@ -924,9 +906,9 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
* unconditionally, because it cannot be already running. * unconditionally, because it cannot be already running.
*/ */
if (in_interrupt() || irqs_disabled()) if (in_interrupt() || irqs_disabled())
queue_main(); queue_main(hostdata);
else else
NCR5380_main(NULL); NCR5380_main(&hostdata->main_task);
return 0; return 0;
} }
...@@ -955,9 +937,10 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) ...@@ -955,9 +937,10 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
static void NCR5380_main(struct work_struct *work) static void NCR5380_main(struct work_struct *work)
{ {
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *tmp, *prev; struct scsi_cmnd *tmp, *prev;
struct Scsi_Host *instance = first_instance;
struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
int done; int done;
unsigned long flags; unsigned long flags;
...@@ -982,9 +965,9 @@ static void NCR5380_main(struct work_struct *work) ...@@ -982,9 +965,9 @@ static void NCR5380_main(struct work_struct *work)
'main_running' is set here, and queues/executes main via the 'main_running' is set here, and queues/executes main via the
task queue, it doesn't do any harm, just this instance of main task queue, it doesn't do any harm, just this instance of main
won't find any work left to do. */ won't find any work left to do. */
if (main_running) if (hostdata->main_running)
return; return;
main_running = 1; hostdata->main_running = 1;
local_save_flags(flags); local_save_flags(flags);
do { do {
...@@ -1103,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -1103,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work)
/* Better allow ints _after_ 'main_running' has been cleared, else /* Better allow ints _after_ 'main_running' has been cleared, else
an interrupt could believe we'll pick up the work it left for an interrupt could believe we'll pick up the work it left for
us, but we won't see it anymore here... */ us, but we won't see it anymore here... */
main_running = 0; hostdata->main_running = 0;
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -1215,7 +1198,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) ...@@ -1215,7 +1198,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
static irqreturn_t NCR5380_intr(int irq, void *dev_id) static irqreturn_t NCR5380_intr(int irq, void *dev_id)
{ {
struct Scsi_Host *instance = first_instance; struct Scsi_Host *instance = dev_id;
int done = 1, handled = 0; int done = 1, handled = 0;
unsigned char basr; unsigned char basr;
...@@ -1287,7 +1270,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id) ...@@ -1287,7 +1270,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
if (!done) { if (!done) {
dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO); dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO);
/* Put a call to NCR5380_main() on the queue... */ /* Put a call to NCR5380_main() on the queue... */
queue_main(); queue_main(shost_priv(instance));
} }
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
...@@ -1767,7 +1750,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, ...@@ -1767,7 +1750,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
* Returns : 0 on success, -1 on failure. * Returns : 0 on success, -1 on failure.
*/ */
static int do_abort(struct Scsi_Host *host) static int do_abort(struct Scsi_Host *instance)
{ {
unsigned char tmp, *msgptr, phase; unsigned char tmp, *msgptr, phase;
int len; int len;
...@@ -1802,7 +1785,7 @@ static int do_abort(struct Scsi_Host *host) ...@@ -1802,7 +1785,7 @@ static int do_abort(struct Scsi_Host *host)
msgptr = &tmp; msgptr = &tmp;
len = 1; len = 1;
phase = PHASE_MSGOUT; phase = PHASE_MSGOUT;
NCR5380_transfer_pio(host, &phase, &len, &msgptr); NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
/* /*
* If we got here, and the command completed successfully, * If we got here, and the command completed successfully,
......
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
#define NCR5380_dma_xfer_len(instance, cmd, phase) \ #define NCR5380_dma_xfer_len(instance, cmd, phase) \
atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO)) atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
#define NCR5380_acquire_dma_irq(instance) falcon_get_lock() #define NCR5380_acquire_dma_irq(instance) falcon_get_lock(instance)
#define NCR5380_release_dma_irq(instance) falcon_release_lock() #define NCR5380_release_dma_irq(instance) falcon_release_lock()
#include "NCR5380.h" #include "NCR5380.h"
...@@ -468,15 +468,15 @@ static void falcon_release_lock(void) ...@@ -468,15 +468,15 @@ static void falcon_release_lock(void)
* command immediately but tell the SCSI mid-layer to defer. * command immediately but tell the SCSI mid-layer to defer.
*/ */
static int falcon_get_lock(void) static int falcon_get_lock(struct Scsi_Host *instance)
{ {
if (IS_A_TT()) if (IS_A_TT())
return 1; return 1;
if (in_interrupt()) if (in_interrupt())
return stdma_try_lock(scsi_falcon_intr, NULL); return stdma_try_lock(scsi_falcon_intr, instance);
stdma_lock(scsi_falcon_intr, NULL); stdma_lock(scsi_falcon_intr, instance);
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment