aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/probe_roms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/probe_roms.c')
-rw-r--r--drivers/scsi/isci/probe_roms.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index 64e9a808c814..0d968d3b334b 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -61,6 +61,11 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
61 61
62 len = pci_biosrom_size(pdev); 62 len = pci_biosrom_size(pdev);
63 rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL); 63 rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);
64 if (!rom) {
65 dev_warn(&pdev->dev,
66 "Unable to allocate memory for orom\n");
67 return NULL;
68 }
64 69
65 for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) { 70 for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) {
66 memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE); 71 memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE);
@@ -181,7 +186,11 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev)
181{ 186{
182 struct efi_variable *evar; 187 struct efi_variable *evar;
183 efi_status_t status; 188 efi_status_t status;
184 struct isci_orom *orom = NULL; 189 struct isci_orom *rom = NULL;
190 struct isci_oem_hdr *oem_hdr;
191 u8 *tmp, sum;
192 int j;
193 size_t copy_len;
185 194
186 evar = devm_kzalloc(&pdev->dev, 195 evar = devm_kzalloc(&pdev->dev,
187 sizeof(struct efi_variable), 196 sizeof(struct efi_variable),
@@ -192,6 +201,16 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev)
192 return NULL; 201 return NULL;
193 } 202 }
194 203
204 rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);
205 if (!rom) {
206 dev_warn(&pdev->dev,
207 "Unable to allocate memory for orom\n");
208 return NULL;
209 }
210
211 for (j = 0; j < strlen(ISCI_EFI_VAR_NAME) + 1; j++)
212 evar->VariableName[j] = ISCI_EFI_VAR_NAME[j];
213
195 evar->DataSize = 1024; 214 evar->DataSize = 1024;
196 evar->VendorGuid = ISCI_EFI_VENDOR_GUID; 215 evar->VendorGuid = ISCI_EFI_VENDOR_GUID;
197 evar->Attributes = ISCI_EFI_ATTRIBUTES; 216 evar->Attributes = ISCI_EFI_ATTRIBUTES;
@@ -205,19 +224,48 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev)
205 else 224 else
206 status = EFI_NOT_FOUND; 225 status = EFI_NOT_FOUND;
207 226
208 if (status == EFI_SUCCESS) 227 if (status != EFI_SUCCESS) {
209 orom = (struct isci_orom *)evar->Data;
210 else
211 dev_warn(&pdev->dev, 228 dev_warn(&pdev->dev,
212 "Unable to obtain EFI variable for OEM parms\n"); 229 "Unable to obtain EFI variable for OEM parms\n");
230 return NULL;
231 }
232
233 oem_hdr = (struct isci_oem_hdr *)evar->Data;
213 234
214 if (orom && memcmp(orom->hdr.signature, ISCI_ROM_SIG, 235 if (memcmp(oem_hdr->sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) != 0) {
215 strlen(ISCI_ROM_SIG)) != 0)
216 dev_warn(&pdev->dev, 236 dev_warn(&pdev->dev,
217 "Verifying OROM signature failed\n"); 237 "Invalid OEM header signature\n");
238 return NULL;
239 }
218 240
219 if (!orom) 241 /* calculate checksum */
220 devm_kfree(&pdev->dev, evar); 242 tmp = (u8 *)oem_hdr;
243 for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++)
244 sum += *tmp;
221 245
222 return orom; 246 tmp = (u8 *)rom;
247 for (j = 0; j < sizeof(*rom); j++, tmp++)
248 sum += *tmp;
249
250 if (sum != 0) {
251 dev_warn(&pdev->dev,
252 "OEM table checksum failed\n");
253 return NULL;
254 }
255
256 copy_len = min(evar->DataSize,
257 min(oem_hdr->len - sizeof(*oem_hdr),
258 sizeof(*rom)));
259
260 memcpy(rom, (char *)evar->Data + sizeof(*oem_hdr), copy_len);
261
262 if (memcmp(rom->hdr.signature,
263 ISCI_ROM_SIG,
264 ISCI_ROM_SIG_SIZE) != 0) {
265 dev_warn(&pdev->dev,
266 "Invalid OEM table signature\n");
267 return NULL;
268 }
269
270 return rom;
223} 271}