aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2016-12-05 01:07:20 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-12-08 16:57:21 -0500
commit906e4a3c7e03701008d343daec8952d6cf49f82b (patch)
tree1971ad8a833d53b0f2dfbfb716be3149a63840be
parent89fa9b5cb08c9d8ad709415b88395be463eceeee (diff)
scsi: g_NCR5380: Use probe_irq_*() for IRQ probing
Use standard probe_irq_on() and probe_irq_off() functions instead of own implementation. This prevents warning messages like this in the kernel log: genirq: Flags mismatch irq 1. 00000000 (NCR-probe) vs. 00000080 (i8042) Move the IRQ trigger code from NCR5380 to g_NCR5380 where it is used. Also clear interrupt flag before and after the probe. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Tested-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/NCR5380.c77
-rw-r--r--drivers/scsi/NCR5380.h11
-rw-r--r--drivers/scsi/g_NCR5380.c52
-rw-r--r--drivers/scsi/g_NCR5380.h2
4 files changed, 54 insertions, 88 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d849ffa378b1..4f5ca794bb71 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -97,9 +97,6 @@
97 * and macros and include this file in your driver. 97 * and macros and include this file in your driver.
98 * 98 *
99 * These macros control options : 99 * These macros control options :
100 * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be
101 * defined.
102 *
103 * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically 100 * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
104 * for commands that return with a CHECK CONDITION status. 101 * for commands that return with a CHECK CONDITION status.
105 * 102 *
@@ -127,9 +124,7 @@
127 * NCR5380_dma_residual - residual byte count 124 * NCR5380_dma_residual - residual byte count
128 * 125 *
129 * The generic driver is initialized by calling NCR5380_init(instance), 126 * The generic driver is initialized by calling NCR5380_init(instance),
130 * after setting the appropriate host specific fields and ID. If the 127 * after setting the appropriate host specific fields and ID.
131 * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
132 * possible) function may be used.
133 */ 128 */
134 129
135#ifndef NCR5380_io_delay 130#ifndef NCR5380_io_delay
@@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
351} 346}
352#endif 347#endif
353 348
354
355static int probe_irq;
356
357/**
358 * probe_intr - helper for IRQ autoprobe
359 * @irq: interrupt number
360 * @dev_id: unused
361 * @regs: unused
362 *
363 * Set a flag to indicate the IRQ in question was received. This is
364 * used by the IRQ probe code.
365 */
366
367static irqreturn_t probe_intr(int irq, void *dev_id)
368{
369 probe_irq = irq;
370 return IRQ_HANDLED;
371}
372
373/**
374 * NCR5380_probe_irq - find the IRQ of an NCR5380
375 * @instance: NCR5380 controller
376 * @possible: bitmask of ISA IRQ lines
377 *
378 * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
379 * and then looking to see what interrupt actually turned up.
380 */
381
382static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
383 int possible)
384{
385 struct NCR5380_hostdata *hostdata = shost_priv(instance);
386 unsigned long timeout;
387 int trying_irqs, i, mask;
388
389 for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1)
390 if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0))
391 trying_irqs |= mask;
392
393 timeout = jiffies + msecs_to_jiffies(250);
394 probe_irq = NO_IRQ;
395
396 /*
397 * A interrupt is triggered whenever BSY = false, SEL = true
398 * and a bit set in the SELECT_ENABLE_REG is asserted on the
399 * SCSI bus.
400 *
401 * Note that the bus is only driven when the phase control signals
402 * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
403 * to zero.
404 */
405
406 NCR5380_write(TARGET_COMMAND_REG, 0);
407 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
408 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
409 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
410
411 while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
412 schedule_timeout_uninterruptible(1);
413
414 NCR5380_write(SELECT_ENABLE_REG, 0);
415 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
416
417 for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
418 if (trying_irqs & mask)
419 free_irq(i, NULL);
420
421 return probe_irq;
422}
423
424/** 349/**
425 * NCR58380_info - report driver and host information 350 * NCR58380_info - report driver and host information
426 * @instance: relevant scsi host instance 351 * @instance: relevant scsi host instance
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 3c6ce5434449..51a3567a6fb2 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -199,16 +199,6 @@
199 199
200#define PHASE_SR_TO_TCR(phase) ((phase) >> 2) 200#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
201 201
202/*
203 * These are "special" values for the irq and dma_channel fields of the
204 * Scsi_Host structure
205 */
206
207#define DMA_NONE 255
208#define IRQ_AUTO 254
209#define DMA_AUTO 254
210#define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */
211
212#ifndef NO_IRQ 202#ifndef NO_IRQ
213#define NO_IRQ 0 203#define NO_IRQ 0
214#endif 204#endif
@@ -290,7 +280,6 @@ static void NCR5380_print(struct Scsi_Host *instance);
290#define NCR5380_dprint_phase(flg, arg) do {} while (0) 280#define NCR5380_dprint_phase(flg, arg) do {} while (0)
291#endif 281#endif
292 282
293static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
294static int NCR5380_init(struct Scsi_Host *instance, int flags); 283static int NCR5380_init(struct Scsi_Host *instance, int flags);
295static int NCR5380_maybe_reset_bus(struct Scsi_Host *); 284static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
296static void NCR5380_exit(struct Scsi_Host *instance); 285static void NCR5380_exit(struct Scsi_Host *instance);
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 76e37455480e..6d245a7b9363 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -67,6 +67,56 @@ MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC31
67MODULE_ALIAS("g_NCR5380_mmio"); 67MODULE_ALIAS("g_NCR5380_mmio");
68MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
69 69
70static void g_NCR5380_trigger_irq(struct Scsi_Host *instance)
71{
72 struct NCR5380_hostdata *hostdata = shost_priv(instance);
73
74 /*
75 * An interrupt is triggered whenever BSY = false, SEL = true
76 * and a bit set in the SELECT_ENABLE_REG is asserted on the
77 * SCSI bus.
78 *
79 * Note that the bus is only driven when the phase control signals
80 * (I/O, C/D, and MSG) match those in the TCR.
81 */
82 NCR5380_write(TARGET_COMMAND_REG,
83 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
84 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
85 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
86 NCR5380_write(INITIATOR_COMMAND_REG,
87 ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
88
89 msleep(1);
90
91 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
92 NCR5380_write(SELECT_ENABLE_REG, 0);
93 NCR5380_write(TARGET_COMMAND_REG, 0);
94}
95
96/**
97 * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent
98 * @instance: SCSI host instance
99 *
100 * Autoprobe for the IRQ line used by the card by triggering an IRQ
101 * and then looking to see what interrupt actually turned up.
102 */
103
104static int g_NCR5380_probe_irq(struct Scsi_Host *instance)
105{
106 struct NCR5380_hostdata *hostdata = shost_priv(instance);
107 int irq_mask, irq;
108
109 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
110 irq_mask = probe_irq_on();
111 g_NCR5380_trigger_irq(instance);
112 irq = probe_irq_off(irq_mask);
113 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
114
115 if (irq <= 0)
116 return NO_IRQ;
117 return irq;
118}
119
70/* 120/*
71 * Configure I/O address of 53C400A or DTC436 by writing magic numbers 121 * Configure I/O address of 53C400A or DTC436 by writing magic numbers
72 * to ports 0x779 and 0x379. 122 * to ports 0x779 and 0x379.
@@ -272,7 +322,7 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
272 if (irq != IRQ_AUTO) 322 if (irq != IRQ_AUTO)
273 instance->irq = irq; 323 instance->irq = irq;
274 else 324 else
275 instance->irq = NCR5380_probe_irq(instance, 0xffff); 325 instance->irq = g_NCR5380_probe_irq(instance);
276 326
277 /* Compatibility with documented NCR5380 kernel parameters */ 327 /* Compatibility with documented NCR5380 kernel parameters */
278 if (instance->irq == 255) 328 if (instance->irq == 255)
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index 3ce5b65ccb00..81b22d989648 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -51,4 +51,6 @@
51#define BOARD_DTC3181E 3 51#define BOARD_DTC3181E 3
52#define BOARD_HP_C2502 4 52#define BOARD_HP_C2502 4
53 53
54#define IRQ_AUTO 254
55
54#endif /* GENERIC_NCR5380_H */ 56#endif /* GENERIC_NCR5380_H */