aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001/pm8001_sas.c
diff options
context:
space:
mode:
authorMark Salyzyn <mark_salyzyn@xyratex.com>2012-01-17 09:18:57 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:51 -0500
commitd95d00016f8f51dc502cadb263d861bd8c0212bb (patch)
treeaa60333c6d9aa97f3dc1f32f0fce3f3f08baa939 /drivers/scsi/pm8001/pm8001_sas.c
parent5c4fb76af31e9dabcd132a0e69ed3799df1304c3 (diff)
[SCSI] pm8001: Add FUNC_GET_EVENTS
Jack noticed I dropped a patch fragment associated with a flags automatic variable in mpi_set_phys_g3_with_ssc (ooops) and that the pre-emptive locking that piggy-backed this patch was not in-fact necessary because of underlying atomic accesses to the hardware. Here is the updated patch fixing these two issues. The pm8001 driver is missing the FUNC_GET_EVENTS handler in the phy control function. Since the pm8001_bar4_shift function was not designed to be called at runtime, added locking surrounding the adjustment for all accesses. Signed-off-by: Mark Salyzyn <mark_salyzyn@xyratex.com> Acked-by: Jack Wang <jack_wang@usish.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_sas.c')
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 7ae22a67bd31..ab0704e39040 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -166,6 +166,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
166 struct pm8001_hba_info *pm8001_ha = NULL; 166 struct pm8001_hba_info *pm8001_ha = NULL;
167 struct sas_phy_linkrates *rates; 167 struct sas_phy_linkrates *rates;
168 DECLARE_COMPLETION_ONSTACK(completion); 168 DECLARE_COMPLETION_ONSTACK(completion);
169 unsigned long flags;
169 pm8001_ha = sas_phy->ha->lldd_ha; 170 pm8001_ha = sas_phy->ha->lldd_ha;
170 pm8001_ha->phy[phy_id].enable_completion = &completion; 171 pm8001_ha->phy[phy_id].enable_completion = &completion;
171 switch (func) { 172 switch (func) {
@@ -209,8 +210,29 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
209 case PHY_FUNC_DISABLE: 210 case PHY_FUNC_DISABLE:
210 PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id); 211 PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
211 break; 212 break;
213 case PHY_FUNC_GET_EVENTS:
214 spin_lock_irqsave(&pm8001_ha->lock, flags);
215 if (-1 == pm8001_bar4_shift(pm8001_ha,
216 (phy_id < 4) ? 0x30000 : 0x40000)) {
217 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
218 return -EINVAL;
219 }
220 {
221 struct sas_phy *phy = sas_phy->phy;
222 uint32_t *qp = (uint32_t *)(((char *)
223 pm8001_ha->io_mem[2].memvirtaddr)
224 + 0x1034 + (0x4000 * (phy_id & 3)));
225
226 phy->invalid_dword_count = qp[0];
227 phy->running_disparity_error_count = qp[1];
228 phy->loss_of_dword_sync_count = qp[3];
229 phy->phy_reset_problem_count = qp[4];
230 }
231 pm8001_bar4_shift(pm8001_ha, 0);
232 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
233 return 0;
212 default: 234 default:
213 rc = -ENOSYS; 235 rc = -EOPNOTSUPP;
214 } 236 }
215 msleep(300); 237 msleep(300);
216 return rc; 238 return rc;