diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-08 12:53:51 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:31 -0400 |
commit | 3b67c1f376acb24b7c6679f75275ac5a96792986 (patch) | |
tree | 1d9db0ca797010ee7998dde4eb62c3bc3b878526 /drivers | |
parent | 02839a8b51002d90e4b7c52bf37531834b063f71 (diff) |
isci: fixup with testing from isci OROM in BIOS
Added fixups for the OROM parsing code after testing with BIOS OROM
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/init.c | 7 | ||||
-rw-r--r-- | drivers/scsi/isci/probe_roms.c | 48 | ||||
-rw-r--r-- | drivers/scsi/isci/probe_roms.h | 13 |
3 files changed, 60 insertions, 8 deletions
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 13105294fbea..ef0c49a0c0a0 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c | |||
@@ -495,8 +495,11 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic | |||
495 | } | 495 | } |
496 | 496 | ||
497 | if (orom) | 497 | if (orom) |
498 | dev_info(&pdev->dev, "sas parameters (version: %#x) loaded\n", | 498 | dev_info(&pdev->dev, |
499 | orom->hdr.version); | 499 | "OEM SAS parameters (version: %u.%u) loaded\n", |
500 | (orom->hdr.version & 0xf0) >> 4, | ||
501 | (orom->hdr.version & 0xf)); | ||
502 | |||
500 | pci_info->orom = orom; | 503 | pci_info->orom = orom; |
501 | 504 | ||
502 | err = isci_pci_init(pdev); | 505 | err = isci_pci_init(pdev); |
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c index 822240578115..64e9a808c814 100644 --- a/drivers/scsi/isci/probe_roms.c +++ b/drivers/scsi/isci/probe_roms.c | |||
@@ -51,6 +51,10 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev) | |||
51 | void __iomem *oprom = pci_map_biosrom(pdev); | 51 | void __iomem *oprom = pci_map_biosrom(pdev); |
52 | struct isci_orom *rom = NULL; | 52 | struct isci_orom *rom = NULL; |
53 | size_t len, i; | 53 | size_t len, i; |
54 | int j; | ||
55 | char oem_sig[4]; | ||
56 | struct isci_oem_hdr oem_hdr; | ||
57 | u8 *tmp, sum; | ||
54 | 58 | ||
55 | if (!oprom) | 59 | if (!oprom) |
56 | return NULL; | 60 | return NULL; |
@@ -58,13 +62,45 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev) | |||
58 | len = pci_biosrom_size(pdev); | 62 | len = pci_biosrom_size(pdev); |
59 | rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL); | 63 | rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL); |
60 | 64 | ||
61 | for (i = 0; i < len && rom; i += ISCI_ROM_SIG_SIZE) { | 65 | for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) { |
62 | memcpy_fromio(rom->hdr.signature, oprom + i, ISCI_ROM_SIG_SIZE); | 66 | memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE); |
63 | if (memcmp(rom->hdr.signature, ISCI_ROM_SIG, | ||
64 | ISCI_ROM_SIG_SIZE) == 0) { | ||
65 | size_t copy_len = min(len - i, sizeof(*rom)); | ||
66 | 67 | ||
67 | memcpy_fromio(rom, oprom + i, copy_len); | 68 | /* we think we found the OEM table */ |
69 | if (memcmp(oem_sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) == 0) { | ||
70 | size_t copy_len; | ||
71 | |||
72 | memcpy_fromio(&oem_hdr, oprom + i, sizeof(oem_hdr)); | ||
73 | |||
74 | copy_len = min(oem_hdr.len - sizeof(oem_hdr), | ||
75 | sizeof(*rom)); | ||
76 | |||
77 | memcpy_fromio(rom, | ||
78 | oprom + i + sizeof(oem_hdr), | ||
79 | copy_len); | ||
80 | |||
81 | /* calculate checksum */ | ||
82 | tmp = (u8 *)&oem_hdr; | ||
83 | for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++) | ||
84 | sum += *tmp; | ||
85 | |||
86 | tmp = (u8 *)rom; | ||
87 | for (j = 0; j < sizeof(*rom); j++, tmp++) | ||
88 | sum += *tmp; | ||
89 | |||
90 | if (sum != 0) { | ||
91 | dev_warn(&pdev->dev, | ||
92 | "OEM table checksum failed\n"); | ||
93 | continue; | ||
94 | } | ||
95 | |||
96 | /* keep going if that's not the oem param table */ | ||
97 | if (memcmp(rom->hdr.signature, | ||
98 | ISCI_ROM_SIG, | ||
99 | ISCI_ROM_SIG_SIZE) != 0) | ||
100 | continue; | ||
101 | |||
102 | dev_info(&pdev->dev, | ||
103 | "OEM parameter table found in OROM\n"); | ||
68 | break; | 104 | break; |
69 | } | 105 | } |
70 | } | 106 | } |
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h index 02940e709f97..0449239dae45 100644 --- a/drivers/scsi/isci/probe_roms.h +++ b/drivers/scsi/isci/probe_roms.h | |||
@@ -70,6 +70,17 @@ enum sci_status isci_parse_oem_parameters( | |||
70 | int scu_index); | 70 | int scu_index); |
71 | struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw); | 71 | struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw); |
72 | struct isci_orom *isci_get_efi_var(struct pci_dev *pdev); | 72 | struct isci_orom *isci_get_efi_var(struct pci_dev *pdev); |
73 | |||
74 | struct isci_oem_hdr { | ||
75 | u8 sig[4]; | ||
76 | u8 rev_major; | ||
77 | u8 rev_minor; | ||
78 | u16 len; | ||
79 | u8 checksum; | ||
80 | u8 reserved1; | ||
81 | u16 reserved2; | ||
82 | } __attribute__ ((packed)); | ||
83 | |||
73 | #else | 84 | #else |
74 | #define SCI_MAX_PORTS 4 | 85 | #define SCI_MAX_PORTS 4 |
75 | #define SCI_MAX_PHYS 4 | 86 | #define SCI_MAX_PHYS 4 |
@@ -80,6 +91,8 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev); | |||
80 | 91 | ||
81 | #define ROMSIGNATURE 0xaa55 | 92 | #define ROMSIGNATURE 0xaa55 |
82 | 93 | ||
94 | #define ISCI_OEM_SIG "$OEM" | ||
95 | #define ISCI_OEM_SIG_SIZE 4 | ||
83 | #define ISCI_ROM_SIG "ISCUOEMB" | 96 | #define ISCI_ROM_SIG "ISCUOEMB" |
84 | #define ISCI_ROM_SIG_SIZE 8 | 97 | #define ISCI_ROM_SIG_SIZE 8 |
85 | 98 | ||