Skip to content

Commit

Permalink
isci: fixup with testing from isci OROM in BIOS
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent 02839a8 commit 3b67c1f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
7 changes: 5 additions & 2 deletions drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,11 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
}

if (orom)
dev_info(&pdev->dev, "sas parameters (version: %#x) loaded\n",
orom->hdr.version);
dev_info(&pdev->dev,
"OEM SAS parameters (version: %u.%u) loaded\n",
(orom->hdr.version & 0xf0) >> 4,
(orom->hdr.version & 0xf));

pci_info->orom = orom;

err = isci_pci_init(pdev);
Expand Down
48 changes: 42 additions & 6 deletions drivers/scsi/isci/probe_roms.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,56 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
void __iomem *oprom = pci_map_biosrom(pdev);
struct isci_orom *rom = NULL;
size_t len, i;
int j;
char oem_sig[4];
struct isci_oem_hdr oem_hdr;
u8 *tmp, sum;

if (!oprom)
return NULL;

len = pci_biosrom_size(pdev);
rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);

for (i = 0; i < len && rom; i += ISCI_ROM_SIG_SIZE) {
memcpy_fromio(rom->hdr.signature, oprom + i, ISCI_ROM_SIG_SIZE);
if (memcmp(rom->hdr.signature, ISCI_ROM_SIG,
ISCI_ROM_SIG_SIZE) == 0) {
size_t copy_len = min(len - i, sizeof(*rom));
for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) {
memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE);

memcpy_fromio(rom, oprom + i, copy_len);
/* we think we found the OEM table */
if (memcmp(oem_sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) == 0) {
size_t copy_len;

memcpy_fromio(&oem_hdr, oprom + i, sizeof(oem_hdr));

copy_len = min(oem_hdr.len - sizeof(oem_hdr),
sizeof(*rom));

memcpy_fromio(rom,
oprom + i + sizeof(oem_hdr),
copy_len);

/* calculate checksum */
tmp = (u8 *)&oem_hdr;
for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++)
sum += *tmp;

tmp = (u8 *)rom;
for (j = 0; j < sizeof(*rom); j++, tmp++)
sum += *tmp;

if (sum != 0) {
dev_warn(&pdev->dev,
"OEM table checksum failed\n");
continue;
}

/* keep going if that's not the oem param table */
if (memcmp(rom->hdr.signature,
ISCI_ROM_SIG,
ISCI_ROM_SIG_SIZE) != 0)
continue;

dev_info(&pdev->dev,
"OEM parameter table found in OROM\n");
break;
}
}
Expand Down
13 changes: 13 additions & 0 deletions drivers/scsi/isci/probe_roms.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ enum sci_status isci_parse_oem_parameters(
int scu_index);
struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw);
struct isci_orom *isci_get_efi_var(struct pci_dev *pdev);

struct isci_oem_hdr {
u8 sig[4];
u8 rev_major;
u8 rev_minor;
u16 len;
u8 checksum;
u8 reserved1;
u16 reserved2;
} __attribute__ ((packed));

#else
#define SCI_MAX_PORTS 4
#define SCI_MAX_PHYS 4
Expand All @@ -80,6 +91,8 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev);

#define ROMSIGNATURE 0xaa55

#define ISCI_OEM_SIG "$OEM"
#define ISCI_OEM_SIG_SIZE 4
#define ISCI_ROM_SIG "ISCUOEMB"
#define ISCI_ROM_SIG_SIZE 8

Expand Down

0 comments on commit 3b67c1f

Please sign in to comment.