diff options
-rw-r--r-- | drivers/scsi/hpsa.c | 39 |
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 | ||
127 | static int number_of_controllers; | 127 | static int number_of_controllers; |
128 | 128 | ||
129 | static irqreturn_t do_hpsa_intr(int irq, void *dev_id); | 129 | static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id); |
130 | static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id); | ||
130 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); | 131 | static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); |
131 | static void start_io(struct ctlr_info *h); | 132 | static void start_io(struct ctlr_info *h); |
132 | 133 | ||
@@ -2858,9 +2859,8 @@ static inline bool interrupt_pending(struct ctlr_info *h) | |||
2858 | 2859 | ||
2859 | static inline long interrupt_not_for_us(struct ctlr_info *h) | 2860 | static 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 | ||
2866 | static inline int bad_tag(struct ctlr_info *h, u32 tag_index, | 2866 | static 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 | ||
2937 | static irqreturn_t do_hpsa_intr(int irq, void *dev_id) | 2937 | static 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 | |||
2959 | static 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); |