Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / hpsa.c
index f57d533f74756a8db48b435b8230e21133d570a9..4f5551b5fe53d29a1a0473d3d5d799dabb46e0d5 100644 (file)
@@ -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);
 
@@ -179,6 +180,7 @@ static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev,
        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);
@@ -2857,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,
@@ -2933,7 +2934,7 @@ 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;
@@ -2941,6 +2942,26 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
 
        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) {
@@ -3148,7 +3169,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
        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
@@ -3170,6 +3191,18 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
         * 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]);
 
@@ -3472,13 +3505,25 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h)
        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));
        /*
@@ -3669,7 +3714,8 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
 
        /* -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. */
@@ -3740,8 +3786,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);
@@ -4017,7 +4068,7 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
        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);