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:40 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:00 -0400
commit1df8552abf36519ca8b9e2a8d1e204bac2076d51 (patch)
tree6bf8e7f5dad9917e07edf126e24a40f101f6a496 /drivers/scsi/hpsa.c
parent4c2a8c40d877effc25774f00406a4a7df1967102 (diff)
[SCSI] hpsa: Fix hard reset code.
Smart Array controllers newer than the P600 do not honor the PCI power state method of resetting the controllers. Instead, in these cases we can get them to reset via the "doorbell" register. This escaped notice until we began using "performant" mode because the fact that the controllers did not reset did not normally impede subsequent operation, and so things generally appeared to "work". Once the performant mode code was added, if the controller does not reset, it remains in performant mode. The code immediately after the reset presumes the controller is in "simple" mode (which previously, it had remained in simple mode the whole time). If the controller remains in performant mode any code which presumes it is in simple mode will not work. So the reset needs to be fixed. Unfortunately there are some controllers which cannot be reset by either method. (eg. p800). We detect these cases by noticing that the controller seems to remain in performant mode even after a reset has been attempted. In those case, we proceed anyway, as if the reset has happened (and skip the step of waiting for the controller to become ready -- which is expecting it to be in "simple" mode.) To sum up, we try to do a better job of resetting the controller if "reset_devices" is set, and if it doesn't work, we print a message and try to continue anyway. 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.c174
1 files changed, 133 insertions, 41 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b2f478596dfb..f57d533f7475 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -174,6 +174,11 @@ static void calc_bucket_map(int *bucket, int num_buckets,
174 int nsgs, int *bucket_map); 174 int nsgs, int *bucket_map);
175static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h); 175static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
176static inline u32 next_command(struct ctlr_info *h); 176static inline u32 next_command(struct ctlr_info *h);
177static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev,
178 void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index,
179 u64 *cfg_offset);
180static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev,
181 unsigned long *memory_bar);
177 182
178static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); 183static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
179static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); 184static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
@@ -3078,17 +3083,75 @@ static __devinit int hpsa_reset_msi(struct pci_dev *pdev)
3078 return 0; 3083 return 0;
3079} 3084}
3080 3085
3086static int hpsa_controller_hard_reset(struct pci_dev *pdev,
3087 void * __iomem vaddr, bool use_doorbell)
3088{
3089 u16 pmcsr;
3090 int pos;
3091
3092 if (use_doorbell) {
3093 /* For everything after the P600, the PCI power state method
3094 * of resetting the controller doesn't work, so we have this
3095 * other way using the doorbell register.
3096 */
3097 dev_info(&pdev->dev, "using doorbell to reset controller\n");
3098 writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
3099 msleep(1000);
3100 } else { /* Try to do it the PCI power state way */
3101
3102 /* Quoting from the Open CISS Specification: "The Power
3103 * Management Control/Status Register (CSR) controls the power
3104 * state of the device. The normal operating state is D0,
3105 * CSR=00h. The software off state is D3, CSR=03h. To reset
3106 * the controller, place the interface device in D3 then to D0,
3107 * this causes a secondary PCI reset which will reset the
3108 * controller." */
3109
3110 pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
3111 if (pos == 0) {
3112 dev_err(&pdev->dev,
3113 "hpsa_reset_controller: "
3114 "PCI PM not supported\n");
3115 return -ENODEV;
3116 }
3117 dev_info(&pdev->dev, "using PCI PM to reset controller\n");
3118 /* enter the D3hot power management state */
3119 pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
3120 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
3121 pmcsr |= PCI_D3hot;
3122 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3123
3124 msleep(500);
3125
3126 /* enter the D0 power management state */
3127 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
3128 pmcsr |= PCI_D0;
3129 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3130
3131 msleep(500);
3132 }
3133 return 0;
3134}
3135
3081/* This does a hard reset of the controller using PCI power management 3136/* This does a hard reset of the controller using PCI power management
3082 * states. 3137 * states or the using the doorbell register.
3083 */ 3138 */
3084static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) 3139static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3085{ 3140{
3086 u16 pmcsr, saved_config_space[32]; 3141 u16 saved_config_space[32];
3087 int i, pos; 3142 u64 cfg_offset;
3143 u32 cfg_base_addr;
3144 u64 cfg_base_addr_index;
3145 void __iomem *vaddr;
3146 unsigned long paddr;
3147 u32 misc_fw_support, active_transport;
3148 int rc, i;
3149 struct CfgTable __iomem *cfgtable;
3150 bool use_doorbell;
3088 3151
3089 dev_info(&pdev->dev, "using PCI PM to reset controller\n");
3090 3152
3091 /* This is very nearly the same thing as 3153 /* For controllers as old as the P600, this is very nearly
3154 * the same thing as
3092 * 3155 *
3093 * pci_save_state(pci_dev); 3156 * pci_save_state(pci_dev);
3094 * pci_set_power_state(pci_dev, PCI_D3hot); 3157 * pci_set_power_state(pci_dev, PCI_D3hot);
@@ -3102,41 +3165,42 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev)
3102 * violate the ordering requirements for restoring the 3165 * violate the ordering requirements for restoring the
3103 * configuration space from the CCISS document (see the 3166 * configuration space from the CCISS document (see the
3104 * comment below). So we roll our own .... 3167 * comment below). So we roll our own ....
3168 *
3169 * For controllers newer than the P600, the pci power state
3170 * method of resetting doesn't work so we have another way
3171 * using the doorbell register.
3105 */ 3172 */
3106
3107 for (i = 0; i < 32; i++) 3173 for (i = 0; i < 32; i++)
3108 pci_read_config_word(pdev, 2*i, &saved_config_space[i]); 3174 pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
3109 3175
3110 pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
3111 if (pos == 0) {
3112 dev_err(&pdev->dev,
3113 "hpsa_reset_controller: PCI PM not supported\n");
3114 return -ENODEV;
3115 }
3116
3117 /* Quoting from the Open CISS Specification: "The Power
3118 * Management Control/Status Register (CSR) controls the power
3119 * state of the device. The normal operating state is D0,
3120 * CSR=00h. The software off state is D3, CSR=03h. To reset
3121 * the controller, place the interface device in D3 then to
3122 * D0, this causes a secondary PCI reset which will reset the
3123 * controller."
3124 */
3125 3176
3126 /* enter the D3hot power management state */ 3177 /* find the first memory BAR, so we can find the cfg table */
3127 pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); 3178 rc = hpsa_pci_find_memory_BAR(pdev, &paddr);
3128 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 3179 if (rc)
3129 pmcsr |= PCI_D3hot; 3180 return rc;
3130 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); 3181 vaddr = remap_pci_mem(paddr, 0x250);
3182 if (!vaddr)
3183 return -ENOMEM;
3131 3184
3132 msleep(500); 3185 /* find cfgtable in order to check if reset via doorbell is supported */
3186 rc = hpsa_find_cfg_addrs(pdev, vaddr, &cfg_base_addr,
3187 &cfg_base_addr_index, &cfg_offset);
3188 if (rc)
3189 goto unmap_vaddr;
3190 cfgtable = remap_pci_mem(pci_resource_start(pdev,
3191 cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable));
3192 if (!cfgtable) {
3193 rc = -ENOMEM;
3194 goto unmap_vaddr;
3195 }
3133 3196
3134 /* enter the D0 power management state */ 3197 /* If reset via doorbell register is supported, use that. */
3135 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 3198 misc_fw_support = readl(&cfgtable->misc_fw_support);
3136 pmcsr |= PCI_D0; 3199 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
3137 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3138 3200
3139 msleep(500); 3201 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
3202 if (rc)
3203 goto unmap_cfgtable;
3140 3204
3141 /* Restore the PCI configuration space. The Open CISS 3205 /* Restore the PCI configuration space. The Open CISS
3142 * Specification says, "Restore the PCI Configuration 3206 * Specification says, "Restore the PCI Configuration
@@ -3153,7 +3217,29 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev)
3153 wmb(); 3217 wmb();
3154 pci_write_config_word(pdev, 4, saved_config_space[2]); 3218 pci_write_config_word(pdev, 4, saved_config_space[2]);
3155 3219
3156 return 0; 3220 /* Some devices (notably the HP Smart Array 5i Controller)
3221 need a little pause here */
3222 msleep(HPSA_POST_RESET_PAUSE_MSECS);
3223
3224 /* Controller should be in simple mode at this point. If it's not,
3225 * It means we're on one of those controllers which doesn't support
3226 * the doorbell reset method and on which the PCI power management reset
3227 * method doesn't work (P800, for example.)
3228 * In those cases, pretend the reset worked and hope for the best.
3229 */
3230 active_transport = readl(&cfgtable->TransportActive);
3231 if (active_transport & PERFORMANT_MODE) {
3232 dev_warn(&pdev->dev, "Unable to successfully reset controller,"
3233 " proceeding anyway.\n");
3234 rc = -ENOTSUPP;
3235 }
3236
3237unmap_cfgtable:
3238 iounmap(cfgtable);
3239
3240unmap_vaddr:
3241 iounmap(vaddr);
3242 return rc;
3157} 3243}
3158 3244
3159/* 3245/*
@@ -3573,18 +3659,24 @@ static void __devinit hpsa_hba_inquiry(struct ctlr_info *h)
3573 3659
3574static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev) 3660static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
3575{ 3661{
3576 int i; 3662 int rc, i;
3577 3663
3578 if (!reset_devices) 3664 if (!reset_devices)
3579 return 0; 3665 return 0;
3580 3666
3581 /* Reset the controller with a PCI power-cycle */ 3667 /* Reset the controller with a PCI power-cycle or via doorbell */
3582 if (hpsa_hard_reset_controller(pdev) || hpsa_reset_msi(pdev)) 3668 rc = hpsa_kdump_hard_reset_controller(pdev);
3583 return -ENODEV;
3584 3669
3585 /* Some devices (notably the HP Smart Array 5i Controller) 3670 /* -ENOTSUPP here means we cannot reset the controller
3586 need a little pause here */ 3671 * but it's already (and still) up and running in
3587 msleep(HPSA_POST_RESET_PAUSE_MSECS); 3672 * "performant mode".
3673 */
3674 if (rc == -ENOTSUPP)
3675 return 0; /* just try to do the kdump anyhow. */
3676 if (rc)
3677 return -ENODEV;
3678 if (hpsa_reset_msi(pdev))
3679 return -ENODEV;
3588 3680
3589 /* Now try to get the controller to respond to a no-op */ 3681 /* Now try to get the controller to respond to a no-op */
3590 for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { 3682 for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {