atari_NCR5380: Move static co-routine variables to host data
authorFinn Thain <fthain@telegraphics.com.au>
Wed, 12 Nov 2014 05:12:21 +0000 (16:12 +1100)
committerChristoph Hellwig <hch@lst.de>
Thu, 20 Nov 2014 08:11:20 +0000 (09:11 +0100)
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>
drivers/scsi/NCR5380.h
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c

index a6946f2d1dc0197b0a28ac6ef47b6bd74f2b3b33..162112dd1bf8eabeaf0c8bb029291742d6c55ce4 100644 (file)
@@ -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
index 590035f194e33aa43ea879d3d2a3e78d27ea6a8a..f1f9f479452798604fbc105e13bc097dcec1ee3a 100644 (file)
  * 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,
index b690106046999e225392efda7cd06f7e93fe0783..d1c37a386947b03d080524dac5f18c244580bd08 100644 (file)
 #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;
 }