aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-06-16 14:51:50 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:03 -0400
commit10f66018088fd0c9fe81b1e328e3264c7b10caa5 (patch)
treec63cd4610b2c7fd51ab57d8528c87a796e21b4ce /drivers
parent1886765906686cdb08c35afae20e4ad8f82367f5 (diff)
[SCSI] hpsa: separate intx and msi/msix interrupt handlers
There are things which need to be done in the intx interrupt handler which do not need to be done in the msi/msix interrupt handler, like checking that the interrupt is actually for us, and checking that the interrupt pending bit on the hardware is set (which we weren't previously doing at all, which means old controllers wouldn't work), so it makes sense to separate these into two functions. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/hpsa.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index d903cc690eb9..f8b614b591e4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -126,7 +126,8 @@ static struct board_type products[] = {
126 126
127static int number_of_controllers; 127static int number_of_controllers;
128 128
129static irqreturn_t do_hpsa_intr(int irq, void *dev_id); 129static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
130static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
130static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); 131static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
131static void start_io(struct ctlr_info *h); 132static void start_io(struct ctlr_info *h);
132 133
@@ -2858,9 +2859,8 @@ static inline bool interrupt_pending(struct ctlr_info *h)
2858 2859
2859static inline long interrupt_not_for_us(struct ctlr_info *h) 2860static inline long interrupt_not_for_us(struct ctlr_info *h)
2860{ 2861{
2861 return !(h->msi_vector || h->msix_vector) && 2862 return (h->access.intr_pending(h) == 0) ||
2862 ((h->access.intr_pending(h) == 0) || 2863 (h->interrupts_enabled == 0);
2863 (h->interrupts_enabled == 0));
2864} 2864}
2865 2865
2866static inline int bad_tag(struct ctlr_info *h, u32 tag_index, 2866static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
@@ -2934,7 +2934,7 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
2934 return next_command(h); 2934 return next_command(h);
2935} 2935}
2936 2936
2937static irqreturn_t do_hpsa_intr(int irq, void *dev_id) 2937static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
2938{ 2938{
2939 struct ctlr_info *h = dev_id; 2939 struct ctlr_info *h = dev_id;
2940 unsigned long flags; 2940 unsigned long flags;
@@ -2943,6 +2943,26 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
2943 if (interrupt_not_for_us(h)) 2943 if (interrupt_not_for_us(h))
2944 return IRQ_NONE; 2944 return IRQ_NONE;
2945 spin_lock_irqsave(&h->lock, flags); 2945 spin_lock_irqsave(&h->lock, flags);
2946 while (interrupt_pending(h)) {
2947 raw_tag = get_next_completion(h);
2948 while (raw_tag != FIFO_EMPTY) {
2949 if (hpsa_tag_contains_index(raw_tag))
2950 raw_tag = process_indexed_cmd(h, raw_tag);
2951 else
2952 raw_tag = process_nonindexed_cmd(h, raw_tag);
2953 }
2954 }
2955 spin_unlock_irqrestore(&h->lock, flags);
2956 return IRQ_HANDLED;
2957}
2958
2959static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
2960{
2961 struct ctlr_info *h = dev_id;
2962 unsigned long flags;
2963 u32 raw_tag;
2964
2965 spin_lock_irqsave(&h->lock, flags);
2946 raw_tag = get_next_completion(h); 2966 raw_tag = get_next_completion(h);
2947 while (raw_tag != FIFO_EMPTY) { 2967 while (raw_tag != FIFO_EMPTY) {
2948 if (hpsa_tag_contains_index(raw_tag)) 2968 if (hpsa_tag_contains_index(raw_tag))
@@ -3754,8 +3774,13 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3754 3774
3755 /* make sure the board interrupts are off */ 3775 /* make sure the board interrupts are off */
3756 h->access.set_intr_mask(h, HPSA_INTR_OFF); 3776 h->access.set_intr_mask(h, HPSA_INTR_OFF);
3757 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr, 3777
3758 IRQF_DISABLED, h->devname, h); 3778 if (h->msix_vector || h->msi_vector)
3779 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_msi,
3780 IRQF_DISABLED, h->devname, h);
3781 else
3782 rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_intx,
3783 IRQF_DISABLED, h->devname, h);
3759 if (rc) { 3784 if (rc) {
3760 dev_err(&pdev->dev, "unable to get irq %d for %s\n", 3785 dev_err(&pdev->dev, "unable to get irq %d for %s\n",
3761 h->intr[PERF_MODE_INT], h->devname); 3786 h->intr[PERF_MODE_INT], h->devname);