diff options
author | Dave Jiang <dave.jiang@intel.com> | 2011-05-25 01:04:35 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:50 -0400 |
commit | bf482c6069b514b7fe57a048ae1b6f11cf3bb10c (patch) | |
tree | 0630cb34b500867fe362dcb610a2ea3b1e44c6ea /drivers/scsi | |
parent | 77d67385f7b4a630912fd567f104946be137f477 (diff) |
isci: Retrieve the EFI variable for OEM parameter
We can call the EFI get_variable service routine directly to retrieve
the EFI variable that holds the OEM parameters table.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/isci/probe_roms.c | 73 | ||||
-rw-r--r-- | drivers/scsi/isci/probe_roms.h | 2 |
2 files changed, 24 insertions, 51 deletions
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c index 9bc173fa49e1..084fdc60548f 100644 --- a/drivers/scsi/isci/probe_roms.c +++ b/drivers/scsi/isci/probe_roms.c | |||
@@ -34,14 +34,8 @@ | |||
34 | #include "task.h" | 34 | #include "task.h" |
35 | #include "probe_roms.h" | 35 | #include "probe_roms.h" |
36 | 36 | ||
37 | struct efi_variable { | 37 | static efi_char16_t isci_efivar_name[] = |
38 | efi_char16_t VariableName[1024/sizeof(efi_char16_t)]; | 38 | {'R', 's', 't', 'S', 'c', 'u', 'O'}; |
39 | efi_guid_t VendorGuid; | ||
40 | unsigned long DataSize; | ||
41 | __u8 Data[1024]; | ||
42 | efi_status_t Status; | ||
43 | __u32 Attributes; | ||
44 | } __attribute__((packed)); | ||
45 | 39 | ||
46 | struct isci_orom *isci_request_oprom(struct pci_dev *pdev) | 40 | struct isci_orom *isci_request_oprom(struct pci_dev *pdev) |
47 | { | 41 | { |
@@ -169,62 +163,50 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw | |||
169 | 163 | ||
170 | static struct efi *get_efi(void) | 164 | static struct efi *get_efi(void) |
171 | { | 165 | { |
172 | #ifdef CONFIG_EFI | 166 | #ifdef CONFIG_EFI |
173 | return &efi; | 167 | return &efi; |
174 | #else | 168 | #else |
175 | return NULL; | 169 | return NULL; |
176 | #endif | 170 | #endif |
177 | } | 171 | } |
178 | 172 | ||
179 | struct isci_orom *isci_get_efi_var(struct pci_dev *pdev) | 173 | struct isci_orom *isci_get_efi_var(struct pci_dev *pdev) |
180 | { | 174 | { |
181 | struct efi_variable *evar; | ||
182 | efi_status_t status; | 175 | efi_status_t status; |
183 | struct isci_orom *rom = NULL; | 176 | struct isci_orom *rom; |
184 | struct isci_oem_hdr *oem_hdr; | 177 | struct isci_oem_hdr *oem_hdr; |
185 | u8 *tmp, sum; | 178 | u8 *tmp, sum; |
186 | int j; | 179 | int j; |
187 | size_t copy_len; | 180 | ssize_t data_len; |
181 | u8 *efi_data; | ||
182 | u32 efi_attrib = 0; | ||
188 | 183 | ||
189 | evar = devm_kzalloc(&pdev->dev, | 184 | data_len = 1024; |
190 | sizeof(struct efi_variable), | 185 | efi_data = devm_kzalloc(&pdev->dev, data_len, GFP_KERNEL); |
191 | GFP_KERNEL); | 186 | if (!efi_data) { |
192 | if (!evar) { | ||
193 | dev_warn(&pdev->dev, | 187 | dev_warn(&pdev->dev, |
194 | "Unable to allocate memory for EFI var\n"); | 188 | "Unable to allocate memory for EFI data\n"); |
195 | return NULL; | 189 | return NULL; |
196 | } | 190 | } |
197 | 191 | ||
198 | rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL); | 192 | rom = (struct isci_orom *)(efi_data + sizeof(struct isci_oem_hdr)); |
199 | if (!rom) { | ||
200 | dev_warn(&pdev->dev, | ||
201 | "Unable to allocate memory for orom\n"); | ||
202 | return NULL; | ||
203 | } | ||
204 | |||
205 | for (j = 0; j < strlen(ISCI_EFI_VAR_NAME) + 1; j++) | ||
206 | evar->VariableName[j] = ISCI_EFI_VAR_NAME[j]; | ||
207 | |||
208 | evar->DataSize = 1024; | ||
209 | evar->VendorGuid = ISCI_EFI_VENDOR_GUID; | ||
210 | evar->Attributes = ISCI_EFI_ATTRIBUTES; | ||
211 | 193 | ||
212 | if (get_efi()) | 194 | if (get_efi()) |
213 | status = get_efi()->get_variable(evar->VariableName, | 195 | status = get_efi()->get_variable(isci_efivar_name, |
214 | &evar->VendorGuid, | 196 | &ISCI_EFI_VENDOR_GUID, |
215 | &evar->Attributes, | 197 | &efi_attrib, |
216 | &evar->DataSize, | 198 | &data_len, |
217 | evar->Data); | 199 | efi_data); |
218 | else | 200 | else |
219 | status = EFI_NOT_FOUND; | 201 | status = EFI_NOT_FOUND; |
220 | 202 | ||
221 | if (status != EFI_SUCCESS) { | 203 | if (status != EFI_SUCCESS) { |
222 | dev_warn(&pdev->dev, | 204 | dev_warn(&pdev->dev, |
223 | "Unable to obtain EFI variable for OEM parms\n"); | 205 | "Unable to obtain EFI var data for OEM parms\n"); |
224 | return NULL; | 206 | return NULL; |
225 | } | 207 | } |
226 | 208 | ||
227 | oem_hdr = (struct isci_oem_hdr *)evar->Data; | 209 | oem_hdr = (struct isci_oem_hdr *)efi_data; |
228 | 210 | ||
229 | if (memcmp(oem_hdr->sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) != 0) { | 211 | if (memcmp(oem_hdr->sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) != 0) { |
230 | dev_warn(&pdev->dev, | 212 | dev_warn(&pdev->dev, |
@@ -233,12 +215,8 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev) | |||
233 | } | 215 | } |
234 | 216 | ||
235 | /* calculate checksum */ | 217 | /* calculate checksum */ |
236 | tmp = (u8 *)oem_hdr; | 218 | tmp = (u8 *)efi_data; |
237 | for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++) | 219 | for (j = 0, sum = 0; j < (sizeof(*oem_hdr) + sizeof(*rom)); j++, tmp++) |
238 | sum += *tmp; | ||
239 | |||
240 | tmp = (u8 *)rom; | ||
241 | for (j = 0; j < sizeof(*rom); j++, tmp++) | ||
242 | sum += *tmp; | 220 | sum += *tmp; |
243 | 221 | ||
244 | if (sum != 0) { | 222 | if (sum != 0) { |
@@ -247,11 +225,6 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev) | |||
247 | return NULL; | 225 | return NULL; |
248 | } | 226 | } |
249 | 227 | ||
250 | copy_len = min_t(u16, evar->DataSize, | ||
251 | min_t(u16, oem_hdr->len - sizeof(*oem_hdr), sizeof(*rom))); | ||
252 | |||
253 | memcpy(rom, (char *)evar->Data + sizeof(*oem_hdr), copy_len); | ||
254 | |||
255 | if (memcmp(rom->hdr.signature, | 228 | if (memcmp(rom->hdr.signature, |
256 | ISCI_ROM_SIG, | 229 | ISCI_ROM_SIG, |
257 | ISCI_ROM_SIG_SIZE) != 0) { | 230 | ISCI_ROM_SIG_SIZE) != 0) { |
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h index 7e3e6d7a0a47..95c8d91aab8d 100644 --- a/drivers/scsi/isci/probe_roms.h +++ b/drivers/scsi/isci/probe_roms.h | |||
@@ -58,6 +58,7 @@ | |||
58 | #ifdef __KERNEL__ | 58 | #ifdef __KERNEL__ |
59 | #include <linux/firmware.h> | 59 | #include <linux/firmware.h> |
60 | #include <linux/pci.h> | 60 | #include <linux/pci.h> |
61 | #include <linux/efi.h> | ||
61 | #include "isci.h" | 62 | #include "isci.h" |
62 | 63 | ||
63 | #define SCIC_SDS_PARM_NO_SPEED 0 | 64 | #define SCIC_SDS_PARM_NO_SPEED 0 |
@@ -202,7 +203,6 @@ struct isci_oem_hdr { | |||
202 | #define ISCI_EFI_VENDOR_GUID \ | 203 | #define ISCI_EFI_VENDOR_GUID \ |
203 | EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, \ | 204 | EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, \ |
204 | 0x1a, 0x04, 0xc6) | 205 | 0x1a, 0x04, 0xc6) |
205 | #define ISCI_EFI_ATTRIBUTES 0 | ||
206 | #define ISCI_EFI_VAR_NAME "RstScuO" | 206 | #define ISCI_EFI_VAR_NAME "RstScuO" |
207 | 207 | ||
208 | /* Allowed PORT configuration modes APC Automatic PORT configuration mode is | 208 | /* Allowed PORT configuration modes APC Automatic PORT configuration mode is |