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);
u64 *cfg_offset);
static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev,
unsigned long *memory_bar);
+static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
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,
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;
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) {
int rc, i;
struct CfgTable __iomem *cfgtable;
bool use_doorbell;
-
+ u32 board_id;
/* For controllers as old as the P600, this is very nearly
* the same thing as
* method of resetting doesn't work so we have another way
* using the doorbell register.
*/
+
+ /* Exclude 640x boards. These are two pci devices in one slot
+ * which share a battery backed cache module. One controls the
+ * cache, the other accesses the cache through the one that controls
+ * it. If we reset the one controlling the cache, the other will
+ * likely not be happy. Just forbid resetting this conjoined mess.
+ * The 640x isn't really supported by hpsa anyway.
+ */
+ hpsa_lookup_board_id(pdev, &board_id);
+ if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
+ return -ENOTSUPP;
+
for (i = 0; i < 32; i++)
pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
return 0;
}
+static void __devinit hpsa_get_max_perf_mode_cmds(struct ctlr_info *h)
+{
+ h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+ if (h->max_commands < 16) {
+ dev_warn(&h->pdev->dev, "Controller reports "
+ "max supported commands of %d, an obvious lie. "
+ "Using 16. Ensure that firmware is up to date.\n",
+ h->max_commands);
+ h->max_commands = 16;
+ }
+}
+
/* Interrogate the hardware for some limits:
* max commands, max SG elements without chaining, and with chaining,
* SG chain block size, etc.
*/
static void __devinit hpsa_find_board_params(struct ctlr_info *h)
{
- h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+ hpsa_get_max_perf_mode_cmds(h);
h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
/*
/* -ENOTSUPP here means we cannot reset the controller
* but it's already (and still) up and running in
- * "performant mode".
+ * "performant mode". Or, it might be 640x, which can't reset
+ * due to concerns about shared bbwc between 6402/6404 pair.
*/
if (rc == -ENOTSUPP)
return 0; /* just try to do the kdump anyhow. */
/* 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);
if (!(trans_support & PERFORMANT_MODE))
return;
- h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+ hpsa_get_max_perf_mode_cmds(h);
h->max_sg_entries = 32;
/* Performant mode ring buffer and supporting data structures */
h->reply_pool_size = h->max_commands * sizeof(u64);