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/scsi/isci/probe_roms.c | |
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/scsi/isci/probe_roms.c')
-rw-r--r-- | drivers/scsi/isci/probe_roms.c | 48 |
1 files changed, 42 insertions, 6 deletions
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 | } |