summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-07-19 22:46:33 +0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 20:52:30 +0400
commit058a0f9f31283d5eb9d8686d3b4f69e55d1589f1 (patch)
treedf9b1bc7ff388df0f7cad99226a852e46ca3e5c8
parentadfbc1ff342ece2e482254bcc5381fadfffbbb89 (diff)
downloadlinux-058a0f9f31283d5eb9d8686d3b4f69e55d1589f1.tar.xz
cciss: forbid hard reset of 640x boards
cciss: forbid hard reset of 640x boards The 6402/6404 are two PCI devices -- two Smart Array controllers -- that fit into one slot. It is possible to reset them independently, however, they share a battery backed cache module. One of the pair controls the cache and the 2nd one access the cache through the first one. If you reset the one controlling the cache, the other one will not be a happy camper. So we just forbid resetting this conjoined mess. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--drivers/block/cciss.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 6d4c4f227d55..2abe6df9445e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -4495,6 +4495,7 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
int rc, i;
CfgTable_struct __iomem *cfgtable;
bool use_doorbell;
+ u32 board_id;
/* For controllers as old a the p600, this is very nearly
* the same thing as
@@ -4517,6 +4518,19 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
* 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.
+ */
+ cciss_lookup_board_id(pdev, &board_id);
+ if (board_id == 0x409C0E11 || board_id == 0x409D0E11) {
+ dev_warn(&pdev->dev, "Cannot reset Smart Array 640x "
+ "due to shared cache module.");
+ return -ENODEV;
+ }
+
for (i = 0; i < 32; i++)
pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
@@ -4600,7 +4614,8 @@ static __devinit int cciss_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. */