aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic94xx/aic94xx_sds.c
diff options
context:
space:
mode:
authorGilbert Wu <Gilbert_Wu@adaptec.com>2007-10-22 18:19:11 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:30 -0500
commit1237c98db2aa94b42dbb9fb1df062b7d3733dc83 (patch)
tree01c6d82790815753c0e66e9c3e571862d0f226bf /drivers/scsi/aic94xx/aic94xx_sds.c
parent285e9670d91cdeb6b6693729950339cb45410fdc (diff)
[SCSI] aic94xx: update BIOS image from user space.
1. Create a file "update_bios" in sysfs to allow user to update bios from user space. 2. The BIOS image file can be downloaded from web site "http://www.adaptec.com/en-US/downloads/bios_fw/bios_fw_ver?productId=SAS-48300&dn=Adaptec+Serial+Attached+SCSI+48300" and copy the BIOS image into /lib/firmware folder. 3. The aic994xx will accept "update bios_file" and "verify bios_file" commands to perform update and verify BIOS image . For example: Type "echo "update asc483c01.ufi" > /sys/devices/.../update_bios" to update BIOS image from /lib/firmware/as483c01.ufi file into HBA's flash memory. Type "echo "verify asc483c01.ufi" > /sys/devices/.../update_bios" to verify BIOS image between /lib/firmware/asc48c01.ufi file and HBA's flash memory. 4. Type "cat /sys/devices/.../update_bios" to view the status or result of updating BIOS. Signed-off-by: Gilbert Wu <gilbert_wu@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_sds.c')
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c389
1 files changed, 389 insertions, 0 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 06509bff71f7..2a4c933eb89c 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -30,6 +30,7 @@
30 30
31#include "aic94xx.h" 31#include "aic94xx.h"
32#include "aic94xx_reg.h" 32#include "aic94xx_reg.h"
33#include "aic94xx_sds.h"
33 34
34/* ---------- OCM stuff ---------- */ 35/* ---------- OCM stuff ---------- */
35 36
@@ -1083,3 +1084,391 @@ out:
1083 kfree(flash_dir); 1084 kfree(flash_dir);
1084 return err; 1085 return err;
1085} 1086}
1087
1088/**
1089 * asd_verify_flash_seg - verify data with flash memory
1090 * @asd_ha: pointer to the host adapter structure
1091 * @src: pointer to the source data to be verified
1092 * @dest_offset: offset from flash memory
1093 * @bytes_to_verify: total bytes to verify
1094 */
1095int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
1096 void *src, u32 dest_offset, u32 bytes_to_verify)
1097{
1098 u8 *src_buf;
1099 u8 flash_char;
1100 int err;
1101 u32 nv_offset, reg, i;
1102
1103 reg = asd_ha->hw_prof.flash.bar;
1104 src_buf = NULL;
1105
1106 err = FLASH_OK;
1107 nv_offset = dest_offset;
1108 src_buf = (u8 *)src;
1109 for (i = 0; i < bytes_to_verify; i++) {
1110 flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
1111 if (flash_char != src_buf[i]) {
1112 err = FAIL_VERIFY;
1113 break;
1114 }
1115 }
1116 return err;
1117}
1118
1119/**
1120 * asd_write_flash_seg - write data into flash memory
1121 * @asd_ha: pointer to the host adapter structure
1122 * @src: pointer to the source data to be written
1123 * @dest_offset: offset from flash memory
1124 * @bytes_to_write: total bytes to write
1125 */
1126int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
1127 void *src, u32 dest_offset, u32 bytes_to_write)
1128{
1129 u8 *src_buf;
1130 u32 nv_offset, reg, i;
1131 int err;
1132
1133 reg = asd_ha->hw_prof.flash.bar;
1134 src_buf = NULL;
1135
1136 err = asd_check_flash_type(asd_ha);
1137 if (err) {
1138 ASD_DPRINTK("couldn't find the type of flash. err=%d\n", err);
1139 return err;
1140 }
1141
1142 nv_offset = dest_offset;
1143 err = asd_erase_nv_sector(asd_ha, nv_offset, bytes_to_write);
1144 if (err) {
1145 ASD_DPRINTK("Erase failed at offset:0x%x\n",
1146 nv_offset);
1147 return err;
1148 }
1149
1150 err = asd_reset_flash(asd_ha);
1151 if (err) {
1152 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1153 return err;
1154 }
1155
1156 src_buf = (u8 *)src;
1157 for (i = 0; i < bytes_to_write; i++) {
1158 /* Setup program command sequence */
1159 switch (asd_ha->hw_prof.flash.method) {
1160 case FLASH_METHOD_A:
1161 {
1162 asd_write_reg_byte(asd_ha,
1163 (reg + 0xAAA), 0xAA);
1164 asd_write_reg_byte(asd_ha,
1165 (reg + 0x555), 0x55);
1166 asd_write_reg_byte(asd_ha,
1167 (reg + 0xAAA), 0xA0);
1168 asd_write_reg_byte(asd_ha,
1169 (reg + nv_offset + i),
1170 (*(src_buf + i)));
1171 break;
1172 }
1173 case FLASH_METHOD_B:
1174 {
1175 asd_write_reg_byte(asd_ha,
1176 (reg + 0x555), 0xAA);
1177 asd_write_reg_byte(asd_ha,
1178 (reg + 0x2AA), 0x55);
1179 asd_write_reg_byte(asd_ha,
1180 (reg + 0x555), 0xA0);
1181 asd_write_reg_byte(asd_ha,
1182 (reg + nv_offset + i),
1183 (*(src_buf + i)));
1184 break;
1185 }
1186 default:
1187 break;
1188 }
1189 if (asd_chk_write_status(asd_ha,
1190 (nv_offset + i), 0) != 0) {
1191 ASD_DPRINTK("aicx: Write failed at offset:0x%x\n",
1192 reg + nv_offset + i);
1193 return FAIL_WRITE_FLASH;
1194 }
1195 }
1196
1197 err = asd_reset_flash(asd_ha);
1198 if (err) {
1199 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1200 return err;
1201 }
1202 return 0;
1203}
1204
1205int asd_chk_write_status(struct asd_ha_struct *asd_ha,
1206 u32 sector_addr, u8 erase_flag)
1207{
1208 u32 reg;
1209 u32 loop_cnt;
1210 u8 nv_data1, nv_data2;
1211 u8 toggle_bit1;
1212
1213 /*
1214 * Read from DQ2 requires sector address
1215 * while it's dont care for DQ6
1216 */
1217 reg = asd_ha->hw_prof.flash.bar;
1218
1219 for (loop_cnt = 0; loop_cnt < 50000; loop_cnt++) {
1220 nv_data1 = asd_read_reg_byte(asd_ha, reg);
1221 nv_data2 = asd_read_reg_byte(asd_ha, reg);
1222
1223 toggle_bit1 = ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
1224 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
1225
1226 if (toggle_bit1 == 0) {
1227 return 0;
1228 } else {
1229 if (nv_data2 & FLASH_STATUS_BIT_MASK_DQ5) {
1230 nv_data1 = asd_read_reg_byte(asd_ha,
1231 reg);
1232 nv_data2 = asd_read_reg_byte(asd_ha,
1233 reg);
1234 toggle_bit1 =
1235 ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
1236 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
1237
1238 if (toggle_bit1 == 0)
1239 return 0;
1240 }
1241 }
1242
1243 /*
1244 * ERASE is a sector-by-sector operation and requires
1245 * more time to finish while WRITE is byte-byte-byte
1246 * operation and takes lesser time to finish.
1247 *
1248 * For some strange reason a reduced ERASE delay gives different
1249 * behaviour across different spirit boards. Hence we set
1250 * a optimum balance of 50mus for ERASE which works well
1251 * across all boards.
1252 */
1253 if (erase_flag) {
1254 udelay(FLASH_STATUS_ERASE_DELAY_COUNT);
1255 } else {
1256 udelay(FLASH_STATUS_WRITE_DELAY_COUNT);
1257 }
1258 }
1259 return -1;
1260}
1261
1262/**
1263 * asd_hwi_erase_nv_sector - Erase the flash memory sectors.
1264 * @asd_ha: pointer to the host adapter structure
1265 * @flash_addr: pointer to offset from flash memory
1266 * @size: total bytes to erase.
1267 */
1268int asd_erase_nv_sector(struct asd_ha_struct *asd_ha, u32 flash_addr, u32 size)
1269{
1270 u32 reg;
1271 u32 sector_addr;
1272
1273 reg = asd_ha->hw_prof.flash.bar;
1274
1275 /* sector staring address */
1276 sector_addr = flash_addr & FLASH_SECTOR_SIZE_MASK;
1277
1278 /*
1279 * Erasing an flash sector needs to be done in six consecutive
1280 * write cyles.
1281 */
1282 while (sector_addr < flash_addr+size) {
1283 switch (asd_ha->hw_prof.flash.method) {
1284 case FLASH_METHOD_A:
1285 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
1286 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
1287 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0x80);
1288 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
1289 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
1290 asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
1291 break;
1292 case FLASH_METHOD_B:
1293 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1294 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1295 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x80);
1296 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1297 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1298 asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
1299 break;
1300 default:
1301 break;
1302 }
1303
1304 if (asd_chk_write_status(asd_ha, sector_addr, 1) != 0)
1305 return FAIL_ERASE_FLASH;
1306
1307 sector_addr += FLASH_SECTOR_SIZE;
1308 }
1309
1310 return 0;
1311}
1312
1313int asd_check_flash_type(struct asd_ha_struct *asd_ha)
1314{
1315 u8 manuf_id;
1316 u8 dev_id;
1317 u8 sec_prot;
1318 u32 inc;
1319 u32 reg;
1320 int err;
1321
1322 /* get Flash memory base address */
1323 reg = asd_ha->hw_prof.flash.bar;
1324
1325 /* Determine flash info */
1326 err = asd_reset_flash(asd_ha);
1327 if (err) {
1328 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1329 return err;
1330 }
1331
1332 asd_ha->hw_prof.flash.method = FLASH_METHOD_UNKNOWN;
1333 asd_ha->hw_prof.flash.manuf = FLASH_MANUF_ID_UNKNOWN;
1334 asd_ha->hw_prof.flash.dev_id = FLASH_DEV_ID_UNKNOWN;
1335
1336 /* Get flash info. This would most likely be AMD Am29LV family flash.
1337 * First try the sequence for word mode. It is the same as for
1338 * 008B (byte mode only), 160B (word mode) and 800D (word mode).
1339 */
1340 inc = asd_ha->hw_prof.flash.wide ? 2 : 1;
1341 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0xAA);
1342 asd_write_reg_byte(asd_ha, reg + 0x555, 0x55);
1343 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0x90);
1344 manuf_id = asd_read_reg_byte(asd_ha, reg);
1345 dev_id = asd_read_reg_byte(asd_ha, reg + inc);
1346 sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
1347 /* Get out of autoselect mode. */
1348 err = asd_reset_flash(asd_ha);
1349 if (err) {
1350 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1351 return err;
1352 }
1353 ASD_DPRINTK("Flash MethodA manuf_id(0x%x) dev_id(0x%x) "
1354 "sec_prot(0x%x)\n", manuf_id, dev_id, sec_prot);
1355 err = asd_reset_flash(asd_ha);
1356 if (err != 0)
1357 return err;
1358
1359 switch (manuf_id) {
1360 case FLASH_MANUF_ID_AMD:
1361 switch (sec_prot) {
1362 case FLASH_DEV_ID_AM29LV800DT:
1363 case FLASH_DEV_ID_AM29LV640MT:
1364 case FLASH_DEV_ID_AM29F800B:
1365 asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1366 break;
1367 default:
1368 break;
1369 }
1370 break;
1371 case FLASH_MANUF_ID_ST:
1372 switch (sec_prot) {
1373 case FLASH_DEV_ID_STM29W800DT:
1374 case FLASH_DEV_ID_STM29LV640:
1375 asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1376 break;
1377 default:
1378 break;
1379 }
1380 break;
1381 case FLASH_MANUF_ID_FUJITSU:
1382 switch (sec_prot) {
1383 case FLASH_DEV_ID_MBM29LV800TE:
1384 case FLASH_DEV_ID_MBM29DL800TA:
1385 asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1386 break;
1387 }
1388 break;
1389 case FLASH_MANUF_ID_MACRONIX:
1390 switch (sec_prot) {
1391 case FLASH_DEV_ID_MX29LV800BT:
1392 asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
1393 break;
1394 }
1395 break;
1396 }
1397
1398 if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN) {
1399 err = asd_reset_flash(asd_ha);
1400 if (err) {
1401 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1402 return err;
1403 }
1404
1405 /* Issue Unlock sequence for AM29LV008BT */
1406 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
1407 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
1408 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x90);
1409 manuf_id = asd_read_reg_byte(asd_ha, reg);
1410 dev_id = asd_read_reg_byte(asd_ha, reg + inc);
1411 sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
1412
1413 ASD_DPRINTK("Flash MethodB manuf_id(0x%x) dev_id(0x%x) sec_prot"
1414 "(0x%x)\n", manuf_id, dev_id, sec_prot);
1415
1416 err = asd_reset_flash(asd_ha);
1417 if (err != 0) {
1418 ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
1419 return err;
1420 }
1421
1422 switch (manuf_id) {
1423 case FLASH_MANUF_ID_AMD:
1424 switch (dev_id) {
1425 case FLASH_DEV_ID_AM29LV008BT:
1426 asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1427 break;
1428 default:
1429 break;
1430 }
1431 break;
1432 case FLASH_MANUF_ID_ST:
1433 switch (dev_id) {
1434 case FLASH_DEV_ID_STM29008:
1435 asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1436 break;
1437 default:
1438 break;
1439 }
1440 break;
1441 case FLASH_MANUF_ID_FUJITSU:
1442 switch (dev_id) {
1443 case FLASH_DEV_ID_MBM29LV008TA:
1444 asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1445 break;
1446 }
1447 break;
1448 case FLASH_MANUF_ID_INTEL:
1449 switch (dev_id) {
1450 case FLASH_DEV_ID_I28LV00TAT:
1451 asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1452 break;
1453 }
1454 break;
1455 case FLASH_MANUF_ID_MACRONIX:
1456 switch (dev_id) {
1457 case FLASH_DEV_ID_I28LV00TAT:
1458 asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
1459 break;
1460 }
1461 break;
1462 default:
1463 return FAIL_FIND_FLASH_ID;
1464 }
1465 }
1466
1467 if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN)
1468 return FAIL_FIND_FLASH_ID;
1469
1470 asd_ha->hw_prof.flash.manuf = manuf_id;
1471 asd_ha->hw_prof.flash.dev_id = dev_id;
1472 asd_ha->hw_prof.flash.sec_prot = sec_prot;
1473 return 0;
1474}