diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2005-07-06 13:30:36 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-07-14 10:55:08 -0400 |
commit | 6d9b61ed94fd9097f81adfa78d31c4613d9b3ae4 (patch) | |
tree | d7065f9968681cb9052bbe700d6f6bcebe19e2f1 | |
parent | 3d71644cf952fd1157a13173237258422ba3c569 (diff) |
[SCSI] qla2xxx: Add ISP24xx diagnostic routines.
Add ISP24xx diagnostic routines.
Add function and structure definitions for the ISP24xx
diagnostic firmware dump routines.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 949 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 32 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 3 |
3 files changed, 983 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 8e93dd7065a1..80dcc2bac6d6 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -975,7 +975,939 @@ qla_uprintf(char **uiter, char *fmt, ...) | |||
975 | return (len); | 975 | return (len); |
976 | } | 976 | } |
977 | 977 | ||
978 | //FIXME | 978 | |
979 | void | ||
980 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | ||
981 | { | ||
982 | int rval; | ||
983 | uint32_t cnt, timer; | ||
984 | uint32_t risc_address; | ||
985 | uint16_t mb[4]; | ||
986 | |||
987 | uint32_t stat; | ||
988 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
989 | uint32_t __iomem *dmp_reg; | ||
990 | uint32_t *iter_reg; | ||
991 | uint16_t __iomem *mbx_reg; | ||
992 | unsigned long flags; | ||
993 | struct qla24xx_fw_dump *fw; | ||
994 | uint32_t ext_mem_cnt; | ||
995 | |||
996 | risc_address = ext_mem_cnt = 0; | ||
997 | memset(mb, 0, sizeof(mb)); | ||
998 | flags = 0; | ||
999 | |||
1000 | if (!hardware_locked) | ||
1001 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1002 | |||
1003 | if (!ha->fw_dump24) { | ||
1004 | qla_printk(KERN_WARNING, ha, | ||
1005 | "No buffer available for dump!!!\n"); | ||
1006 | goto qla24xx_fw_dump_failed; | ||
1007 | } | ||
1008 | |||
1009 | if (ha->fw_dumped) { | ||
1010 | qla_printk(KERN_WARNING, ha, | ||
1011 | "Firmware has been previously dumped (%p) -- ignoring " | ||
1012 | "request...\n", ha->fw_dump24); | ||
1013 | goto qla24xx_fw_dump_failed; | ||
1014 | } | ||
1015 | fw = (struct qla24xx_fw_dump *) ha->fw_dump24; | ||
1016 | |||
1017 | rval = QLA_SUCCESS; | ||
1018 | fw->hccr = RD_REG_DWORD(®->hccr); | ||
1019 | |||
1020 | /* Pause RISC. */ | ||
1021 | if ((fw->hccr & HCCRX_RISC_PAUSE) == 0) { | ||
1022 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | | ||
1023 | HCCRX_CLR_HOST_INT); | ||
1024 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
1025 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | ||
1026 | for (cnt = 30000; | ||
1027 | (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && | ||
1028 | rval == QLA_SUCCESS; cnt--) { | ||
1029 | if (cnt) | ||
1030 | udelay(100); | ||
1031 | else | ||
1032 | rval = QLA_FUNCTION_TIMEOUT; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | /* Disable interrupts. */ | ||
1037 | WRT_REG_DWORD(®->ictrl, 0); | ||
1038 | RD_REG_DWORD(®->ictrl); | ||
1039 | |||
1040 | if (rval == QLA_SUCCESS) { | ||
1041 | /* Host interface registers. */ | ||
1042 | dmp_reg = (uint32_t __iomem *)(reg + 0); | ||
1043 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | ||
1044 | fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1045 | |||
1046 | /* Mailbox registers. */ | ||
1047 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | ||
1048 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | ||
1049 | fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++); | ||
1050 | |||
1051 | /* Transfer sequence registers. */ | ||
1052 | iter_reg = fw->xseq_gp_reg; | ||
1053 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | ||
1054 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1055 | for (cnt = 0; cnt < 16; cnt++) | ||
1056 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1057 | |||
1058 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | ||
1059 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1060 | for (cnt = 0; cnt < 16; cnt++) | ||
1061 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1062 | |||
1063 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | ||
1064 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1065 | for (cnt = 0; cnt < 16; cnt++) | ||
1066 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1067 | |||
1068 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | ||
1069 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1070 | for (cnt = 0; cnt < 16; cnt++) | ||
1071 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1072 | |||
1073 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | ||
1074 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1075 | for (cnt = 0; cnt < 16; cnt++) | ||
1076 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1077 | |||
1078 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | ||
1079 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1080 | for (cnt = 0; cnt < 16; cnt++) | ||
1081 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1082 | |||
1083 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | ||
1084 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1085 | for (cnt = 0; cnt < 16; cnt++) | ||
1086 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1087 | |||
1088 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | ||
1089 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1090 | for (cnt = 0; cnt < 16; cnt++) | ||
1091 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1092 | |||
1093 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | ||
1094 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1095 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | ||
1096 | fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1097 | |||
1098 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | ||
1099 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1100 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | ||
1101 | fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1102 | |||
1103 | /* Receive sequence registers. */ | ||
1104 | iter_reg = fw->rseq_gp_reg; | ||
1105 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | ||
1106 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1107 | for (cnt = 0; cnt < 16; cnt++) | ||
1108 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1109 | |||
1110 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | ||
1111 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1112 | for (cnt = 0; cnt < 16; cnt++) | ||
1113 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1114 | |||
1115 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | ||
1116 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1117 | for (cnt = 0; cnt < 16; cnt++) | ||
1118 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1119 | |||
1120 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | ||
1121 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1122 | for (cnt = 0; cnt < 16; cnt++) | ||
1123 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1124 | |||
1125 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | ||
1126 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1127 | for (cnt = 0; cnt < 16; cnt++) | ||
1128 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1129 | |||
1130 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | ||
1131 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1132 | for (cnt = 0; cnt < 16; cnt++) | ||
1133 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1134 | |||
1135 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | ||
1136 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1137 | for (cnt = 0; cnt < 16; cnt++) | ||
1138 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1139 | |||
1140 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | ||
1141 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1142 | for (cnt = 0; cnt < 16; cnt++) | ||
1143 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1144 | |||
1145 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | ||
1146 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1147 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | ||
1148 | fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1149 | |||
1150 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | ||
1151 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1152 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | ||
1153 | fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1154 | |||
1155 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | ||
1156 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1157 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | ||
1158 | fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1159 | |||
1160 | /* Command DMA registers. */ | ||
1161 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | ||
1162 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1163 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | ||
1164 | fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1165 | |||
1166 | /* Queues. */ | ||
1167 | iter_reg = fw->req0_dma_reg; | ||
1168 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | ||
1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1170 | for (cnt = 0; cnt < 8; cnt++) | ||
1171 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1172 | |||
1173 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | ||
1174 | for (cnt = 0; cnt < 7; cnt++) | ||
1175 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1176 | |||
1177 | iter_reg = fw->resp0_dma_reg; | ||
1178 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | ||
1179 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1180 | for (cnt = 0; cnt < 8; cnt++) | ||
1181 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1182 | |||
1183 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | ||
1184 | for (cnt = 0; cnt < 7; cnt++) | ||
1185 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1186 | |||
1187 | iter_reg = fw->req1_dma_reg; | ||
1188 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | ||
1189 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1190 | for (cnt = 0; cnt < 8; cnt++) | ||
1191 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1192 | |||
1193 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | ||
1194 | for (cnt = 0; cnt < 7; cnt++) | ||
1195 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1196 | |||
1197 | /* Transmit DMA registers. */ | ||
1198 | iter_reg = fw->xmt0_dma_reg; | ||
1199 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | ||
1200 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1201 | for (cnt = 0; cnt < 16; cnt++) | ||
1202 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1203 | |||
1204 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | ||
1205 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1206 | for (cnt = 0; cnt < 16; cnt++) | ||
1207 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1208 | |||
1209 | iter_reg = fw->xmt1_dma_reg; | ||
1210 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | ||
1211 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1212 | for (cnt = 0; cnt < 16; cnt++) | ||
1213 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1214 | |||
1215 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | ||
1216 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1217 | for (cnt = 0; cnt < 16; cnt++) | ||
1218 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1219 | |||
1220 | iter_reg = fw->xmt2_dma_reg; | ||
1221 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | ||
1222 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1223 | for (cnt = 0; cnt < 16; cnt++) | ||
1224 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1225 | |||
1226 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | ||
1227 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1228 | for (cnt = 0; cnt < 16; cnt++) | ||
1229 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1230 | |||
1231 | iter_reg = fw->xmt3_dma_reg; | ||
1232 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | ||
1233 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1234 | for (cnt = 0; cnt < 16; cnt++) | ||
1235 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1236 | |||
1237 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | ||
1238 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1239 | for (cnt = 0; cnt < 16; cnt++) | ||
1240 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1241 | |||
1242 | iter_reg = fw->xmt4_dma_reg; | ||
1243 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | ||
1244 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1245 | for (cnt = 0; cnt < 16; cnt++) | ||
1246 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1247 | |||
1248 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | ||
1249 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1250 | for (cnt = 0; cnt < 16; cnt++) | ||
1251 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1252 | |||
1253 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | ||
1254 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1255 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | ||
1256 | fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | ||
1257 | |||
1258 | /* Receive DMA registers. */ | ||
1259 | iter_reg = fw->rcvt0_data_dma_reg; | ||
1260 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | ||
1261 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1262 | for (cnt = 0; cnt < 16; cnt++) | ||
1263 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1264 | |||
1265 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | ||
1266 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1267 | for (cnt = 0; cnt < 16; cnt++) | ||
1268 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1269 | |||
1270 | iter_reg = fw->rcvt1_data_dma_reg; | ||
1271 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | ||
1272 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1273 | for (cnt = 0; cnt < 16; cnt++) | ||
1274 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1275 | |||
1276 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | ||
1277 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1278 | for (cnt = 0; cnt < 16; cnt++) | ||
1279 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1280 | |||
1281 | /* RISC registers. */ | ||
1282 | iter_reg = fw->risc_gp_reg; | ||
1283 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | ||
1284 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1285 | for (cnt = 0; cnt < 16; cnt++) | ||
1286 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1287 | |||
1288 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | ||
1289 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1290 | for (cnt = 0; cnt < 16; cnt++) | ||
1291 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1292 | |||
1293 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | ||
1294 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1295 | for (cnt = 0; cnt < 16; cnt++) | ||
1296 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1297 | |||
1298 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | ||
1299 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1300 | for (cnt = 0; cnt < 16; cnt++) | ||
1301 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1302 | |||
1303 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | ||
1304 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1305 | for (cnt = 0; cnt < 16; cnt++) | ||
1306 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1307 | |||
1308 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | ||
1309 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1310 | for (cnt = 0; cnt < 16; cnt++) | ||
1311 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1312 | |||
1313 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | ||
1314 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1315 | for (cnt = 0; cnt < 16; cnt++) | ||
1316 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1317 | |||
1318 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1319 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1320 | for (cnt = 0; cnt < 16; cnt++) | ||
1321 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1322 | |||
1323 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1324 | RD_REG_DWORD(®->iobase_addr); | ||
1325 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1326 | WRT_REG_DWORD(dmp_reg, 0xB0000000); | ||
1327 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1328 | fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg); | ||
1329 | |||
1330 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1331 | WRT_REG_DWORD(dmp_reg, 0xB0100000); | ||
1332 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1333 | fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg); | ||
1334 | |||
1335 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1336 | WRT_REG_DWORD(dmp_reg, 0xB0200000); | ||
1337 | dmp_reg = (uint32_t *)((uint8_t *)reg + 0xFC); | ||
1338 | fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg); | ||
1339 | |||
1340 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1341 | WRT_REG_DWORD(dmp_reg, 0xB0300000); | ||
1342 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1343 | fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg); | ||
1344 | |||
1345 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1346 | WRT_REG_DWORD(dmp_reg, 0xB0400000); | ||
1347 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1348 | fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg); | ||
1349 | |||
1350 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1351 | WRT_REG_DWORD(dmp_reg, 0xB0500000); | ||
1352 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1353 | fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg); | ||
1354 | |||
1355 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
1356 | WRT_REG_DWORD(dmp_reg, 0xB0600000); | ||
1357 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
1358 | fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg); | ||
1359 | |||
1360 | /* Local memory controller registers. */ | ||
1361 | iter_reg = fw->lmc_reg; | ||
1362 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | ||
1363 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1364 | for (cnt = 0; cnt < 16; cnt++) | ||
1365 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1366 | |||
1367 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | ||
1368 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1369 | for (cnt = 0; cnt < 16; cnt++) | ||
1370 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1371 | |||
1372 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | ||
1373 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1374 | for (cnt = 0; cnt < 16; cnt++) | ||
1375 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1376 | |||
1377 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | ||
1378 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1379 | for (cnt = 0; cnt < 16; cnt++) | ||
1380 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1381 | |||
1382 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | ||
1383 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1384 | for (cnt = 0; cnt < 16; cnt++) | ||
1385 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1386 | |||
1387 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | ||
1388 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1389 | for (cnt = 0; cnt < 16; cnt++) | ||
1390 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1391 | |||
1392 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | ||
1393 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1394 | for (cnt = 0; cnt < 16; cnt++) | ||
1395 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1396 | |||
1397 | /* Fibre Protocol Module registers. */ | ||
1398 | iter_reg = fw->fpm_hdw_reg; | ||
1399 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | ||
1400 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1401 | for (cnt = 0; cnt < 16; cnt++) | ||
1402 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1403 | |||
1404 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | ||
1405 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1406 | for (cnt = 0; cnt < 16; cnt++) | ||
1407 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1408 | |||
1409 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | ||
1410 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1411 | for (cnt = 0; cnt < 16; cnt++) | ||
1412 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1413 | |||
1414 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | ||
1415 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1416 | for (cnt = 0; cnt < 16; cnt++) | ||
1417 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1418 | |||
1419 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | ||
1420 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1421 | for (cnt = 0; cnt < 16; cnt++) | ||
1422 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1423 | |||
1424 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | ||
1425 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1426 | for (cnt = 0; cnt < 16; cnt++) | ||
1427 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1428 | |||
1429 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | ||
1430 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1431 | for (cnt = 0; cnt < 16; cnt++) | ||
1432 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1433 | |||
1434 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | ||
1435 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1436 | for (cnt = 0; cnt < 16; cnt++) | ||
1437 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1438 | |||
1439 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | ||
1440 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1441 | for (cnt = 0; cnt < 16; cnt++) | ||
1442 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1443 | |||
1444 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | ||
1445 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1446 | for (cnt = 0; cnt < 16; cnt++) | ||
1447 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1448 | |||
1449 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | ||
1450 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1451 | for (cnt = 0; cnt < 16; cnt++) | ||
1452 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1453 | |||
1454 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | ||
1455 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1456 | for (cnt = 0; cnt < 16; cnt++) | ||
1457 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1458 | |||
1459 | /* Frame Buffer registers. */ | ||
1460 | iter_reg = fw->fb_hdw_reg; | ||
1461 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | ||
1462 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1463 | for (cnt = 0; cnt < 16; cnt++) | ||
1464 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1465 | |||
1466 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | ||
1467 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1468 | for (cnt = 0; cnt < 16; cnt++) | ||
1469 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1470 | |||
1471 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | ||
1472 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1473 | for (cnt = 0; cnt < 16; cnt++) | ||
1474 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1475 | |||
1476 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | ||
1477 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1478 | for (cnt = 0; cnt < 16; cnt++) | ||
1479 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1480 | |||
1481 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | ||
1482 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1483 | for (cnt = 0; cnt < 16; cnt++) | ||
1484 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1485 | |||
1486 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | ||
1487 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1488 | for (cnt = 0; cnt < 16; cnt++) | ||
1489 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1490 | |||
1491 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | ||
1492 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1493 | for (cnt = 0; cnt < 16; cnt++) | ||
1494 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1495 | |||
1496 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | ||
1497 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1498 | for (cnt = 0; cnt < 16; cnt++) | ||
1499 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1500 | |||
1501 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | ||
1502 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1503 | for (cnt = 0; cnt < 16; cnt++) | ||
1504 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1505 | |||
1506 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | ||
1507 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1508 | for (cnt = 0; cnt < 16; cnt++) | ||
1509 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1510 | |||
1511 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | ||
1512 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | ||
1513 | for (cnt = 0; cnt < 16; cnt++) | ||
1514 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | ||
1515 | |||
1516 | /* Reset RISC. */ | ||
1517 | WRT_REG_DWORD(®->ctrl_status, | ||
1518 | CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1519 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1520 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1521 | CSRX_DMA_ACTIVE) == 0) | ||
1522 | break; | ||
1523 | |||
1524 | udelay(10); | ||
1525 | } | ||
1526 | |||
1527 | WRT_REG_DWORD(®->ctrl_status, | ||
1528 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1529 | udelay(20); | ||
1530 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1531 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1532 | CSRX_ISP_SOFT_RESET) == 0) | ||
1533 | break; | ||
1534 | |||
1535 | udelay(10); | ||
1536 | } | ||
1537 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | ||
1538 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
1539 | } | ||
1540 | |||
1541 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | ||
1542 | rval == QLA_SUCCESS; cnt--) { | ||
1543 | if (cnt) | ||
1544 | udelay(100); | ||
1545 | else | ||
1546 | rval = QLA_FUNCTION_TIMEOUT; | ||
1547 | } | ||
1548 | |||
1549 | /* Memory. */ | ||
1550 | if (rval == QLA_SUCCESS) { | ||
1551 | /* Code RAM. */ | ||
1552 | risc_address = 0x20000; | ||
1553 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
1554 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
1555 | } | ||
1556 | for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS; | ||
1557 | cnt++, risc_address++) { | ||
1558 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
1559 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
1560 | RD_REG_WORD(®->mailbox8); | ||
1561 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
1562 | |||
1563 | for (timer = 6000000; timer; timer--) { | ||
1564 | /* Check for pending interrupts. */ | ||
1565 | stat = RD_REG_DWORD(®->host_status); | ||
1566 | if (stat & HSRX_RISC_INT) { | ||
1567 | stat &= 0xff; | ||
1568 | |||
1569 | if (stat == 0x1 || stat == 0x2 || | ||
1570 | stat == 0x10 || stat == 0x11) { | ||
1571 | set_bit(MBX_INTERRUPT, | ||
1572 | &ha->mbx_cmd_flags); | ||
1573 | |||
1574 | mb[0] = RD_REG_WORD(®->mailbox0); | ||
1575 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
1576 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
1577 | |||
1578 | WRT_REG_DWORD(®->hccr, | ||
1579 | HCCRX_CLR_RISC_INT); | ||
1580 | RD_REG_DWORD(®->hccr); | ||
1581 | break; | ||
1582 | } | ||
1583 | |||
1584 | /* Clear this intr; it wasn't a mailbox intr */ | ||
1585 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1586 | RD_REG_DWORD(®->hccr); | ||
1587 | } | ||
1588 | udelay(5); | ||
1589 | } | ||
1590 | |||
1591 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
1592 | rval = mb[0] & MBS_MASK; | ||
1593 | fw->code_ram[cnt] = (mb[3] << 16) | mb[2]; | ||
1594 | } else { | ||
1595 | rval = QLA_FUNCTION_FAILED; | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | if (rval == QLA_SUCCESS) { | ||
1600 | /* External Memory. */ | ||
1601 | risc_address = 0x100000; | ||
1602 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
1603 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
1604 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
1605 | } | ||
1606 | for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS; | ||
1607 | cnt++, risc_address++) { | ||
1608 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
1609 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
1610 | RD_REG_WORD(®->mailbox8); | ||
1611 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
1612 | |||
1613 | for (timer = 6000000; timer; timer--) { | ||
1614 | /* Check for pending interrupts. */ | ||
1615 | stat = RD_REG_DWORD(®->host_status); | ||
1616 | if (stat & HSRX_RISC_INT) { | ||
1617 | stat &= 0xff; | ||
1618 | |||
1619 | if (stat == 0x1 || stat == 0x2 || | ||
1620 | stat == 0x10 || stat == 0x11) { | ||
1621 | set_bit(MBX_INTERRUPT, | ||
1622 | &ha->mbx_cmd_flags); | ||
1623 | |||
1624 | mb[0] = RD_REG_WORD(®->mailbox0); | ||
1625 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
1626 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
1627 | |||
1628 | WRT_REG_DWORD(®->hccr, | ||
1629 | HCCRX_CLR_RISC_INT); | ||
1630 | RD_REG_DWORD(®->hccr); | ||
1631 | break; | ||
1632 | } | ||
1633 | |||
1634 | /* Clear this intr; it wasn't a mailbox intr */ | ||
1635 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1636 | RD_REG_DWORD(®->hccr); | ||
1637 | } | ||
1638 | udelay(5); | ||
1639 | } | ||
1640 | |||
1641 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
1642 | rval = mb[0] & MBS_MASK; | ||
1643 | fw->ext_mem[cnt] = (mb[3] << 16) | mb[2]; | ||
1644 | } else { | ||
1645 | rval = QLA_FUNCTION_FAILED; | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1649 | if (rval != QLA_SUCCESS) { | ||
1650 | qla_printk(KERN_WARNING, ha, | ||
1651 | "Failed to dump firmware (%x)!!!\n", rval); | ||
1652 | ha->fw_dumped = 0; | ||
1653 | |||
1654 | } else { | ||
1655 | qla_printk(KERN_INFO, ha, | ||
1656 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
1657 | ha->host_no, ha->fw_dump24); | ||
1658 | ha->fw_dumped = 1; | ||
1659 | } | ||
1660 | |||
1661 | qla24xx_fw_dump_failed: | ||
1662 | if (!hardware_locked) | ||
1663 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1664 | } | ||
1665 | |||
1666 | void | ||
1667 | qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) | ||
1668 | { | ||
1669 | uint32_t cnt; | ||
1670 | char *uiter; | ||
1671 | struct qla24xx_fw_dump *fw; | ||
1672 | uint32_t ext_mem_cnt; | ||
1673 | |||
1674 | uiter = ha->fw_dump_buffer; | ||
1675 | fw = ha->fw_dump24; | ||
1676 | |||
1677 | qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", | ||
1678 | ha->fw_major_version, ha->fw_minor_version, | ||
1679 | ha->fw_subminor_version, ha->fw_attributes); | ||
1680 | |||
1681 | qla_uprintf(&uiter, "\nHCCR Register\n%04x\n", fw->hccr); | ||
1682 | |||
1683 | qla_uprintf(&uiter, "\nHost Interface Registers"); | ||
1684 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) { | ||
1685 | if (cnt % 8 == 0) | ||
1686 | qla_uprintf(&uiter, "\n"); | ||
1687 | |||
1688 | qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]); | ||
1689 | } | ||
1690 | |||
1691 | qla_uprintf(&uiter, "\n\nMailbox Registers"); | ||
1692 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) { | ||
1693 | if (cnt % 8 == 0) | ||
1694 | qla_uprintf(&uiter, "\n"); | ||
1695 | |||
1696 | qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]); | ||
1697 | } | ||
1698 | |||
1699 | qla_uprintf(&uiter, "\n\nXSEQ GP Registers"); | ||
1700 | for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) { | ||
1701 | if (cnt % 8 == 0) | ||
1702 | qla_uprintf(&uiter, "\n"); | ||
1703 | |||
1704 | qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]); | ||
1705 | } | ||
1706 | |||
1707 | qla_uprintf(&uiter, "\n\nXSEQ-0 Registers"); | ||
1708 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) { | ||
1709 | if (cnt % 8 == 0) | ||
1710 | qla_uprintf(&uiter, "\n"); | ||
1711 | |||
1712 | qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]); | ||
1713 | } | ||
1714 | |||
1715 | qla_uprintf(&uiter, "\n\nXSEQ-1 Registers"); | ||
1716 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) { | ||
1717 | if (cnt % 8 == 0) | ||
1718 | qla_uprintf(&uiter, "\n"); | ||
1719 | |||
1720 | qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]); | ||
1721 | } | ||
1722 | |||
1723 | qla_uprintf(&uiter, "\n\nRSEQ GP Registers"); | ||
1724 | for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) { | ||
1725 | if (cnt % 8 == 0) | ||
1726 | qla_uprintf(&uiter, "\n"); | ||
1727 | |||
1728 | qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]); | ||
1729 | } | ||
1730 | |||
1731 | qla_uprintf(&uiter, "\n\nRSEQ-0 Registers"); | ||
1732 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) { | ||
1733 | if (cnt % 8 == 0) | ||
1734 | qla_uprintf(&uiter, "\n"); | ||
1735 | |||
1736 | qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]); | ||
1737 | } | ||
1738 | |||
1739 | qla_uprintf(&uiter, "\n\nRSEQ-1 Registers"); | ||
1740 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) { | ||
1741 | if (cnt % 8 == 0) | ||
1742 | qla_uprintf(&uiter, "\n"); | ||
1743 | |||
1744 | qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]); | ||
1745 | } | ||
1746 | |||
1747 | qla_uprintf(&uiter, "\n\nRSEQ-2 Registers"); | ||
1748 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) { | ||
1749 | if (cnt % 8 == 0) | ||
1750 | qla_uprintf(&uiter, "\n"); | ||
1751 | |||
1752 | qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]); | ||
1753 | } | ||
1754 | |||
1755 | qla_uprintf(&uiter, "\n\nCommand DMA Registers"); | ||
1756 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) { | ||
1757 | if (cnt % 8 == 0) | ||
1758 | qla_uprintf(&uiter, "\n"); | ||
1759 | |||
1760 | qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]); | ||
1761 | } | ||
1762 | |||
1763 | qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers"); | ||
1764 | for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) { | ||
1765 | if (cnt % 8 == 0) | ||
1766 | qla_uprintf(&uiter, "\n"); | ||
1767 | |||
1768 | qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]); | ||
1769 | } | ||
1770 | |||
1771 | qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers"); | ||
1772 | for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) { | ||
1773 | if (cnt % 8 == 0) | ||
1774 | qla_uprintf(&uiter, "\n"); | ||
1775 | |||
1776 | qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]); | ||
1777 | } | ||
1778 | |||
1779 | qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers"); | ||
1780 | for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) { | ||
1781 | if (cnt % 8 == 0) | ||
1782 | qla_uprintf(&uiter, "\n"); | ||
1783 | |||
1784 | qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]); | ||
1785 | } | ||
1786 | |||
1787 | qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers"); | ||
1788 | for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) { | ||
1789 | if (cnt % 8 == 0) | ||
1790 | qla_uprintf(&uiter, "\n"); | ||
1791 | |||
1792 | qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]); | ||
1793 | } | ||
1794 | |||
1795 | qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers"); | ||
1796 | for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) { | ||
1797 | if (cnt % 8 == 0) | ||
1798 | qla_uprintf(&uiter, "\n"); | ||
1799 | |||
1800 | qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]); | ||
1801 | } | ||
1802 | |||
1803 | qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers"); | ||
1804 | for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) { | ||
1805 | if (cnt % 8 == 0) | ||
1806 | qla_uprintf(&uiter, "\n"); | ||
1807 | |||
1808 | qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]); | ||
1809 | } | ||
1810 | |||
1811 | qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers"); | ||
1812 | for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) { | ||
1813 | if (cnt % 8 == 0) | ||
1814 | qla_uprintf(&uiter, "\n"); | ||
1815 | |||
1816 | qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]); | ||
1817 | } | ||
1818 | |||
1819 | qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers"); | ||
1820 | for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) { | ||
1821 | if (cnt % 8 == 0) | ||
1822 | qla_uprintf(&uiter, "\n"); | ||
1823 | |||
1824 | qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]); | ||
1825 | } | ||
1826 | |||
1827 | qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers"); | ||
1828 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) { | ||
1829 | if (cnt % 8 == 0) | ||
1830 | qla_uprintf(&uiter, "\n"); | ||
1831 | |||
1832 | qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]); | ||
1833 | } | ||
1834 | |||
1835 | qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers"); | ||
1836 | for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) { | ||
1837 | if (cnt % 8 == 0) | ||
1838 | qla_uprintf(&uiter, "\n"); | ||
1839 | |||
1840 | qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]); | ||
1841 | } | ||
1842 | |||
1843 | qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers"); | ||
1844 | for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) { | ||
1845 | if (cnt % 8 == 0) | ||
1846 | qla_uprintf(&uiter, "\n"); | ||
1847 | |||
1848 | qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]); | ||
1849 | } | ||
1850 | |||
1851 | qla_uprintf(&uiter, "\n\nRISC GP Registers"); | ||
1852 | for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) { | ||
1853 | if (cnt % 8 == 0) | ||
1854 | qla_uprintf(&uiter, "\n"); | ||
1855 | |||
1856 | qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]); | ||
1857 | } | ||
1858 | |||
1859 | qla_uprintf(&uiter, "\n\nShadow Registers"); | ||
1860 | for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) { | ||
1861 | if (cnt % 8 == 0) | ||
1862 | qla_uprintf(&uiter, "\n"); | ||
1863 | |||
1864 | qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]); | ||
1865 | } | ||
1866 | |||
1867 | qla_uprintf(&uiter, "\n\nLMC Registers"); | ||
1868 | for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) { | ||
1869 | if (cnt % 8 == 0) | ||
1870 | qla_uprintf(&uiter, "\n"); | ||
1871 | |||
1872 | qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]); | ||
1873 | } | ||
1874 | |||
1875 | qla_uprintf(&uiter, "\n\nFPM Hardware Registers"); | ||
1876 | for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) { | ||
1877 | if (cnt % 8 == 0) | ||
1878 | qla_uprintf(&uiter, "\n"); | ||
1879 | |||
1880 | qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]); | ||
1881 | } | ||
1882 | |||
1883 | qla_uprintf(&uiter, "\n\nFB Hardware Registers"); | ||
1884 | for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) { | ||
1885 | if (cnt % 8 == 0) | ||
1886 | qla_uprintf(&uiter, "\n"); | ||
1887 | |||
1888 | qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]); | ||
1889 | } | ||
1890 | |||
1891 | qla_uprintf(&uiter, "\n\nCode RAM"); | ||
1892 | for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { | ||
1893 | if (cnt % 8 == 0) { | ||
1894 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000); | ||
1895 | } | ||
1896 | qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]); | ||
1897 | } | ||
1898 | |||
1899 | qla_uprintf(&uiter, "\n\nExternal Memory"); | ||
1900 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
1901 | for (cnt = 0; cnt < ext_mem_cnt; cnt++) { | ||
1902 | if (cnt % 8 == 0) { | ||
1903 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000); | ||
1904 | } | ||
1905 | qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]); | ||
1906 | } | ||
1907 | |||
1908 | qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump"); | ||
1909 | } | ||
1910 | |||
979 | 1911 | ||
980 | /****************************************************************************/ | 1912 | /****************************************************************************/ |
981 | /* Driver Debug Functions. */ | 1913 | /* Driver Debug Functions. */ |
@@ -1066,6 +1998,21 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | |||
1066 | printk(" state=%d\n", sp->state); | 1998 | printk(" state=%d\n", sp->state); |
1067 | } | 1999 | } |
1068 | 2000 | ||
2001 | void | ||
2002 | qla2x00_dump_pkt(void *pkt) | ||
2003 | { | ||
2004 | uint32_t i; | ||
2005 | uint8_t *data = (uint8_t *) pkt; | ||
2006 | |||
2007 | for (i = 0; i < 64; i++) { | ||
2008 | if (!(i % 4)) | ||
2009 | printk("\n%02x: ", i); | ||
2010 | |||
2011 | printk("%02x ", data[i]); | ||
2012 | } | ||
2013 | printk("\n"); | ||
2014 | } | ||
2015 | |||
1069 | #if defined(QL_DEBUG_ROUTINES) | 2016 | #if defined(QL_DEBUG_ROUTINES) |
1070 | /* | 2017 | /* |
1071 | * qla2x00_formatted_dump_buffer | 2018 | * qla2x00_formatted_dump_buffer |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index d7f56c761418..eaa0f0f0851a 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -230,4 +230,36 @@ struct qla2100_fw_dump { | |||
230 | uint16_t risc_ram[0xf000]; | 230 | uint16_t risc_ram[0xf000]; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | #define FW_DUMP_SIZE_24XX 0x2B0000 | ||
233 | 234 | ||
235 | struct qla24xx_fw_dump { | ||
236 | uint32_t hccr; | ||
237 | uint32_t host_reg[32]; | ||
238 | uint16_t mailbox_reg[32]; | ||
239 | uint32_t xseq_gp_reg[128]; | ||
240 | uint32_t xseq_0_reg[16]; | ||
241 | uint32_t xseq_1_reg[16]; | ||
242 | uint32_t rseq_gp_reg[128]; | ||
243 | uint32_t rseq_0_reg[16]; | ||
244 | uint32_t rseq_1_reg[16]; | ||
245 | uint32_t rseq_2_reg[16]; | ||
246 | uint32_t cmd_dma_reg[16]; | ||
247 | uint32_t req0_dma_reg[15]; | ||
248 | uint32_t resp0_dma_reg[15]; | ||
249 | uint32_t req1_dma_reg[15]; | ||
250 | uint32_t xmt0_dma_reg[32]; | ||
251 | uint32_t xmt1_dma_reg[32]; | ||
252 | uint32_t xmt2_dma_reg[32]; | ||
253 | uint32_t xmt3_dma_reg[32]; | ||
254 | uint32_t xmt4_dma_reg[32]; | ||
255 | uint32_t xmt_data_dma_reg[16]; | ||
256 | uint32_t rcvt0_data_dma_reg[32]; | ||
257 | uint32_t rcvt1_data_dma_reg[32]; | ||
258 | uint32_t risc_gp_reg[128]; | ||
259 | uint32_t shadow_reg[7]; | ||
260 | uint32_t lmc_reg[112]; | ||
261 | uint32_t fpm_hdw_reg[192]; | ||
262 | uint32_t fb_hdw_reg[176]; | ||
263 | uint32_t code_ram[0x2000]; | ||
264 | uint32_t ext_mem[1]; | ||
265 | }; | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 6bea7ac622c7..ba648f69f2f5 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -207,11 +207,14 @@ extern void qla2x00_write_nvram_word(scsi_qla_host_t *, uint32_t, uint16_t); | |||
207 | */ | 207 | */ |
208 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 208 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
209 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 209 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
210 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | ||
210 | extern void qla2100_ascii_fw_dump(scsi_qla_host_t *); | 211 | extern void qla2100_ascii_fw_dump(scsi_qla_host_t *); |
211 | extern void qla2300_ascii_fw_dump(scsi_qla_host_t *); | 212 | extern void qla2300_ascii_fw_dump(scsi_qla_host_t *); |
213 | extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *); | ||
212 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 214 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
213 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 215 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
214 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 216 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
217 | extern void qla2x00_dump_pkt(void *); | ||
215 | 218 | ||
216 | /* | 219 | /* |
217 | * Global Function Prototypes in qla_gs.c source file. | 220 | * Global Function Prototypes in qla_gs.c source file. |