aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2008-09-12 00:22:49 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-03 12:46:17 -0400
commitc00d8994d91e51aa6b891ad0e877f66cc1011de2 (patch)
tree5c200c361fffd2d8ac48572b22db0c9cd8b55451
parent4b89258c7320bab4155b692e76ae9ffdd85e79be (diff)
[SCSI] qla2xxx: Add Flash Layout Table support.
The Flash Layout Table (FLT) present on many recent HBAs encodes flash usage information, organizes data stored into separate regions and presents the information uniformly to the driver. Use this information rather than using specific hard-coded values based on ISP type. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h8
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h45
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c242
7 files changed, 272 insertions, 44 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 866b0a8b83a1..0ddfe7106b3b 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -292,10 +292,11 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
292 valid = 0; 292 valid = 0;
293 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) 293 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
294 valid = 1; 294 valid = 1;
295 else if (start == (FA_BOOT_CODE_ADDR*4) || 295 else if (start == (ha->flt_region_boot * 4) ||
296 start == (FA_RISC_CODE_ADDR*4)) 296 start == (ha->flt_region_fw * 4))
297 valid = 1; 297 valid = 1;
298 else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4)) 298 else if (IS_QLA25XX(ha) &&
299 start == (ha->flt_region_vpd_nvram * 4))
299 valid = 1; 300 valid = 1;
300 if (!valid) { 301 if (!valid) {
301 qla_printk(KERN_WARNING, ha, 302 qla_printk(KERN_WARNING, ha,
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index d1160d229d10..880e71127b73 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2508,7 +2508,6 @@ typedef struct scsi_qla_host {
2508 uint64_t fce_wr, fce_rd; 2508 uint64_t fce_wr, fce_rd;
2509 struct mutex fce_mutex; 2509 struct mutex fce_mutex;
2510 2510
2511 uint32_t hw_event_start;
2512 uint32_t hw_event_ptr; 2511 uint32_t hw_event_ptr;
2513 uint32_t hw_event_pause_errors; 2512 uint32_t hw_event_pause_errors;
2514 2513
@@ -2554,6 +2553,13 @@ typedef struct scsi_qla_host {
2554 uint32_t fdt_unprotect_sec_cmd; 2553 uint32_t fdt_unprotect_sec_cmd;
2555 uint32_t fdt_protect_sec_cmd; 2554 uint32_t fdt_protect_sec_cmd;
2556 2555
2556 uint32_t flt_region_flt;
2557 uint32_t flt_region_fdt;
2558 uint32_t flt_region_boot;
2559 uint32_t flt_region_fw;
2560 uint32_t flt_region_vpd_nvram;
2561 uint32_t flt_region_hw_event;
2562
2557 /* Needed for BEACON */ 2563 /* Needed for BEACON */
2558 uint16_t beacon_blink_led; 2564 uint16_t beacon_blink_led;
2559 uint8_t beacon_color_state; 2565 uint8_t beacon_color_state;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index cf194517400d..2ec986bf8344 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -789,12 +789,16 @@ struct device_reg_24xx {
789#define FA_RISC_CODE_ADDR 0x20000 789#define FA_RISC_CODE_ADDR 0x20000
790#define FA_RISC_CODE_SEGMENTS 2 790#define FA_RISC_CODE_SEGMENTS 2
791 791
792#define FA_FLASH_DESCR_ADDR_24 0x11000
793#define FA_FLASH_LAYOUT_ADDR_24 0x11400
794
792#define FA_FW_AREA_ADDR 0x40000 795#define FA_FW_AREA_ADDR 0x40000
793#define FA_VPD_NVRAM_ADDR 0x48000 796#define FA_VPD_NVRAM_ADDR 0x48000
794#define FA_FEATURE_ADDR 0x4C000 797#define FA_FEATURE_ADDR 0x4C000
795#define FA_FLASH_DESCR_ADDR 0x50000 798#define FA_FLASH_DESCR_ADDR 0x50000
799#define FA_FLASH_LAYOUT_ADDR 0x50400
796#define FA_HW_EVENT0_ADDR 0x54000 800#define FA_HW_EVENT0_ADDR 0x54000
797#define FA_HW_EVENT1_ADDR 0x54200 801#define FA_HW_EVENT1_ADDR 0x54400
798#define FA_HW_EVENT_SIZE 0x200 802#define FA_HW_EVENT_SIZE 0x200
799#define FA_HW_EVENT_ENTRY_SIZE 4 803#define FA_HW_EVENT_ENTRY_SIZE 4
800/* 804/*
@@ -806,10 +810,6 @@ struct device_reg_24xx {
806#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023 810#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
807#define HW_EVENT_FLASH_FW_ERR 0xF024 811#define HW_EVENT_FLASH_FW_ERR 0xF024
808 812
809#define FA_BOOT_LOG_ADDR 0x58000
810#define FA_FW_DUMP0_ADDR 0x60000
811#define FA_FW_DUMP1_ADDR 0x70000
812
813 uint32_t flash_data; /* Flash/NVRAM BIOS data. */ 813 uint32_t flash_data; /* Flash/NVRAM BIOS data. */
814 814
815 uint32_t ctrl_status; /* Control/Status. */ 815 uint32_t ctrl_status; /* Control/Status. */
@@ -1203,6 +1203,41 @@ struct qla_fdt_layout {
1203 uint8_t unused2[65]; 1203 uint8_t unused2[65];
1204}; 1204};
1205 1205
1206/* Flash Layout Table ********************************************************/
1207
1208struct qla_flt_location {
1209 uint8_t sig[4];
1210 uint32_t start_lo;
1211 uint32_t start_hi;
1212 uint16_t unused;
1213 uint16_t checksum;
1214};
1215
1216struct qla_flt_header {
1217 uint16_t version;
1218 uint16_t length;
1219 uint16_t checksum;
1220 uint16_t unused;
1221};
1222
1223#define FLT_REG_FW 0x01
1224#define FLT_REG_BOOT_CODE 0x07
1225#define FLT_REG_VPD_0 0x14
1226#define FLT_REG_NVRAM_0 0x15
1227#define FLT_REG_VPD_1 0x16
1228#define FLT_REG_NVRAM_1 0x17
1229#define FLT_REG_FDT 0x1a
1230#define FLT_REG_FLT 0x1c
1231#define FLT_REG_HW_EVENT_0 0x1d
1232#define FLT_REG_HW_EVENT_1 0x1f
1233
1234struct qla_flt_region {
1235 uint32_t code;
1236 uint32_t size;
1237 uint32_t start;
1238 uint32_t end;
1239};
1240
1206/* 84XX Support **************************************************************/ 1241/* 84XX Support **************************************************************/
1207 1242
1208#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ 1243#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 0b156735e9a6..dbd9f93890e8 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -313,7 +313,7 @@ extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
313extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, 313extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
314 uint16_t, uint16_t); 314 uint16_t, uint16_t);
315 315
316extern void qla2xxx_get_flash_info(scsi_qla_host_t *); 316extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
317extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); 317extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
318 318
319/* 319/*
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 57f24df626d9..20847fb15bdb 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -83,6 +83,13 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
83 83
84 ha->isp_ops->reset_chip(ha); 84 ha->isp_ops->reset_chip(ha);
85 85
86 rval = qla2xxx_get_flash_info(ha);
87 if (rval) {
88 DEBUG2(printk("scsi(%ld): Unable to validate FLASH data.\n",
89 ha->host_no));
90 return (rval);
91 }
92
86 ha->isp_ops->get_flash_version(ha, ha->request_ring); 93 ha->isp_ops->get_flash_version(ha, ha->request_ring);
87 94
88 qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); 95 qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
@@ -109,7 +116,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
109 rval = qla2x00_setup_chip(ha); 116 rval = qla2x00_setup_chip(ha);
110 if (rval) 117 if (rval)
111 return (rval); 118 return (rval);
112 qla2xxx_get_flash_info(ha);
113 } 119 }
114 if (IS_QLA84XX(ha)) { 120 if (IS_QLA84XX(ha)) {
115 ha->cs84xx = qla84xx_get_chip(ha); 121 ha->cs84xx = qla84xx_get_chip(ha);
@@ -3751,7 +3757,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
3751 rval = QLA_SUCCESS; 3757 rval = QLA_SUCCESS;
3752 3758
3753 segments = FA_RISC_CODE_SEGMENTS; 3759 segments = FA_RISC_CODE_SEGMENTS;
3754 faddr = FA_RISC_CODE_ADDR; 3760 faddr = ha->flt_region_fw;
3755 dcode = (uint32_t *)ha->request_ring; 3761 dcode = (uint32_t *)ha->request_ring;
3756 *srisc_addr = 0; 3762 *srisc_addr = 0;
3757 3763
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 6d0f0e5f2827..c1ffc3070ebe 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1663,8 +1663,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1663 ha->gid_list_info_size = 8; 1663 ha->gid_list_info_size = 8;
1664 ha->optrom_size = OPTROM_SIZE_25XX; 1664 ha->optrom_size = OPTROM_SIZE_25XX;
1665 ha->isp_ops = &qla25xx_isp_ops; 1665 ha->isp_ops = &qla25xx_isp_ops;
1666 ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
1667 FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
1668 } 1666 }
1669 host->can_queue = ha->request_q_length + 128; 1667 host->can_queue = ha->request_q_length + 128;
1670 1668
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 1bca74474935..6de1e3bc62a8 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -543,23 +543,186 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
543 } 543 }
544} 544}
545 545
546void 546static int
547qla2xxx_get_flash_info(scsi_qla_host_t *ha) 547qla2xxx_find_flt_start(scsi_qla_host_t *ha, uint32_t *start)
548{
549 const char *loc, *locations[] = { "DEF", "PCI" };
550 uint32_t pcihdr, pcids;
551 uint32_t *dcode;
552 uint8_t *buf, *bcode, last_image;
553 uint16_t cnt, chksum, *wptr;
554 struct qla_flt_location *fltl;
555
556 /*
557 * FLT-location structure resides after the last PCI region.
558 */
559
560 /* Begin with sane defaults. */
561 loc = locations[0];
562 *start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
563 FA_FLASH_LAYOUT_ADDR;
564
565 /* Begin with first PCI expansion ROM header. */
566 buf = (uint8_t *)ha->request_ring;
567 dcode = (uint32_t *)ha->request_ring;
568 pcihdr = 0;
569 last_image = 1;
570 do {
571 /* Verify PCI expansion ROM header. */
572 qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20);
573 bcode = buf + (pcihdr % 4);
574 if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
575 goto end;
576
577 /* Locate PCI data structure. */
578 pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
579 qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20);
580 bcode = buf + (pcihdr % 4);
581
582 /* Validate signature of PCI data structure. */
583 if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
584 bcode[0x2] != 'I' || bcode[0x3] != 'R')
585 goto end;
586
587 last_image = bcode[0x15] & BIT_7;
588
589 /* Locate next PCI expansion ROM. */
590 pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
591 } while (!last_image);
592
593 /* Now verify FLT-location structure. */
594 fltl = (struct qla_flt_location *)ha->request_ring;
595 qla24xx_read_flash_data(ha, dcode, pcihdr >> 2,
596 sizeof(struct qla_flt_location) >> 2);
597 if (fltl->sig[0] != 'Q' || fltl->sig[1] != 'F' ||
598 fltl->sig[2] != 'L' || fltl->sig[3] != 'T')
599 goto end;
600
601 wptr = (uint16_t *)ha->request_ring;
602 cnt = sizeof(struct qla_flt_location) >> 1;
603 for (chksum = 0; cnt; cnt--)
604 chksum += le16_to_cpu(*wptr++);
605 if (chksum) {
606 qla_printk(KERN_ERR, ha,
607 "Inconsistent FLTL detected: checksum=0x%x.\n", chksum);
608 qla2x00_dump_buffer(buf, sizeof(struct qla_flt_location));
609 return QLA_FUNCTION_FAILED;
610 }
611
612 /* Good data. Use specified location. */
613 loc = locations[1];
614 *start = le16_to_cpu(fltl->start_hi) << 16 |
615 le16_to_cpu(fltl->start_lo);
616end:
617 DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
618 return QLA_SUCCESS;
619}
620
621static void
622qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr)
623{
624 const char *loc, *locations[] = { "DEF", "FLT" };
625 uint16_t *wptr;
626 uint16_t cnt, chksum;
627 uint32_t start;
628 struct qla_flt_header *flt;
629 struct qla_flt_region *region;
630
631 ha->flt_region_flt = flt_addr;
632 wptr = (uint16_t *)ha->request_ring;
633 flt = (struct qla_flt_header *)ha->request_ring;
634 region = (struct qla_flt_region *)&flt[1];
635 ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
636 flt_addr << 2, OPTROM_BURST_SIZE);
637 if (*wptr == __constant_cpu_to_le16(0xffff))
638 goto no_flash_data;
639 if (flt->version != __constant_cpu_to_le16(1)) {
640 DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported FLT detected: "
641 "version=0x%x length=0x%x checksum=0x%x.\n",
642 le16_to_cpu(flt->version), le16_to_cpu(flt->length),
643 le16_to_cpu(flt->checksum)));
644 goto no_flash_data;
645 }
646
647 cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1;
648 for (chksum = 0; cnt; cnt--)
649 chksum += le16_to_cpu(*wptr++);
650 if (chksum) {
651 DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FLT detected: "
652 "version=0x%x length=0x%x checksum=0x%x.\n",
653 le16_to_cpu(flt->version), le16_to_cpu(flt->length),
654 chksum));
655 goto no_flash_data;
656 }
657
658 loc = locations[1];
659 cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
660 for ( ; cnt; cnt--, region++) {
661 /* Store addresses as DWORD offsets. */
662 start = le32_to_cpu(region->start) >> 2;
663
664 DEBUG3(qla_printk(KERN_DEBUG, ha, "FLT[%02x]: start=0x%x "
665 "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
666 le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
667
668 switch (le32_to_cpu(region->code)) {
669 case FLT_REG_FW:
670 ha->flt_region_fw = start;
671 break;
672 case FLT_REG_BOOT_CODE:
673 ha->flt_region_boot = start;
674 break;
675 case FLT_REG_VPD_0:
676 ha->flt_region_vpd_nvram = start;
677 break;
678 case FLT_REG_FDT:
679 ha->flt_region_fdt = start;
680 break;
681 case FLT_REG_HW_EVENT_0:
682 if (!PCI_FUNC(ha->pdev->devfn))
683 ha->flt_region_hw_event = start;
684 break;
685 case FLT_REG_HW_EVENT_1:
686 if (PCI_FUNC(ha->pdev->devfn))
687 ha->flt_region_hw_event = start;
688 break;
689 }
690 }
691 goto done;
692
693no_flash_data:
694 /* Use hardcoded defaults. */
695 loc = locations[0];
696 ha->flt_region_fw = FA_RISC_CODE_ADDR;
697 ha->flt_region_boot = FA_BOOT_CODE_ADDR;
698 ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
699 ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
700 FA_FLASH_DESCR_ADDR;
701 ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ?
702 FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR;
703done:
704 DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
705 "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x.\n", loc,
706 ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
707 ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event));
708}
709
710static void
711qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
548{ 712{
549#define FLASH_BLK_SIZE_32K 0x8000 713#define FLASH_BLK_SIZE_32K 0x8000
550#define FLASH_BLK_SIZE_64K 0x10000 714#define FLASH_BLK_SIZE_64K 0x10000
715 const char *loc, *locations[] = { "MID", "FDT" };
551 uint16_t cnt, chksum; 716 uint16_t cnt, chksum;
552 uint16_t *wptr; 717 uint16_t *wptr;
553 struct qla_fdt_layout *fdt; 718 struct qla_fdt_layout *fdt;
554 uint8_t man_id, flash_id; 719 uint8_t man_id, flash_id;
555 720 uint16_t mid, fid;
556 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
557 return;
558 721
559 wptr = (uint16_t *)ha->request_ring; 722 wptr = (uint16_t *)ha->request_ring;
560 fdt = (struct qla_fdt_layout *)ha->request_ring; 723 fdt = (struct qla_fdt_layout *)ha->request_ring;
561 ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring, 724 ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
562 FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE); 725 ha->flt_region_fdt << 2, OPTROM_BURST_SIZE);
563 if (*wptr == __constant_cpu_to_le16(0xffff)) 726 if (*wptr == __constant_cpu_to_le16(0xffff))
564 goto no_flash_data; 727 goto no_flash_data;
565 if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || 728 if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' ||
@@ -577,7 +740,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
577 goto no_flash_data; 740 goto no_flash_data;
578 } 741 }
579 742
580 ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f; 743 loc = locations[1];
744 mid = le16_to_cpu(fdt->man_id);
745 fid = le16_to_cpu(fdt->id);
746 ha->fdt_odd_index = mid == 0x1f;
581 ha->fdt_wrt_disable = fdt->wrt_disable_bits; 747 ha->fdt_wrt_disable = fdt->wrt_disable_bits;
582 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); 748 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
583 ha->fdt_block_size = le32_to_cpu(fdt->block_size); 749 ha->fdt_block_size = le32_to_cpu(fdt->block_size);
@@ -588,16 +754,12 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
588 flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd): 754 flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
589 flash_conf_to_access_addr(0x0336); 755 flash_conf_to_access_addr(0x0336);
590 } 756 }
591 757 goto done;
592 DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
593 "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
594 le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
595 ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
596 ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
597 return;
598
599no_flash_data: 758no_flash_data:
759 loc = locations[0];
600 qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); 760 qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
761 mid = man_id;
762 fid = flash_id;
601 ha->fdt_wrt_disable = 0x9c; 763 ha->fdt_wrt_disable = 0x9c;
602 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8); 764 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
603 switch (man_id) { 765 switch (man_id) {
@@ -625,14 +787,33 @@ no_flash_data:
625 ha->fdt_block_size = FLASH_BLK_SIZE_64K; 787 ha->fdt_block_size = FLASH_BLK_SIZE_64K;
626 break; 788 break;
627 } 789 }
628 790done:
629 DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x " 791 DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
630 "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id, 792 "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
631 ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, 793 ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
632 ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, 794 ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
633 ha->fdt_block_size)); 795 ha->fdt_block_size));
634} 796}
635 797
798int
799qla2xxx_get_flash_info(scsi_qla_host_t *ha)
800{
801 int ret;
802 uint32_t flt_addr;
803
804 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
805 return QLA_SUCCESS;
806
807 ret = qla2xxx_find_flt_start(ha, &flt_addr);
808 if (ret != QLA_SUCCESS)
809 return ret;
810
811 qla2xxx_get_flt_info(ha, flt_addr);
812 qla2xxx_get_fdt_info(ha);
813
814 return QLA_SUCCESS;
815}
816
636static void 817static void
637qla24xx_unprotect_flash(scsi_qla_host_t *ha) 818qla24xx_unprotect_flash(scsi_qla_host_t *ha)
638{ 819{
@@ -920,7 +1101,8 @@ qla25xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
920 dwptr = (uint32_t *)buf; 1101 dwptr = (uint32_t *)buf;
921 for (i = 0; i < bytes >> 2; i++, naddr++) 1102 for (i = 0; i < bytes >> 2; i++, naddr++)
922 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, 1103 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
923 flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr))); 1104 flash_data_to_access_addr(ha->flt_region_vpd_nvram |
1105 naddr)));
924 1106
925 return buf; 1107 return buf;
926} 1108}
@@ -935,10 +1117,10 @@ qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
935 dbuf = vmalloc(RMW_BUFFER_SIZE); 1117 dbuf = vmalloc(RMW_BUFFER_SIZE);
936 if (!dbuf) 1118 if (!dbuf)
937 return QLA_MEMORY_ALLOC_FAILED; 1119 return QLA_MEMORY_ALLOC_FAILED;
938 ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, 1120 ha->isp_ops->read_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
939 RMW_BUFFER_SIZE); 1121 RMW_BUFFER_SIZE);
940 memcpy(dbuf + (naddr << 2), buf, bytes); 1122 memcpy(dbuf + (naddr << 2), buf, bytes);
941 ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, 1123 ha->isp_ops->write_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
942 RMW_BUFFER_SIZE); 1124 RMW_BUFFER_SIZE);
943 vfree(dbuf); 1125 vfree(dbuf);
944 1126
@@ -2166,7 +2348,7 @@ qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
2166 memset(dbyte, 0, 8); 2348 memset(dbyte, 0, 8);
2167 dcode = (uint16_t *)dbyte; 2349 dcode = (uint16_t *)dbyte;
2168 2350
2169 qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10, 2351 qla2x00_read_flash_data(ha, dbyte, ha->flt_region_fw * 4 + 10,
2170 8); 2352 8);
2171 DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n", 2353 DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n",
2172 __func__, ha->host_no)); 2354 __func__, ha->host_no));
@@ -2177,7 +2359,7 @@ qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
2177 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && 2359 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
2178 dcode[3] == 0)) { 2360 dcode[3] == 0)) {
2179 DEBUG2(printk("%s(): Unrecognized fw revision at " 2361 DEBUG2(printk("%s(): Unrecognized fw revision at "
2180 "%x.\n", __func__, FA_RISC_CODE_ADDR * 4)); 2362 "%x.\n", __func__, ha->flt_region_fw * 4));
2181 } else { 2363 } else {
2182 /* values are in big endian */ 2364 /* values are in big endian */
2183 ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1]; 2365 ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1];
@@ -2212,7 +2394,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
2212 dcode = mbuf; 2394 dcode = mbuf;
2213 2395
2214 /* Begin with first PCI expansion ROM header. */ 2396 /* Begin with first PCI expansion ROM header. */
2215 pcihdr = 0; 2397 pcihdr = ha->flt_region_boot;
2216 last_image = 1; 2398 last_image = 1;
2217 do { 2399 do {
2218 /* Verify PCI expansion ROM header. */ 2400 /* Verify PCI expansion ROM header. */
@@ -2282,7 +2464,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
2282 memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); 2464 memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
2283 dcode = mbuf; 2465 dcode = mbuf;
2284 2466
2285 qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4); 2467 qla24xx_read_flash_data(ha, dcode, ha->flt_region_fw + 4, 4);
2286 for (i = 0; i < 4; i++) 2468 for (i = 0; i < 4; i++)
2287 dcode[i] = be32_to_cpu(dcode[i]); 2469 dcode[i] = be32_to_cpu(dcode[i]);
2288 2470
@@ -2291,7 +2473,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
2291 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && 2473 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
2292 dcode[3] == 0)) { 2474 dcode[3] == 0)) {
2293 DEBUG2(printk("%s(): Unrecognized fw version at %x.\n", 2475 DEBUG2(printk("%s(): Unrecognized fw version at %x.\n",
2294 __func__, FA_RISC_CODE_ADDR)); 2476 __func__, ha->flt_region_fw));
2295 } else { 2477 } else {
2296 ha->fw_revision[0] = dcode[0]; 2478 ha->fw_revision[0] = dcode[0];
2297 ha->fw_revision[1] = dcode[1]; 2479 ha->fw_revision[1] = dcode[1];
@@ -2355,7 +2537,7 @@ qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata)
2355 /* Locate first empty entry. */ 2537 /* Locate first empty entry. */
2356 for (;;) { 2538 for (;;) {
2357 if (ha->hw_event_ptr >= 2539 if (ha->hw_event_ptr >=
2358 ha->hw_event_start + FA_HW_EVENT_SIZE) { 2540 ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
2359 DEBUG2(qla_printk(KERN_WARNING, ha, 2541 DEBUG2(qla_printk(KERN_WARNING, ha,
2360 "HW event -- Log Full!\n")); 2542 "HW event -- Log Full!\n"));
2361 return QLA_MEMORY_ALLOC_FAILED; 2543 return QLA_MEMORY_ALLOC_FAILED;
@@ -2391,7 +2573,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
2391 int rval; 2573 int rval;
2392 uint32_t marker[2], fdata[4]; 2574 uint32_t marker[2], fdata[4];
2393 2575
2394 if (ha->hw_event_start == 0) 2576 if (ha->flt_region_hw_event == 0)
2395 return QLA_FUNCTION_FAILED; 2577 return QLA_FUNCTION_FAILED;
2396 2578
2397 DEBUG2(qla_printk(KERN_WARNING, ha, 2579 DEBUG2(qla_printk(KERN_WARNING, ha,
@@ -2406,7 +2588,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
2406 QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER); 2588 QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER);
2407 2589
2408 /* Locate marker. */ 2590 /* Locate marker. */
2409 ha->hw_event_ptr = ha->hw_event_start; 2591 ha->hw_event_ptr = ha->flt_region_hw_event;
2410 for (;;) { 2592 for (;;) {
2411 qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr, 2593 qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr,
2412 4); 2594 4);
@@ -2415,7 +2597,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
2415 break; 2597 break;
2416 ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; 2598 ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE;
2417 if (ha->hw_event_ptr >= 2599 if (ha->hw_event_ptr >=
2418 ha->hw_event_start + FA_HW_EVENT_SIZE) { 2600 ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
2419 DEBUG2(qla_printk(KERN_WARNING, ha, 2601 DEBUG2(qla_printk(KERN_WARNING, ha,
2420 "HW event -- Log Full!\n")); 2602 "HW event -- Log Full!\n"));
2421 return QLA_MEMORY_ALLOC_FAILED; 2603 return QLA_MEMORY_ALLOC_FAILED;