aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-06-16 14:51:45 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:02 -0400
commit1886765906686cdb08c35afae20e4ad8f82367f5 (patch)
tree2b9a4826282c396233676bf90e9d8ea65929b094 /drivers/scsi/hpsa.c
parent1df8552abf36519ca8b9e2a8d1e204bac2076d51 (diff)
[SCSI] hpsa: 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: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index f57d533f7475..d903cc690eb9 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -179,6 +179,7 @@ static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev,
179 u64 *cfg_offset); 179 u64 *cfg_offset);
180static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, 180static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev,
181 unsigned long *memory_bar); 181 unsigned long *memory_bar);
182static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
182 183
183static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); 184static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
184static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); 185static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
@@ -3148,7 +3149,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3148 int rc, i; 3149 int rc, i;
3149 struct CfgTable __iomem *cfgtable; 3150 struct CfgTable __iomem *cfgtable;
3150 bool use_doorbell; 3151 bool use_doorbell;
3151 3152 u32 board_id;
3152 3153
3153 /* For controllers as old as the P600, this is very nearly 3154 /* For controllers as old as the P600, this is very nearly
3154 * the same thing as 3155 * the same thing as
@@ -3170,6 +3171,18 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3170 * method of resetting doesn't work so we have another way 3171 * method of resetting doesn't work so we have another way
3171 * using the doorbell register. 3172 * using the doorbell register.
3172 */ 3173 */
3174
3175 /* Exclude 640x boards. These are two pci devices in one slot
3176 * which share a battery backed cache module. One controls the
3177 * cache, the other accesses the cache through the one that controls
3178 * it. If we reset the one controlling the cache, the other will
3179 * likely not be happy. Just forbid resetting this conjoined mess.
3180 * The 640x isn't really supported by hpsa anyway.
3181 */
3182 hpsa_lookup_board_id(pdev, &board_id);
3183 if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
3184 return -ENOTSUPP;
3185
3173 for (i = 0; i < 32; i++) 3186 for (i = 0; i < 32; i++)
3174 pci_read_config_word(pdev, 2*i, &saved_config_space[i]); 3187 pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
3175 3188
@@ -3669,7 +3682,8 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
3669 3682
3670 /* -ENOTSUPP here means we cannot reset the controller 3683 /* -ENOTSUPP here means we cannot reset the controller
3671 * but it's already (and still) up and running in 3684 * but it's already (and still) up and running in
3672 * "performant mode". 3685 * "performant mode". Or, it might be 640x, which can't reset
3686 * due to concerns about shared bbwc between 6402/6404 pair.
3673 */ 3687 */
3674 if (rc == -ENOTSUPP) 3688 if (rc == -ENOTSUPP)
3675 return 0; /* just try to do the kdump anyhow. */ 3689 return 0; /* just try to do the kdump anyhow. */