aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/probe_roms.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-08 12:52:49 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:30 -0400
commitd044af17aacd03a1f4fced1af4b7570d205c8fd9 (patch)
tree1304fd0c7fa979fb229a4bf57771e9e6cde7b37d /drivers/scsi/isci/probe_roms.c
parent9affa289e2f9ef4721e85edbde86466524bfe957 (diff)
isci: Add support for probing OROM for OEM params
We need to scan the OROM for signature and grab the OEM parameters. We also need to do the same for EFI. If all fails then we resort to user binary blob, and if that fails then we go to the defaults. Share the format with the create_fw utility so that all possible sources of the parameters are in-sync. 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.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
new file mode 100644
index 000000000000..0b90e7c546c0
--- /dev/null
+++ b/drivers/scsi/isci/probe_roms.c
@@ -0,0 +1,133 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 */
24
25/* probe_roms - scan for oem parameters */
26
27#include <linux/kernel.h>
28#include <linux/firmware.h>
29#include <linux/uaccess.h>
30#include <asm/probe_roms.h>
31
32#include "isci.h"
33#include "task.h"
34#include "sci_controller_constants.h"
35#include "scic_remote_device.h"
36#include "sci_environment.h"
37#include "probe_roms.h"
38
39struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
40{
41 void __iomem *oprom = pci_map_biosrom(pdev);
42 struct isci_orom *rom = NULL;
43 size_t len, i;
44
45 if (!oprom)
46 return NULL;
47
48 len = pci_biosrom_size(pdev);
49 rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);
50
51 for (i = 0; i < len && rom; i += ISCI_ROM_SIG_SIZE) {
52 memcpy_fromio(rom->hdr.signature, oprom + i, ISCI_ROM_SIG_SIZE);
53 if (memcmp(rom->hdr.signature, ISCI_ROM_SIG,
54 ISCI_ROM_SIG_SIZE) == 0) {
55 size_t copy_len = min(len - i, sizeof(*rom));
56
57 memcpy_fromio(rom, oprom + i, copy_len);
58 break;
59 }
60 }
61
62 if (i >= len) {
63 dev_err(&pdev->dev, "oprom parse error\n");
64 devm_kfree(&pdev->dev, rom);
65 rom = NULL;
66 }
67 pci_unmap_biosrom(oprom);
68
69 return rom;
70}
71
72/**
73 * isci_parse_oem_parameters() - This method will take OEM parameters
74 * from the module init parameters and copy them to oem_params. This will
75 * only copy values that are not set to the module parameter default values
76 * @oem_parameters: This parameter specifies the controller default OEM
77 * parameters. It is expected that this has been initialized to the default
78 * parameters for the controller
79 *
80 *
81 */
82enum sci_status isci_parse_oem_parameters(union scic_oem_parameters *oem_params,
83 struct isci_orom *orom, int scu_index)
84{
85 int i;
86
87 /* check for valid inputs */
88 if (!(scu_index >= 0
89 && scu_index < SCI_MAX_CONTROLLERS
90 && oem_params != NULL))
91 return -EINVAL;
92
93 for (i = 0; i < SCI_MAX_PHYS; i++) {
94 oem_params->sds1.phys[i].sas_address.low =
95 orom->ctrl[scu_index].phys[i].sas_address.low;
96 oem_params->sds1.phys[i].sas_address.high =
97 orom->ctrl[scu_index].phys[i].sas_address.high;
98 }
99
100 for (i = 0; i < SCI_MAX_PORTS; i++)
101 oem_params->sds1.ports[i].phy_mask =
102 orom->ctrl[scu_index].ports[i].phy_mask;
103
104 return 0;
105}
106
107struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw)
108{
109 struct isci_orom *orom = NULL, *data;
110
111 if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0)
112 return NULL;
113
114 if (fw->size < sizeof(*orom))
115 goto out;
116
117 data = (struct isci_orom *)fw->data;
118
119 if (strncmp(ISCI_ROM_SIG, data->hdr.signature,
120 strlen(ISCI_ROM_SIG)) != 0)
121 goto out;
122
123 orom = devm_kzalloc(&pdev->dev, fw->size, GFP_KERNEL);
124 if (!orom)
125 goto out;
126
127 memcpy(orom, fw->data, fw->size);
128
129 out:
130 release_firmware(fw);
131
132 return orom;
133}