diff options
author | Joe Carnuccio <joe.carnuccio@qlogic.com> | 2012-11-21 02:40:37 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-11-30 10:11:16 -0500 |
commit | 4ea2c9c7b32f808cb2743f2e349a614aa3a46088 (patch) | |
tree | 8ecb3f529a11815db5c783c64df3f521fe0c9567 /drivers/scsi/qla2xxx | |
parent | 807fb6d8afad1552c6981256a83bc2c0ce4e2125 (diff) |
[SCSI] qla2xxx: Add acquiring of risc semaphore before doing ISP reset.
Try to acquire the semaphore; if semaphore is hung then acquire it by force.
The ISP reset clears the semaphore, thereby implicitly releasing it.
Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 21 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 79 |
2 files changed, 100 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 59524aa0ab32..be6d61a89edc 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1092,6 +1092,27 @@ struct device_reg_24xx { | |||
1092 | uint32_t unused_6[2]; /* Gap. */ | 1092 | uint32_t unused_6[2]; /* Gap. */ |
1093 | uint32_t iobase_sdata; | 1093 | uint32_t iobase_sdata; |
1094 | }; | 1094 | }; |
1095 | /* RISC-RISC semaphore register PCI offet */ | ||
1096 | #define RISC_REGISTER_BASE_OFFSET 0x7010 | ||
1097 | #define RISC_REGISTER_WINDOW_OFFET 0x6 | ||
1098 | |||
1099 | /* RISC-RISC semaphore/flag register (risc address 0x7016) */ | ||
1100 | |||
1101 | #define RISC_SEMAPHORE 0x1UL | ||
1102 | #define RISC_SEMAPHORE_WE (RISC_SEMAPHORE << 16) | ||
1103 | #define RISC_SEMAPHORE_CLR (RISC_SEMAPHORE_WE | 0x0UL) | ||
1104 | #define RISC_SEMAPHORE_SET (RISC_SEMAPHORE_WE | RISC_SEMAPHORE) | ||
1105 | |||
1106 | #define RISC_SEMAPHORE_FORCE 0x8000UL | ||
1107 | #define RISC_SEMAPHORE_FORCE_WE (RISC_SEMAPHORE_FORCE << 16) | ||
1108 | #define RISC_SEMAPHORE_FORCE_CLR (RISC_SEMAPHORE_FORCE_WE | 0x0UL) | ||
1109 | #define RISC_SEMAPHORE_FORCE_SET \ | ||
1110 | (RISC_SEMAPHORE_FORCE_WE | RISC_SEMAPHORE_FORCE) | ||
1111 | |||
1112 | /* RISC semaphore timeouts (ms) */ | ||
1113 | #define TIMEOUT_SEMAPHORE 2500 | ||
1114 | #define TIMEOUT_SEMAPHORE_FORCE 2000 | ||
1115 | #define TIMEOUT_TOTAL_ELAPSED 4500 | ||
1095 | 1116 | ||
1096 | /* Trace Control *************************************************************/ | 1117 | /* Trace Control *************************************************************/ |
1097 | 1118 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b7e42a80e165..7464a4731ef6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1095,6 +1095,83 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) | |||
1095 | ha->isp_ops->enable_intrs(ha); | 1095 | ha->isp_ops->enable_intrs(ha); |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | static void | ||
1099 | qla25xx_read_risc_sema_reg(scsi_qla_host_t *vha, uint32_t *data) | ||
1100 | { | ||
1101 | struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24; | ||
1102 | |||
1103 | WRT_REG_DWORD(®->iobase_addr, RISC_REGISTER_BASE_OFFSET); | ||
1104 | *data = RD_REG_DWORD(®->iobase_window + RISC_REGISTER_WINDOW_OFFET); | ||
1105 | |||
1106 | } | ||
1107 | |||
1108 | static void | ||
1109 | qla25xx_write_risc_sema_reg(scsi_qla_host_t *vha, uint32_t data) | ||
1110 | { | ||
1111 | struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24; | ||
1112 | |||
1113 | WRT_REG_DWORD(®->iobase_addr, RISC_REGISTER_BASE_OFFSET); | ||
1114 | WRT_REG_DWORD(®->iobase_window + RISC_REGISTER_WINDOW_OFFET, data); | ||
1115 | } | ||
1116 | |||
1117 | static void | ||
1118 | qla25xx_manipulate_risc_semaphore(scsi_qla_host_t *vha) | ||
1119 | { | ||
1120 | struct qla_hw_data *ha = vha->hw; | ||
1121 | uint32_t wd32 = 0; | ||
1122 | uint delta_msec = 100; | ||
1123 | uint elapsed_msec = 0; | ||
1124 | uint timeout_msec; | ||
1125 | ulong n; | ||
1126 | |||
1127 | if (!IS_QLA25XX(ha) && !IS_QLA2031(ha)) | ||
1128 | return; | ||
1129 | |||
1130 | attempt: | ||
1131 | timeout_msec = TIMEOUT_SEMAPHORE; | ||
1132 | n = timeout_msec / delta_msec; | ||
1133 | while (n--) { | ||
1134 | qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_SET); | ||
1135 | qla25xx_read_risc_sema_reg(vha, &wd32); | ||
1136 | if (wd32 & RISC_SEMAPHORE) | ||
1137 | break; | ||
1138 | msleep(delta_msec); | ||
1139 | elapsed_msec += delta_msec; | ||
1140 | if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED) | ||
1141 | goto force; | ||
1142 | } | ||
1143 | |||
1144 | if (!(wd32 & RISC_SEMAPHORE)) | ||
1145 | goto force; | ||
1146 | |||
1147 | if (!(wd32 & RISC_SEMAPHORE_FORCE)) | ||
1148 | goto acquired; | ||
1149 | |||
1150 | qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_CLR); | ||
1151 | timeout_msec = TIMEOUT_SEMAPHORE_FORCE; | ||
1152 | n = timeout_msec / delta_msec; | ||
1153 | while (n--) { | ||
1154 | qla25xx_read_risc_sema_reg(vha, &wd32); | ||
1155 | if (!(wd32 & RISC_SEMAPHORE_FORCE)) | ||
1156 | break; | ||
1157 | msleep(delta_msec); | ||
1158 | elapsed_msec += delta_msec; | ||
1159 | if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED) | ||
1160 | goto force; | ||
1161 | } | ||
1162 | |||
1163 | if (wd32 & RISC_SEMAPHORE_FORCE) | ||
1164 | qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_CLR); | ||
1165 | |||
1166 | goto attempt; | ||
1167 | |||
1168 | force: | ||
1169 | qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_SET); | ||
1170 | |||
1171 | acquired: | ||
1172 | return; | ||
1173 | } | ||
1174 | |||
1098 | /** | 1175 | /** |
1099 | * qla24xx_reset_chip() - Reset ISP24xx chip. | 1176 | * qla24xx_reset_chip() - Reset ISP24xx chip. |
1100 | * @ha: HA context | 1177 | * @ha: HA context |
@@ -1113,6 +1190,8 @@ qla24xx_reset_chip(scsi_qla_host_t *vha) | |||
1113 | 1190 | ||
1114 | ha->isp_ops->disable_intrs(ha); | 1191 | ha->isp_ops->disable_intrs(ha); |
1115 | 1192 | ||
1193 | qla25xx_manipulate_risc_semaphore(vha); | ||
1194 | |||
1116 | /* Perform RISC reset. */ | 1195 | /* Perform RISC reset. */ |
1117 | qla24xx_reset_risc(vha); | 1196 | qla24xx_reset_risc(vha); |
1118 | } | 1197 | } |