Skip to content

Commit

Permalink
[SCSI] hpsa: separate intx and msi/msix interrupt handlers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stephen M. Cameron authored and James Bottomley committed Jul 27, 2010
1 parent 1886765 commit 10f6601
Showing 1 changed file with 32 additions and 7 deletions.
39 changes: 32 additions & 7 deletions drivers/scsi/hpsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ static struct board_type products[] = {

static int number_of_controllers;

static irqreturn_t do_hpsa_intr(int irq, void *dev_id);
static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
static void start_io(struct ctlr_info *h);

Expand Down Expand Up @@ -2858,9 +2859,8 @@ static inline bool interrupt_pending(struct ctlr_info *h)

static inline long interrupt_not_for_us(struct ctlr_info *h)
{
return !(h->msi_vector || h->msix_vector) &&
((h->access.intr_pending(h) == 0) ||
(h->interrupts_enabled == 0));
return (h->access.intr_pending(h) == 0) ||
(h->interrupts_enabled == 0);
}

static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
Expand Down Expand Up @@ -2934,14 +2934,34 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
return next_command(h);
}

static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
{
struct ctlr_info *h = dev_id;
unsigned long flags;
u32 raw_tag;

if (interrupt_not_for_us(h))
return IRQ_NONE;
spin_lock_irqsave(&h->lock, flags);
while (interrupt_pending(h)) {
raw_tag = get_next_completion(h);
while (raw_tag != FIFO_EMPTY) {
if (hpsa_tag_contains_index(raw_tag))
raw_tag = process_indexed_cmd(h, raw_tag);
else
raw_tag = process_nonindexed_cmd(h, raw_tag);
}
}
spin_unlock_irqrestore(&h->lock, flags);
return IRQ_HANDLED;
}

static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
{
struct ctlr_info *h = dev_id;
unsigned long flags;
u32 raw_tag;

spin_lock_irqsave(&h->lock, flags);
raw_tag = get_next_completion(h);
while (raw_tag != FIFO_EMPTY) {
Expand Down Expand Up @@ -3754,8 +3774,13 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,

/* make sure the board interrupts are off */
h->access.set_intr_mask(h, HPSA_INTR_OFF);
rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr,
IRQF_DISABLED, h->devname, h);

if (h->msix_vector || h->msi_vector)
rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_msi,
IRQF_DISABLED, h->devname, h);
else
rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_intx,
IRQF_DISABLED, h->devname, h);
if (rc) {
dev_err(&pdev->dev, "unable to get irq %d for %s\n",
h->intr[PERF_MODE_INT], h->devname);
Expand Down

0 comments on commit 10f6601

Please sign in to comment.