diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2014-11-12 00:12:21 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-20 03:11:20 -0500 |
commit | a53a21e4662fd2ed27863f511715898459312393 (patch) | |
tree | b770b830e1ab4843ae4f0e8139b0a02c69f0606c /drivers/scsi/atari_NCR5380.c | |
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>
Diffstat (limited to 'drivers/scsi/atari_NCR5380.c')
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 61 |
1 files changed, 22 insertions, 39 deletions
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 @@ | |||
221 | * possible) function may be used. | 221 | * possible) function may be used. |
222 | */ | 222 | */ |
223 | 223 | ||
224 | static struct Scsi_Host *first_instance = NULL; | ||
225 | static struct scsi_host_template *the_template = NULL; | ||
226 | |||
227 | /* Macros ease life... :-) */ | 224 | /* Macros ease life... :-) */ |
228 | #define SETUP_HOSTDATA(in) \ | 225 | #define SETUP_HOSTDATA(in) \ |
229 | struct NCR5380_hostdata *hostdata = \ | 226 | struct NCR5380_hostdata *hostdata = \ |
@@ -595,32 +592,19 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) | |||
595 | #include <linux/workqueue.h> | 592 | #include <linux/workqueue.h> |
596 | #include <linux/interrupt.h> | 593 | #include <linux/interrupt.h> |
597 | 594 | ||
598 | static volatile int main_running; | 595 | static inline void queue_main(struct NCR5380_hostdata *hostdata) |
599 | static DECLARE_WORK(NCR5380_tqueue, NCR5380_main); | ||
600 | |||
601 | static inline void queue_main(void) | ||
602 | { | 596 | { |
603 | if (!main_running) { | 597 | if (!hostdata->main_running) { |
604 | /* If in interrupt and NCR5380_main() not already running, | 598 | /* If in interrupt and NCR5380_main() not already running, |
605 | queue it on the 'immediate' task queue, to be processed | 599 | queue it on the 'immediate' task queue, to be processed |
606 | immediately after the current interrupt processing has | 600 | immediately after the current interrupt processing has |
607 | finished. */ | 601 | finished. */ |
608 | schedule_work(&NCR5380_tqueue); | 602 | schedule_work(&hostdata->main_task); |
609 | } | 603 | } |
610 | /* else: nothing to do: the running NCR5380_main() will pick up | 604 | /* else: nothing to do: the running NCR5380_main() will pick up |
611 | any newly queued command. */ | 605 | any newly queued command. */ |
612 | } | 606 | } |
613 | 607 | ||
614 | |||
615 | static inline void NCR5380_all_init(void) | ||
616 | { | ||
617 | static int done = 0; | ||
618 | if (!done) { | ||
619 | dprintk(NDEBUG_INIT, "scsi : NCR5380_all_init()\n"); | ||
620 | done = 1; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | /** | 608 | /** |
625 | * NCR58380_info - report driver and host information | 609 | * NCR58380_info - report driver and host information |
626 | * @instance: relevant scsi host instance | 610 | * @instance: relevant scsi host instance |
@@ -703,7 +687,7 @@ static void NCR5380_print_status(struct Scsi_Host *instance) | |||
703 | 687 | ||
704 | local_irq_save(flags); | 688 | local_irq_save(flags); |
705 | printk("NCR5380: coroutine is%s running.\n", | 689 | printk("NCR5380: coroutine is%s running.\n", |
706 | main_running ? "" : "n't"); | 690 | hostdata->main_running ? "" : "n't"); |
707 | if (!hostdata->connected) | 691 | if (!hostdata->connected) |
708 | printk("scsi%d: no currently connected command\n", HOSTNO); | 692 | printk("scsi%d: no currently connected command\n", HOSTNO); |
709 | else | 693 | else |
@@ -746,7 +730,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, | |||
746 | 730 | ||
747 | local_irq_save(flags); | 731 | local_irq_save(flags); |
748 | seq_printf(m, "NCR5380: coroutine is%s running.\n", | 732 | seq_printf(m, "NCR5380: coroutine is%s running.\n", |
749 | main_running ? "" : "n't"); | 733 | hostdata->main_running ? "" : "n't"); |
750 | if (!hostdata->connected) | 734 | if (!hostdata->connected) |
751 | seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); | 735 | seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); |
752 | else | 736 | else |
@@ -783,8 +767,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
783 | int i; | 767 | int i; |
784 | SETUP_HOSTDATA(instance); | 768 | SETUP_HOSTDATA(instance); |
785 | 769 | ||
786 | NCR5380_all_init(); | 770 | hostdata->host = instance; |
787 | |||
788 | hostdata->aborted = 0; | 771 | hostdata->aborted = 0; |
789 | hostdata->id_mask = 1 << instance->this_id; | 772 | hostdata->id_mask = 1 << instance->this_id; |
790 | hostdata->id_higher_mask = 0; | 773 | hostdata->id_higher_mask = 0; |
@@ -805,10 +788,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
805 | hostdata->disconnected_queue = NULL; | 788 | hostdata->disconnected_queue = NULL; |
806 | hostdata->flags = flags; | 789 | hostdata->flags = flags; |
807 | 790 | ||
808 | if (!the_template) { | 791 | INIT_WORK(&hostdata->main_task, NCR5380_main); |
809 | the_template = instance->hostt; | ||
810 | first_instance = instance; | ||
811 | } | ||
812 | 792 | ||
813 | prepare_info(instance); | 793 | prepare_info(instance); |
814 | 794 | ||
@@ -829,7 +809,9 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
829 | 809 | ||
830 | static void NCR5380_exit(struct Scsi_Host *instance) | 810 | static void NCR5380_exit(struct Scsi_Host *instance) |
831 | { | 811 | { |
832 | cancel_work_sync(&NCR5380_tqueue); | 812 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
813 | |||
814 | cancel_work_sync(&hostdata->main_task); | ||
833 | } | 815 | } |
834 | 816 | ||
835 | /** | 817 | /** |
@@ -924,9 +906,9 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, | |||
924 | * unconditionally, because it cannot be already running. | 906 | * unconditionally, because it cannot be already running. |
925 | */ | 907 | */ |
926 | if (in_interrupt() || irqs_disabled()) | 908 | if (in_interrupt() || irqs_disabled()) |
927 | queue_main(); | 909 | queue_main(hostdata); |
928 | else | 910 | else |
929 | NCR5380_main(NULL); | 911 | NCR5380_main(&hostdata->main_task); |
930 | return 0; | 912 | return 0; |
931 | } | 913 | } |
932 | 914 | ||
@@ -955,9 +937,10 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) | |||
955 | 937 | ||
956 | static void NCR5380_main(struct work_struct *work) | 938 | static void NCR5380_main(struct work_struct *work) |
957 | { | 939 | { |
940 | struct NCR5380_hostdata *hostdata = | ||
941 | container_of(work, struct NCR5380_hostdata, main_task); | ||
942 | struct Scsi_Host *instance = hostdata->host; | ||
958 | struct scsi_cmnd *tmp, *prev; | 943 | struct scsi_cmnd *tmp, *prev; |
959 | struct Scsi_Host *instance = first_instance; | ||
960 | struct NCR5380_hostdata *hostdata = HOSTDATA(instance); | ||
961 | int done; | 944 | int done; |
962 | unsigned long flags; | 945 | unsigned long flags; |
963 | 946 | ||
@@ -982,9 +965,9 @@ static void NCR5380_main(struct work_struct *work) | |||
982 | 'main_running' is set here, and queues/executes main via the | 965 | 'main_running' is set here, and queues/executes main via the |
983 | task queue, it doesn't do any harm, just this instance of main | 966 | task queue, it doesn't do any harm, just this instance of main |
984 | won't find any work left to do. */ | 967 | won't find any work left to do. */ |
985 | if (main_running) | 968 | if (hostdata->main_running) |
986 | return; | 969 | return; |
987 | main_running = 1; | 970 | hostdata->main_running = 1; |
988 | 971 | ||
989 | local_save_flags(flags); | 972 | local_save_flags(flags); |
990 | do { | 973 | do { |
@@ -1103,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work) | |||
1103 | /* Better allow ints _after_ 'main_running' has been cleared, else | 1086 | /* Better allow ints _after_ 'main_running' has been cleared, else |
1104 | an interrupt could believe we'll pick up the work it left for | 1087 | an interrupt could believe we'll pick up the work it left for |
1105 | us, but we won't see it anymore here... */ | 1088 | us, but we won't see it anymore here... */ |
1106 | main_running = 0; | 1089 | hostdata->main_running = 0; |
1107 | local_irq_restore(flags); | 1090 | local_irq_restore(flags); |
1108 | } | 1091 | } |
1109 | 1092 | ||
@@ -1215,7 +1198,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1215 | 1198 | ||
1216 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) | 1199 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) |
1217 | { | 1200 | { |
1218 | struct Scsi_Host *instance = first_instance; | 1201 | struct Scsi_Host *instance = dev_id; |
1219 | int done = 1, handled = 0; | 1202 | int done = 1, handled = 0; |
1220 | unsigned char basr; | 1203 | unsigned char basr; |
1221 | 1204 | ||
@@ -1287,7 +1270,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id) | |||
1287 | if (!done) { | 1270 | if (!done) { |
1288 | dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO); | 1271 | dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO); |
1289 | /* Put a call to NCR5380_main() on the queue... */ | 1272 | /* Put a call to NCR5380_main() on the queue... */ |
1290 | queue_main(); | 1273 | queue_main(shost_priv(instance)); |
1291 | } | 1274 | } |
1292 | return IRQ_RETVAL(handled); | 1275 | return IRQ_RETVAL(handled); |
1293 | } | 1276 | } |
@@ -1767,7 +1750,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1767 | * Returns : 0 on success, -1 on failure. | 1750 | * Returns : 0 on success, -1 on failure. |
1768 | */ | 1751 | */ |
1769 | 1752 | ||
1770 | static int do_abort(struct Scsi_Host *host) | 1753 | static int do_abort(struct Scsi_Host *instance) |
1771 | { | 1754 | { |
1772 | unsigned char tmp, *msgptr, phase; | 1755 | unsigned char tmp, *msgptr, phase; |
1773 | int len; | 1756 | int len; |
@@ -1802,7 +1785,7 @@ static int do_abort(struct Scsi_Host *host) | |||
1802 | msgptr = &tmp; | 1785 | msgptr = &tmp; |
1803 | len = 1; | 1786 | len = 1; |
1804 | phase = PHASE_MSGOUT; | 1787 | phase = PHASE_MSGOUT; |
1805 | NCR5380_transfer_pio(host, &phase, &len, &msgptr); | 1788 | NCR5380_transfer_pio(instance, &phase, &len, &msgptr); |
1806 | 1789 | ||
1807 | /* | 1790 | /* |
1808 | * If we got here, and the command completed successfully, | 1791 | * If we got here, and the command completed successfully, |