diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2014-11-12 16:12:21 +1100 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-20 09:11:20 +0100 |
commit | a53a21e4662fd2ed27863f511715898459312393 (patch) | |
tree | b770b830e1ab4843ae4f0e8139b0a02c69f0606c | |
parent | 61d739a4976424af0d2a62d8e8d0b2159702fb45 (diff) |
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: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | drivers/scsi/NCR5380.h | 2 | ||||
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 61 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 8 |
3 files changed, 28 insertions, 43 deletions
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index a6946f2d1dc0..162112dd1bf8 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -283,6 +283,8 @@ struct NCR5380_hostdata { int read_overruns; /* number of bytes to cut from a * transfer to handle chip overruns */ int retain_dma_intr; + struct work_struct main_task; + volatile int main_running; #ifdef SUPPORT_TAGS struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */ #endif diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 590035f194e3..f1f9f4794527 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -221,9 +221,6 @@ * possible) function may be used. */ -static struct Scsi_Host *first_instance = NULL; -static struct scsi_host_template *the_template = NULL; - /* Macros ease life... :-) */ #define SETUP_HOSTDATA(in) \ struct NCR5380_hostdata *hostdata = \ @@ -595,32 +592,19 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) #include <linux/workqueue.h> #include <linux/interrupt.h> -static volatile int main_running; -static DECLARE_WORK(NCR5380_tqueue, NCR5380_main); - -static inline void queue_main(void) +static inline void queue_main(struct NCR5380_hostdata *hostdata) { - if (!main_running) { + if (!hostdata->main_running) { /* If in interrupt and NCR5380_main() not already running, queue it on the 'immediate' task queue, to be processed immediately after the current interrupt processing has finished. */ - schedule_work(&NCR5380_tqueue); + schedule_work(&hostdata->main_task); } /* else: nothing to do: the running NCR5380_main() will pick up 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 * @instance: relevant scsi host instance @@ -703,7 +687,7 @@ static void NCR5380_print_status(struct Scsi_Host *instance) local_irq_save(flags); printk("NCR5380: coroutine is%s running.\n", - main_running ? "" : "n't"); + hostdata->main_running ? "" : "n't"); if (!hostdata->connected) printk("scsi%d: no currently connected command\n", HOSTNO); else @@ -746,7 +730,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, local_irq_save(flags); seq_printf(m, "NCR5380: coroutine is%s running.\n", - main_running ? "" : "n't"); + hostdata->main_running ? "" : "n't"); if (!hostdata->connected) seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); else @@ -783,8 +767,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) int i; SETUP_HOSTDATA(instance); - NCR5380_all_init(); - + hostdata->host = instance; hostdata->aborted = 0; hostdata->id_mask = 1 << instance->this_id; hostdata->id_higher_mask = 0; @@ -805,10 +788,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) hostdata->disconnected_queue = NULL; hostdata->flags = flags; - if (!the_template) { - the_template = instance->hostt; - first_instance = instance; - } + INIT_WORK(&hostdata->main_task, NCR5380_main); prepare_info(instance); @@ -829,7 +809,9 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) 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, * unconditionally, because it cannot be already running. */ if (in_interrupt() || irqs_disabled()) - queue_main(); + queue_main(hostdata); else - NCR5380_main(NULL); + NCR5380_main(&hostdata->main_task); return 0; } @@ -955,9 +937,10 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) 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_Host *instance = first_instance; - struct NCR5380_hostdata *hostdata = HOSTDATA(instance); int done; unsigned long flags; @@ -982,9 +965,9 @@ static void NCR5380_main(struct work_struct *work) 'main_running' is set here, and queues/executes main via the task queue, it doesn't do any harm, just this instance of main won't find any work left to do. */ - if (main_running) + if (hostdata->main_running) return; - main_running = 1; + hostdata->main_running = 1; local_save_flags(flags); do { @@ -1103,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work) /* Better allow ints _after_ 'main_running' has been cleared, else an interrupt could believe we'll pick up the work it left for us, but we won't see it anymore here... */ - main_running = 0; + hostdata->main_running = 0; local_irq_restore(flags); } @@ -1215,7 +1198,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) 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; unsigned char basr; @@ -1287,7 +1270,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id) if (!done) { dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO); /* Put a call to NCR5380_main() on the queue... */ - queue_main(); + queue_main(shost_priv(instance)); } return IRQ_RETVAL(handled); } @@ -1767,7 +1750,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, * 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; int len; @@ -1802,7 +1785,7 @@ static int do_abort(struct Scsi_Host *host) msgptr = &tmp; len = 1; 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, diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index b69010604699..d1c37a386947 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -110,7 +110,7 @@ #define NCR5380_dma_xfer_len(instance, cmd, phase) \ 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() #include "NCR5380.h" @@ -468,15 +468,15 @@ static void falcon_release_lock(void) * 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()) return 1; 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; } |