Commit | Line | Data |
---|---|---|
f92363d1 SR |
1 | /* |
2 | * This module provides common API for accessing firmware configuration pages | |
3 | * | |
4 | * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c | |
a4ffce0d | 5 | * Copyright (C) 2012-2014 LSI Corporation |
a03bd153 SR |
6 | * Copyright (C) 2013-2014 Avago Technologies |
7 | * (mailto: MPT-FusionLinux.pdl@avagotech.com) | |
f92363d1 SR |
8 | * |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License | |
11 | * as published by the Free Software Foundation; either version 2 | |
12 | * of the License, or (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * NO WARRANTY | |
20 | * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR | |
21 | * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT | |
22 | * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, | |
23 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is | |
24 | * solely responsible for determining the appropriateness of using and | |
25 | * distributing the Program and assumes all risks associated with its | |
26 | * exercise of rights under this Agreement, including but not limited to | |
27 | * the risks and costs of program errors, damage to or loss of data, | |
28 | * programs or equipment, and unavailability or interruption of operations. | |
29 | ||
30 | * DISCLAIMER OF LIABILITY | |
31 | * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY | |
32 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
33 | * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND | |
34 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | |
35 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | |
36 | * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED | |
37 | * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES | |
38 | ||
39 | * You should have received a copy of the GNU General Public License | |
40 | * along with this program; if not, write to the Free Software | |
41 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | |
42 | * USA. | |
43 | */ | |
44 | ||
f92363d1 SR |
45 | #include <linux/module.h> |
46 | #include <linux/kernel.h> | |
47 | #include <linux/init.h> | |
48 | #include <linux/errno.h> | |
49 | #include <linux/blkdev.h> | |
50 | #include <linux/sched.h> | |
51 | #include <linux/workqueue.h> | |
52 | #include <linux/delay.h> | |
53 | #include <linux/pci.h> | |
54 | ||
55 | #include "mpt3sas_base.h" | |
56 | ||
57 | /* local definitions */ | |
58 | ||
59 | /* Timeout for config page request (in seconds) */ | |
60 | #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15 | |
61 | ||
62 | /* Common sgl flags for READING a config page. */ | |
63 | #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ | |
64 | MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ | |
65 | | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT) | |
66 | ||
67 | /* Common sgl flags for WRITING a config page. */ | |
68 | #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ | |
69 | MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ | |
70 | | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \ | |
71 | << MPI2_SGE_FLAGS_SHIFT) | |
72 | ||
73 | /** | |
74 | * struct config_request - obtain dma memory via routine | |
75 | * @sz: size | |
76 | * @page: virt pointer | |
77 | * @page_dma: phys pointer | |
78 | * | |
79 | */ | |
80 | struct config_request { | |
81 | u16 sz; | |
82 | void *page; | |
83 | dma_addr_t page_dma; | |
84 | }; | |
85 | ||
f92363d1 SR |
86 | /** |
87 | * _config_display_some_debug - debug routine | |
88 | * @ioc: per adapter object | |
89 | * @smid: system request message index | |
90 | * @calling_function_name: string pass from calling function | |
91 | * @mpi_reply: reply message frame | |
92 | * Context: none. | |
93 | * | |
94 | * Function for displaying debug info helpful when debugging issues | |
95 | * in this module. | |
96 | */ | |
97 | static void | |
98 | _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, | |
99 | char *calling_function_name, MPI2DefaultReply_t *mpi_reply) | |
100 | { | |
101 | Mpi2ConfigRequest_t *mpi_request; | |
102 | char *desc = NULL; | |
103 | ||
104 | if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) | |
105 | return; | |
106 | ||
107 | mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); | |
108 | switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) { | |
109 | case MPI2_CONFIG_PAGETYPE_IO_UNIT: | |
110 | desc = "io_unit"; | |
111 | break; | |
112 | case MPI2_CONFIG_PAGETYPE_IOC: | |
113 | desc = "ioc"; | |
114 | break; | |
115 | case MPI2_CONFIG_PAGETYPE_BIOS: | |
116 | desc = "bios"; | |
117 | break; | |
118 | case MPI2_CONFIG_PAGETYPE_RAID_VOLUME: | |
119 | desc = "raid_volume"; | |
120 | break; | |
121 | case MPI2_CONFIG_PAGETYPE_MANUFACTURING: | |
8700bc76 | 122 | desc = "manufacturing"; |
f92363d1 SR |
123 | break; |
124 | case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK: | |
125 | desc = "physdisk"; | |
126 | break; | |
127 | case MPI2_CONFIG_PAGETYPE_EXTENDED: | |
128 | switch (mpi_request->ExtPageType) { | |
129 | case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT: | |
130 | desc = "sas_io_unit"; | |
131 | break; | |
132 | case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER: | |
133 | desc = "sas_expander"; | |
134 | break; | |
135 | case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE: | |
136 | desc = "sas_device"; | |
137 | break; | |
138 | case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY: | |
139 | desc = "sas_phy"; | |
140 | break; | |
141 | case MPI2_CONFIG_EXTPAGETYPE_LOG: | |
142 | desc = "log"; | |
143 | break; | |
144 | case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE: | |
145 | desc = "enclosure"; | |
146 | break; | |
147 | case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG: | |
148 | desc = "raid_config"; | |
149 | break; | |
150 | case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: | |
07f42258 | 151 | desc = "driver_mapping"; |
f92363d1 | 152 | break; |
c102e00c SPS |
153 | case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT: |
154 | desc = "sas_port"; | |
155 | break; | |
156 | case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING: | |
157 | desc = "ext_manufacturing"; | |
158 | break; | |
159 | case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT: | |
160 | desc = "pcie_io_unit"; | |
161 | break; | |
162 | case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH: | |
163 | desc = "pcie_switch"; | |
164 | break; | |
165 | case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE: | |
166 | desc = "pcie_device"; | |
167 | break; | |
168 | case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK: | |
169 | desc = "pcie_link"; | |
170 | break; | |
f92363d1 SR |
171 | } |
172 | break; | |
173 | } | |
174 | ||
175 | if (!desc) | |
176 | return; | |
177 | ||
919d8a3f JP |
178 | ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n", |
179 | calling_function_name, desc, | |
180 | mpi_request->Header.PageNumber, mpi_request->Action, | |
181 | le32_to_cpu(mpi_request->PageAddress), smid); | |
f92363d1 SR |
182 | |
183 | if (!mpi_reply) | |
184 | return; | |
185 | ||
186 | if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) | |
919d8a3f JP |
187 | ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n", |
188 | le16_to_cpu(mpi_reply->IOCStatus), | |
189 | le32_to_cpu(mpi_reply->IOCLogInfo)); | |
f92363d1 | 190 | } |
f92363d1 SR |
191 | |
192 | /** | |
193 | * _config_alloc_config_dma_memory - obtain physical memory | |
194 | * @ioc: per adapter object | |
195 | * @mem: struct config_request | |
196 | * | |
197 | * A wrapper for obtaining dma-able memory for config page request. | |
198 | * | |
4beb4867 | 199 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
200 | */ |
201 | static int | |
202 | _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, | |
203 | struct config_request *mem) | |
204 | { | |
205 | int r = 0; | |
206 | ||
207 | if (mem->sz > ioc->config_page_sz) { | |
208 | mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz, | |
209 | &mem->page_dma, GFP_KERNEL); | |
210 | if (!mem->page) { | |
919d8a3f JP |
211 | ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n", |
212 | __func__, mem->sz); | |
f92363d1 SR |
213 | r = -ENOMEM; |
214 | } | |
215 | } else { /* use tmp buffer if less than 512 bytes */ | |
216 | mem->page = ioc->config_page; | |
217 | mem->page_dma = ioc->config_page_dma; | |
218 | } | |
182ac784 | 219 | ioc->config_vaddr = mem->page; |
f92363d1 SR |
220 | return r; |
221 | } | |
222 | ||
223 | /** | |
224 | * _config_free_config_dma_memory - wrapper to free the memory | |
225 | * @ioc: per adapter object | |
226 | * @mem: struct config_request | |
227 | * | |
228 | * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory. | |
229 | * | |
4beb4867 | 230 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
231 | */ |
232 | static void | |
233 | _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, | |
234 | struct config_request *mem) | |
235 | { | |
236 | if (mem->sz > ioc->config_page_sz) | |
237 | dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page, | |
238 | mem->page_dma); | |
239 | } | |
240 | ||
241 | /** | |
242 | * mpt3sas_config_done - config page completion routine | |
243 | * @ioc: per adapter object | |
244 | * @smid: system request message index | |
245 | * @msix_index: MSIX table index supplied by the OS | |
246 | * @reply: reply message frame(lower 32bit addr) | |
247 | * Context: none. | |
248 | * | |
249 | * The callback handler when using _config_request. | |
250 | * | |
4beb4867 BVA |
251 | * Return: 1 meaning mf should be freed from _base_interrupt |
252 | * 0 means the mf is freed from this function. | |
f92363d1 SR |
253 | */ |
254 | u8 | |
255 | mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |
256 | u32 reply) | |
257 | { | |
258 | MPI2DefaultReply_t *mpi_reply; | |
259 | ||
260 | if (ioc->config_cmds.status == MPT3_CMD_NOT_USED) | |
261 | return 1; | |
262 | if (ioc->config_cmds.smid != smid) | |
263 | return 1; | |
264 | ioc->config_cmds.status |= MPT3_CMD_COMPLETE; | |
265 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); | |
266 | if (mpi_reply) { | |
267 | ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID; | |
268 | memcpy(ioc->config_cmds.reply, mpi_reply, | |
269 | mpi_reply->MsgLength*4); | |
270 | } | |
271 | ioc->config_cmds.status &= ~MPT3_CMD_PENDING; | |
f92363d1 | 272 | _config_display_some_debug(ioc, smid, "config_done", mpi_reply); |
f92363d1 SR |
273 | ioc->config_cmds.smid = USHRT_MAX; |
274 | complete(&ioc->config_cmds.done); | |
275 | return 1; | |
276 | } | |
277 | ||
278 | /** | |
279 | * _config_request - main routine for sending config page requests | |
280 | * @ioc: per adapter object | |
281 | * @mpi_request: request message frame | |
282 | * @mpi_reply: reply mf payload returned from firmware | |
283 | * @timeout: timeout in seconds | |
284 | * @config_page: contents of the config page | |
285 | * @config_page_sz: size of config page | |
286 | * Context: sleep | |
287 | * | |
288 | * A generic API for config page requests to firmware. | |
289 | * | |
290 | * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling | |
291 | * this API. | |
292 | * | |
293 | * The callback index is set inside `ioc->config_cb_idx. | |
294 | * | |
4beb4867 | 295 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
296 | */ |
297 | static int | |
298 | _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |
299 | *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout, | |
300 | void *config_page, u16 config_page_sz) | |
301 | { | |
302 | u16 smid; | |
f92363d1 SR |
303 | Mpi2ConfigRequest_t *config_request; |
304 | int r; | |
305 | u8 retry_count, issue_host_reset = 0; | |
f92363d1 SR |
306 | struct config_request mem; |
307 | u32 ioc_status = UINT_MAX; | |
308 | ||
309 | mutex_lock(&ioc->config_cmds.mutex); | |
310 | if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { | |
919d8a3f | 311 | ioc_err(ioc, "%s: config_cmd in use\n", __func__); |
f92363d1 SR |
312 | mutex_unlock(&ioc->config_cmds.mutex); |
313 | return -EAGAIN; | |
314 | } | |
315 | ||
316 | retry_count = 0; | |
317 | memset(&mem, 0, sizeof(struct config_request)); | |
318 | ||
319 | mpi_request->VF_ID = 0; /* TODO */ | |
320 | mpi_request->VP_ID = 0; | |
321 | ||
322 | if (config_page) { | |
323 | mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion; | |
324 | mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber; | |
325 | mpi_request->Header.PageType = mpi_reply->Header.PageType; | |
326 | mpi_request->Header.PageLength = mpi_reply->Header.PageLength; | |
327 | mpi_request->ExtPageLength = mpi_reply->ExtPageLength; | |
328 | mpi_request->ExtPageType = mpi_reply->ExtPageType; | |
329 | if (mpi_request->Header.PageLength) | |
330 | mem.sz = mpi_request->Header.PageLength * 4; | |
331 | else | |
332 | mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4; | |
333 | r = _config_alloc_config_dma_memory(ioc, &mem); | |
334 | if (r != 0) | |
335 | goto out; | |
336 | if (mpi_request->Action == | |
337 | MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || | |
338 | mpi_request->Action == | |
339 | MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { | |
340 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, | |
341 | MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, | |
342 | mem.page_dma); | |
343 | memcpy(mem.page, config_page, min_t(u16, mem.sz, | |
344 | config_page_sz)); | |
345 | } else { | |
346 | memset(config_page, 0, config_page_sz); | |
347 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, | |
348 | MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma); | |
349 | memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz)); | |
350 | } | |
351 | } | |
352 | ||
353 | retry_config: | |
354 | if (retry_count) { | |
355 | if (retry_count > 2) { /* attempt only 2 retries */ | |
356 | r = -EFAULT; | |
357 | goto free_mem; | |
358 | } | |
919d8a3f JP |
359 | ioc_info(ioc, "%s: attempting retry (%d)\n", |
360 | __func__, retry_count); | |
f92363d1 | 361 | } |
f4305749 SP |
362 | |
363 | r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT); | |
364 | if (r) | |
365 | goto free_mem; | |
f92363d1 SR |
366 | |
367 | smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx); | |
368 | if (!smid) { | |
919d8a3f | 369 | ioc_err(ioc, "%s: failed obtaining a smid\n", __func__); |
f92363d1 SR |
370 | ioc->config_cmds.status = MPT3_CMD_NOT_USED; |
371 | r = -EAGAIN; | |
372 | goto free_mem; | |
373 | } | |
374 | ||
375 | r = 0; | |
376 | memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t)); | |
377 | ioc->config_cmds.status = MPT3_CMD_PENDING; | |
378 | config_request = mpt3sas_base_get_msg_frame(ioc, smid); | |
379 | ioc->config_cmds.smid = smid; | |
380 | memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); | |
f92363d1 | 381 | _config_display_some_debug(ioc, smid, "config_request", NULL); |
f92363d1 | 382 | init_completion(&ioc->config_cmds.done); |
078a4cc1 | 383 | ioc->put_smid_default(ioc, smid); |
8bbb1cf6 | 384 | wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ); |
f92363d1 | 385 | if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { |
d37306ca C |
386 | mpt3sas_base_check_cmd_timeout(ioc, |
387 | ioc->config_cmds.status, mpi_request, | |
388 | sizeof(Mpi2ConfigRequest_t)/4); | |
f92363d1 SR |
389 | retry_count++; |
390 | if (ioc->config_cmds.smid == smid) | |
391 | mpt3sas_base_free_smid(ioc, smid); | |
392 | if ((ioc->shost_recovery) || (ioc->config_cmds.status & | |
393 | MPT3_CMD_RESET) || ioc->pci_error_recovery) | |
394 | goto retry_config; | |
395 | issue_host_reset = 1; | |
396 | r = -EFAULT; | |
397 | goto free_mem; | |
398 | } | |
399 | ||
400 | if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) { | |
401 | memcpy(mpi_reply, ioc->config_cmds.reply, | |
402 | sizeof(Mpi2ConfigReply_t)); | |
403 | ||
404 | /* Reply Frame Sanity Checks to workaround FW issues */ | |
405 | if ((mpi_request->Header.PageType & 0xF) != | |
406 | (mpi_reply->Header.PageType & 0xF)) { | |
407 | _debug_dump_mf(mpi_request, ioc->request_sz/4); | |
408 | _debug_dump_reply(mpi_reply, ioc->request_sz/4); | |
506f7f6b JP |
409 | panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", |
410 | ioc->name, __func__, | |
411 | mpi_request->Header.PageType & 0xF, | |
412 | mpi_reply->Header.PageType & 0xF); | |
f92363d1 SR |
413 | } |
414 | ||
415 | if (((mpi_request->Header.PageType & 0xF) == | |
416 | MPI2_CONFIG_PAGETYPE_EXTENDED) && | |
417 | mpi_request->ExtPageType != mpi_reply->ExtPageType) { | |
418 | _debug_dump_mf(mpi_request, ioc->request_sz/4); | |
419 | _debug_dump_reply(mpi_reply, ioc->request_sz/4); | |
506f7f6b JP |
420 | panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", |
421 | ioc->name, __func__, | |
422 | mpi_request->ExtPageType, | |
423 | mpi_reply->ExtPageType); | |
f92363d1 SR |
424 | } |
425 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus) | |
426 | & MPI2_IOCSTATUS_MASK; | |
427 | } | |
428 | ||
429 | if (retry_count) | |
919d8a3f JP |
430 | ioc_info(ioc, "%s: retry (%d) completed!!\n", |
431 | __func__, retry_count); | |
f92363d1 SR |
432 | |
433 | if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && | |
434 | config_page && mpi_request->Action == | |
435 | MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) { | |
436 | u8 *p = (u8 *)mem.page; | |
437 | ||
438 | /* Config Page Sanity Checks to workaround FW issues */ | |
439 | if (p) { | |
440 | if ((mpi_request->Header.PageType & 0xF) != | |
441 | (p[3] & 0xF)) { | |
442 | _debug_dump_mf(mpi_request, ioc->request_sz/4); | |
443 | _debug_dump_reply(mpi_reply, ioc->request_sz/4); | |
444 | _debug_dump_config(p, min_t(u16, mem.sz, | |
445 | config_page_sz)/4); | |
506f7f6b JP |
446 | panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", |
447 | ioc->name, __func__, | |
448 | mpi_request->Header.PageType & 0xF, | |
449 | p[3] & 0xF); | |
f92363d1 SR |
450 | } |
451 | ||
452 | if (((mpi_request->Header.PageType & 0xF) == | |
453 | MPI2_CONFIG_PAGETYPE_EXTENDED) && | |
454 | (mpi_request->ExtPageType != p[6])) { | |
455 | _debug_dump_mf(mpi_request, ioc->request_sz/4); | |
456 | _debug_dump_reply(mpi_reply, ioc->request_sz/4); | |
457 | _debug_dump_config(p, min_t(u16, mem.sz, | |
458 | config_page_sz)/4); | |
506f7f6b JP |
459 | panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", |
460 | ioc->name, __func__, | |
461 | mpi_request->ExtPageType, p[6]); | |
f92363d1 SR |
462 | } |
463 | } | |
464 | memcpy(config_page, mem.page, min_t(u16, mem.sz, | |
465 | config_page_sz)); | |
466 | } | |
467 | ||
468 | free_mem: | |
469 | if (config_page) | |
470 | _config_free_config_dma_memory(ioc, &mem); | |
471 | out: | |
472 | ioc->config_cmds.status = MPT3_CMD_NOT_USED; | |
473 | mutex_unlock(&ioc->config_cmds.mutex); | |
474 | ||
475 | if (issue_host_reset) | |
98c56ad3 | 476 | mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); |
f92363d1 SR |
477 | return r; |
478 | } | |
479 | ||
480 | /** | |
481 | * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0 | |
482 | * @ioc: per adapter object | |
483 | * @mpi_reply: reply mf payload returned from firmware | |
484 | * @config_page: contents of the config page | |
485 | * Context: sleep. | |
486 | * | |
4beb4867 | 487 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
488 | */ |
489 | int | |
490 | mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, | |
491 | Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page) | |
492 | { | |
493 | Mpi2ConfigRequest_t mpi_request; | |
494 | int r; | |
495 | ||
496 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
497 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
498 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
499 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; | |
500 | mpi_request.Header.PageNumber = 0; | |
501 | mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; | |
502 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
503 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
504 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
505 | if (r) | |
506 | goto out; | |
507 | ||
508 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
509 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
510 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
511 | sizeof(*config_page)); | |
512 | out: | |
513 | return r; | |
514 | } | |
515 | ||
516 | /** | |
517 | * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 | |
518 | * @ioc: per adapter object | |
519 | * @mpi_reply: reply mf payload returned from firmware | |
520 | * @config_page: contents of the config page | |
521 | * @sz: size of buffer passed in config_page | |
522 | * Context: sleep. | |
523 | * | |
4beb4867 | 524 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
525 | */ |
526 | int | |
527 | mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, | |
528 | Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, | |
529 | u16 sz) | |
530 | { | |
531 | Mpi2ConfigRequest_t mpi_request; | |
532 | int r; | |
533 | ||
534 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
535 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
536 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
537 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; | |
538 | mpi_request.Header.PageNumber = 7; | |
539 | mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION; | |
540 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
541 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
542 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
543 | if (r) | |
544 | goto out; | |
545 | ||
546 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
547 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
548 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
549 | sz); | |
550 | out: | |
551 | return r; | |
552 | } | |
553 | ||
554 | /** | |
555 | * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10 | |
556 | * @ioc: per adapter object | |
557 | * @mpi_reply: reply mf payload returned from firmware | |
558 | * @config_page: contents of the config page | |
559 | * Context: sleep. | |
560 | * | |
4beb4867 | 561 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
562 | */ |
563 | int | |
564 | mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, | |
565 | Mpi2ConfigReply_t *mpi_reply, | |
566 | struct Mpi2ManufacturingPage10_t *config_page) | |
567 | { | |
568 | Mpi2ConfigRequest_t mpi_request; | |
569 | int r; | |
570 | ||
571 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
572 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
573 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
574 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; | |
575 | mpi_request.Header.PageNumber = 10; | |
576 | mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; | |
577 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
578 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
579 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
580 | if (r) | |
581 | goto out; | |
582 | ||
583 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
584 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
585 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
586 | sizeof(*config_page)); | |
587 | out: | |
588 | return r; | |
589 | } | |
590 | ||
591 | /** | |
592 | * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 | |
593 | * @ioc: per adapter object | |
594 | * @mpi_reply: reply mf payload returned from firmware | |
595 | * @config_page: contents of the config page | |
596 | * Context: sleep. | |
597 | * | |
4beb4867 | 598 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
599 | */ |
600 | int | |
601 | mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, | |
602 | Mpi2ConfigReply_t *mpi_reply, | |
603 | struct Mpi2ManufacturingPage11_t *config_page) | |
604 | { | |
605 | Mpi2ConfigRequest_t mpi_request; | |
606 | int r; | |
607 | ||
608 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
609 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
610 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
611 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; | |
612 | mpi_request.Header.PageNumber = 11; | |
613 | mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; | |
614 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
615 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
616 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
617 | if (r) | |
618 | goto out; | |
619 | ||
620 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
621 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
622 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
623 | sizeof(*config_page)); | |
624 | out: | |
625 | return r; | |
626 | } | |
627 | ||
628 | /** | |
629 | * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11 | |
630 | * @ioc: per adapter object | |
631 | * @mpi_reply: reply mf payload returned from firmware | |
632 | * @config_page: contents of the config page | |
633 | * Context: sleep. | |
634 | * | |
4beb4867 | 635 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
636 | */ |
637 | int | |
638 | mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, | |
639 | Mpi2ConfigReply_t *mpi_reply, | |
640 | struct Mpi2ManufacturingPage11_t *config_page) | |
641 | { | |
642 | Mpi2ConfigRequest_t mpi_request; | |
643 | int r; | |
644 | ||
645 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
646 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
647 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
648 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; | |
649 | mpi_request.Header.PageNumber = 11; | |
650 | mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; | |
651 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
652 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
653 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
654 | if (r) | |
655 | goto out; | |
656 | ||
657 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; | |
658 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
659 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
660 | sizeof(*config_page)); | |
f92363d1 SR |
661 | out: |
662 | return r; | |
663 | } | |
664 | ||
665 | /** | |
666 | * mpt3sas_config_get_bios_pg2 - obtain bios page 2 | |
667 | * @ioc: per adapter object | |
668 | * @mpi_reply: reply mf payload returned from firmware | |
669 | * @config_page: contents of the config page | |
670 | * Context: sleep. | |
671 | * | |
4beb4867 | 672 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
673 | */ |
674 | int | |
675 | mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, | |
676 | Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) | |
677 | { | |
678 | Mpi2ConfigRequest_t mpi_request; | |
679 | int r; | |
680 | ||
681 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
682 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
683 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
684 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; | |
685 | mpi_request.Header.PageNumber = 2; | |
686 | mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; | |
687 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
688 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
689 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
690 | if (r) | |
691 | goto out; | |
692 | ||
693 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
694 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
695 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
696 | sizeof(*config_page)); | |
697 | out: | |
698 | return r; | |
699 | } | |
700 | ||
701 | /** | |
702 | * mpt3sas_config_get_bios_pg3 - obtain bios page 3 | |
703 | * @ioc: per adapter object | |
704 | * @mpi_reply: reply mf payload returned from firmware | |
705 | * @config_page: contents of the config page | |
706 | * Context: sleep. | |
707 | * | |
4beb4867 | 708 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
709 | */ |
710 | int | |
711 | mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
712 | *mpi_reply, Mpi2BiosPage3_t *config_page) | |
713 | { | |
714 | Mpi2ConfigRequest_t mpi_request; | |
715 | int r; | |
716 | ||
717 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
718 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
719 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
720 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; | |
721 | mpi_request.Header.PageNumber = 3; | |
722 | mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; | |
723 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
724 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
725 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
726 | if (r) | |
727 | goto out; | |
728 | ||
729 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
730 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
731 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
732 | sizeof(*config_page)); | |
733 | out: | |
734 | return r; | |
735 | } | |
736 | ||
737 | /** | |
738 | * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0 | |
739 | * @ioc: per adapter object | |
740 | * @mpi_reply: reply mf payload returned from firmware | |
741 | * @config_page: contents of the config page | |
742 | * Context: sleep. | |
743 | * | |
4beb4867 | 744 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
745 | */ |
746 | int | |
747 | mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, | |
748 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) | |
749 | { | |
750 | Mpi2ConfigRequest_t mpi_request; | |
751 | int r; | |
752 | ||
753 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
754 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
755 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
756 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; | |
757 | mpi_request.Header.PageNumber = 0; | |
758 | mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; | |
759 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
760 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
761 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
762 | if (r) | |
763 | goto out; | |
764 | ||
765 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
766 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
767 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
768 | sizeof(*config_page)); | |
769 | out: | |
770 | return r; | |
771 | } | |
772 | ||
773 | /** | |
774 | * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1 | |
775 | * @ioc: per adapter object | |
776 | * @mpi_reply: reply mf payload returned from firmware | |
777 | * @config_page: contents of the config page | |
778 | * Context: sleep. | |
779 | * | |
4beb4867 | 780 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
781 | */ |
782 | int | |
783 | mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, | |
784 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) | |
785 | { | |
786 | Mpi2ConfigRequest_t mpi_request; | |
787 | int r; | |
788 | ||
789 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
790 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
791 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
792 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; | |
793 | mpi_request.Header.PageNumber = 1; | |
794 | mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; | |
795 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
796 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
797 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
798 | if (r) | |
799 | goto out; | |
800 | ||
801 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
802 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
803 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
804 | sizeof(*config_page)); | |
805 | out: | |
806 | return r; | |
807 | } | |
808 | ||
809 | /** | |
810 | * mpt3sas_config_set_iounit_pg1 - set iounit page 1 | |
811 | * @ioc: per adapter object | |
812 | * @mpi_reply: reply mf payload returned from firmware | |
813 | * @config_page: contents of the config page | |
814 | * Context: sleep. | |
815 | * | |
4beb4867 | 816 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
817 | */ |
818 | int | |
819 | mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, | |
820 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) | |
821 | { | |
822 | Mpi2ConfigRequest_t mpi_request; | |
823 | int r; | |
824 | ||
825 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
826 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
827 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
828 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; | |
829 | mpi_request.Header.PageNumber = 1; | |
830 | mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; | |
831 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
832 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
833 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
834 | if (r) | |
835 | goto out; | |
836 | ||
837 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; | |
838 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
839 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
840 | sizeof(*config_page)); | |
841 | out: | |
842 | return r; | |
843 | } | |
844 | ||
42263095 SR |
845 | /** |
846 | * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3 | |
847 | * @ioc: per adapter object | |
848 | * @mpi_reply: reply mf payload returned from firmware | |
849 | * @config_page: contents of the config page | |
850 | * @sz: size of buffer passed in config_page | |
851 | * Context: sleep. | |
852 | * | |
4beb4867 | 853 | * Return: 0 for success, non-zero for failure. |
42263095 SR |
854 | */ |
855 | int | |
856 | mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, | |
857 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) | |
858 | { | |
859 | Mpi2ConfigRequest_t mpi_request; | |
860 | int r; | |
861 | ||
862 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
863 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
864 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
865 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; | |
866 | mpi_request.Header.PageNumber = 3; | |
867 | mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; | |
868 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
869 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
870 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
871 | if (r) | |
872 | goto out; | |
873 | ||
874 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
875 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
876 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
877 | out: | |
878 | return r; | |
879 | } | |
42263095 | 880 | |
2d8ce8c9 SR |
881 | /** |
882 | * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 | |
883 | * @ioc: per adapter object | |
884 | * @mpi_reply: reply mf payload returned from firmware | |
885 | * @config_page: contents of the config page | |
886 | * Context: sleep. | |
887 | * | |
4beb4867 | 888 | * Return: 0 for success, non-zero for failure. |
2d8ce8c9 SR |
889 | */ |
890 | int | |
891 | mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, | |
892 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) | |
893 | { | |
894 | Mpi2ConfigRequest_t mpi_request; | |
895 | int r; | |
896 | ||
897 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
898 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
899 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
900 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; | |
901 | mpi_request.Header.PageNumber = 8; | |
902 | mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; | |
903 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
904 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
905 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
906 | if (r) | |
907 | goto out; | |
908 | ||
909 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
910 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
911 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
912 | sizeof(*config_page)); | |
913 | out: | |
914 | return r; | |
915 | } | |
916 | ||
f92363d1 SR |
917 | /** |
918 | * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8 | |
919 | * @ioc: per adapter object | |
920 | * @mpi_reply: reply mf payload returned from firmware | |
921 | * @config_page: contents of the config page | |
922 | * Context: sleep. | |
923 | * | |
4beb4867 | 924 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
925 | */ |
926 | int | |
927 | mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, | |
928 | Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) | |
929 | { | |
930 | Mpi2ConfigRequest_t mpi_request; | |
931 | int r; | |
932 | ||
933 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
934 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
935 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
936 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; | |
937 | mpi_request.Header.PageNumber = 8; | |
938 | mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; | |
939 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
940 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
941 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
942 | if (r) | |
943 | goto out; | |
944 | ||
945 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
946 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
947 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
948 | sizeof(*config_page)); | |
949 | out: | |
950 | return r; | |
951 | } | |
952 | ||
953 | /** | |
954 | * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0 | |
955 | * @ioc: per adapter object | |
956 | * @mpi_reply: reply mf payload returned from firmware | |
957 | * @config_page: contents of the config page | |
958 | * @form: GET_NEXT_HANDLE or HANDLE | |
959 | * @handle: device handle | |
960 | * Context: sleep. | |
961 | * | |
4beb4867 | 962 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
963 | */ |
964 | int | |
965 | mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, | |
966 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, | |
967 | u32 form, u32 handle) | |
968 | { | |
969 | Mpi2ConfigRequest_t mpi_request; | |
970 | int r; | |
971 | ||
972 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
973 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
974 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
975 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
976 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; | |
977 | mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; | |
978 | mpi_request.Header.PageNumber = 0; | |
979 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
980 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
981 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
982 | if (r) | |
983 | goto out; | |
984 | ||
985 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
986 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
987 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
988 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
989 | sizeof(*config_page)); | |
990 | out: | |
991 | return r; | |
992 | } | |
993 | ||
994 | /** | |
995 | * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1 | |
996 | * @ioc: per adapter object | |
997 | * @mpi_reply: reply mf payload returned from firmware | |
998 | * @config_page: contents of the config page | |
999 | * @form: GET_NEXT_HANDLE or HANDLE | |
1000 | * @handle: device handle | |
1001 | * Context: sleep. | |
1002 | * | |
4beb4867 | 1003 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1004 | */ |
1005 | int | |
1006 | mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, | |
1007 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, | |
1008 | u32 form, u32 handle) | |
1009 | { | |
1010 | Mpi2ConfigRequest_t mpi_request; | |
1011 | int r; | |
1012 | ||
1013 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1014 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1015 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1016 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1017 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; | |
1018 | mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; | |
1019 | mpi_request.Header.PageNumber = 1; | |
1020 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1021 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1022 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1023 | if (r) | |
1024 | goto out; | |
1025 | ||
1026 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1027 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1028 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1029 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1030 | sizeof(*config_page)); | |
1031 | out: | |
1032 | return r; | |
1033 | } | |
1034 | ||
c102e00c SPS |
1035 | /** |
1036 | * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0 | |
1037 | * @ioc: per adapter object | |
1038 | * @mpi_reply: reply mf payload returned from firmware | |
1039 | * @config_page: contents of the config page | |
1040 | * @form: GET_NEXT_HANDLE or HANDLE | |
1041 | * @handle: device handle | |
1042 | * Context: sleep. | |
1043 | * | |
4beb4867 | 1044 | * Return: 0 for success, non-zero for failure. |
c102e00c SPS |
1045 | */ |
1046 | int | |
1047 | mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc, | |
1048 | Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, | |
1049 | u32 form, u32 handle) | |
1050 | { | |
1051 | Mpi2ConfigRequest_t mpi_request; | |
1052 | int r; | |
1053 | ||
1054 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1055 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1056 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1057 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1058 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; | |
1059 | mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION; | |
1060 | mpi_request.Header.PageNumber = 0; | |
1061 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1062 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1063 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1064 | if (r) | |
1065 | goto out; | |
1066 | ||
1067 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1068 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1069 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1070 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1071 | sizeof(*config_page)); | |
1072 | out: | |
1073 | return r; | |
1074 | } | |
1075 | ||
1076 | /** | |
1077 | * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 | |
1078 | * @ioc: per adapter object | |
1079 | * @mpi_reply: reply mf payload returned from firmware | |
1080 | * @config_page: contents of the config page | |
1081 | * @form: GET_NEXT_HANDLE or HANDLE | |
1082 | * @handle: device handle | |
1083 | * Context: sleep. | |
1084 | * | |
4beb4867 | 1085 | * Return: 0 for success, non-zero for failure. |
c102e00c SPS |
1086 | */ |
1087 | int | |
1088 | mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, | |
1089 | Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, | |
1090 | u32 form, u32 handle) | |
1091 | { | |
1092 | Mpi2ConfigRequest_t mpi_request; | |
1093 | int r; | |
1094 | ||
1095 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1096 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1097 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1098 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1099 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; | |
1100 | mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION; | |
1101 | mpi_request.Header.PageNumber = 2; | |
1102 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1103 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1104 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1105 | if (r) | |
1106 | goto out; | |
1107 | ||
1108 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1109 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1110 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1111 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1112 | sizeof(*config_page)); | |
1113 | out: | |
1114 | return r; | |
1115 | } | |
1116 | ||
f92363d1 SR |
1117 | /** |
1118 | * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host | |
1119 | * @ioc: per adapter object | |
1120 | * @num_phys: pointer returned with the number of phys | |
1121 | * Context: sleep. | |
1122 | * | |
4beb4867 | 1123 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1124 | */ |
1125 | int | |
1126 | mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) | |
1127 | { | |
1128 | Mpi2ConfigRequest_t mpi_request; | |
1129 | int r; | |
1130 | u16 ioc_status; | |
1131 | Mpi2ConfigReply_t mpi_reply; | |
1132 | Mpi2SasIOUnitPage0_t config_page; | |
1133 | ||
1134 | *num_phys = 0; | |
1135 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1136 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1137 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1138 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1139 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | |
1140 | mpi_request.Header.PageNumber = 0; | |
1141 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; | |
1142 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1143 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1144 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1145 | if (r) | |
1146 | goto out; | |
1147 | ||
1148 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1149 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1150 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, | |
1151 | sizeof(Mpi2SasIOUnitPage0_t)); | |
1152 | if (!r) { | |
1153 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | |
1154 | MPI2_IOCSTATUS_MASK; | |
1155 | if (ioc_status == MPI2_IOCSTATUS_SUCCESS) | |
1156 | *num_phys = config_page.NumPhys; | |
1157 | } | |
1158 | out: | |
1159 | return r; | |
1160 | } | |
1161 | ||
1162 | /** | |
1163 | * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 | |
1164 | * @ioc: per adapter object | |
1165 | * @mpi_reply: reply mf payload returned from firmware | |
1166 | * @config_page: contents of the config page | |
1167 | * @sz: size of buffer passed in config_page | |
1168 | * Context: sleep. | |
1169 | * | |
1170 | * Calling function should call config_get_number_hba_phys prior to | |
1171 | * this function, so enough memory is allocated for config_page. | |
1172 | * | |
4beb4867 | 1173 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1174 | */ |
1175 | int | |
1176 | mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, | |
1177 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, | |
1178 | u16 sz) | |
1179 | { | |
1180 | Mpi2ConfigRequest_t mpi_request; | |
1181 | int r; | |
1182 | ||
1183 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1184 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1185 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1186 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1187 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | |
1188 | mpi_request.Header.PageNumber = 0; | |
1189 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; | |
1190 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1191 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1192 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1193 | if (r) | |
1194 | goto out; | |
1195 | ||
1196 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1197 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1198 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
1199 | out: | |
1200 | return r; | |
1201 | } | |
1202 | ||
1203 | /** | |
1204 | * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 | |
1205 | * @ioc: per adapter object | |
1206 | * @mpi_reply: reply mf payload returned from firmware | |
1207 | * @config_page: contents of the config page | |
1208 | * @sz: size of buffer passed in config_page | |
1209 | * Context: sleep. | |
1210 | * | |
1211 | * Calling function should call config_get_number_hba_phys prior to | |
1212 | * this function, so enough memory is allocated for config_page. | |
1213 | * | |
4beb4867 | 1214 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1215 | */ |
1216 | int | |
1217 | mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, | |
1218 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, | |
1219 | u16 sz) | |
1220 | { | |
1221 | Mpi2ConfigRequest_t mpi_request; | |
1222 | int r; | |
1223 | ||
1224 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1225 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1226 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1227 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1228 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | |
1229 | mpi_request.Header.PageNumber = 1; | |
1230 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; | |
1231 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1232 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1233 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1234 | if (r) | |
1235 | goto out; | |
1236 | ||
1237 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1238 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1239 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
1240 | out: | |
1241 | return r; | |
1242 | } | |
1243 | ||
1244 | /** | |
1245 | * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1 | |
1246 | * @ioc: per adapter object | |
1247 | * @mpi_reply: reply mf payload returned from firmware | |
1248 | * @config_page: contents of the config page | |
1249 | * @sz: size of buffer passed in config_page | |
1250 | * Context: sleep. | |
1251 | * | |
1252 | * Calling function should call config_get_number_hba_phys prior to | |
1253 | * this function, so enough memory is allocated for config_page. | |
1254 | * | |
4beb4867 | 1255 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1256 | */ |
1257 | int | |
1258 | mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, | |
1259 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, | |
1260 | u16 sz) | |
1261 | { | |
1262 | Mpi2ConfigRequest_t mpi_request; | |
1263 | int r; | |
1264 | ||
1265 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1266 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1267 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1268 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1269 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | |
1270 | mpi_request.Header.PageNumber = 1; | |
1271 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; | |
1272 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1273 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1274 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1275 | if (r) | |
1276 | goto out; | |
1277 | ||
1278 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; | |
1279 | _config_request(ioc, &mpi_request, mpi_reply, | |
1280 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
1281 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; | |
1282 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1283 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
1284 | out: | |
1285 | return r; | |
1286 | } | |
1287 | ||
1288 | /** | |
1289 | * mpt3sas_config_get_expander_pg0 - obtain expander page 0 | |
1290 | * @ioc: per adapter object | |
1291 | * @mpi_reply: reply mf payload returned from firmware | |
1292 | * @config_page: contents of the config page | |
1293 | * @form: GET_NEXT_HANDLE or HANDLE | |
1294 | * @handle: expander handle | |
1295 | * Context: sleep. | |
1296 | * | |
4beb4867 | 1297 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1298 | */ |
1299 | int | |
1300 | mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1301 | *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) | |
1302 | { | |
1303 | Mpi2ConfigRequest_t mpi_request; | |
1304 | int r; | |
1305 | ||
1306 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1307 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1308 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1309 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1310 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; | |
1311 | mpi_request.Header.PageNumber = 0; | |
1312 | mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; | |
1313 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1314 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1315 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1316 | if (r) | |
1317 | goto out; | |
1318 | ||
1319 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1320 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1321 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1322 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1323 | sizeof(*config_page)); | |
1324 | out: | |
1325 | return r; | |
1326 | } | |
1327 | ||
1328 | /** | |
1329 | * mpt3sas_config_get_expander_pg1 - obtain expander page 1 | |
1330 | * @ioc: per adapter object | |
1331 | * @mpi_reply: reply mf payload returned from firmware | |
1332 | * @config_page: contents of the config page | |
1333 | * @phy_number: phy number | |
1334 | * @handle: expander handle | |
1335 | * Context: sleep. | |
1336 | * | |
4beb4867 | 1337 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1338 | */ |
1339 | int | |
1340 | mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1341 | *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, | |
1342 | u16 handle) | |
1343 | { | |
1344 | Mpi2ConfigRequest_t mpi_request; | |
1345 | int r; | |
1346 | ||
1347 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1348 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1349 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1350 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1351 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; | |
1352 | mpi_request.Header.PageNumber = 1; | |
1353 | mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; | |
1354 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1355 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1356 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1357 | if (r) | |
1358 | goto out; | |
1359 | ||
1360 | mpi_request.PageAddress = | |
1361 | cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | | |
1362 | (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); | |
1363 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1364 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1365 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1366 | sizeof(*config_page)); | |
1367 | out: | |
1368 | return r; | |
1369 | } | |
1370 | ||
1371 | /** | |
1372 | * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0 | |
1373 | * @ioc: per adapter object | |
1374 | * @mpi_reply: reply mf payload returned from firmware | |
1375 | * @config_page: contents of the config page | |
1376 | * @form: GET_NEXT_HANDLE or HANDLE | |
1377 | * @handle: expander handle | |
1378 | * Context: sleep. | |
1379 | * | |
4beb4867 | 1380 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1381 | */ |
1382 | int | |
1383 | mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1384 | *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) | |
1385 | { | |
1386 | Mpi2ConfigRequest_t mpi_request; | |
1387 | int r; | |
1388 | ||
1389 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1390 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1391 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1392 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1393 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; | |
1394 | mpi_request.Header.PageNumber = 0; | |
1395 | mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; | |
1396 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1397 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1398 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1399 | if (r) | |
1400 | goto out; | |
1401 | ||
1402 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1403 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1404 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1405 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1406 | sizeof(*config_page)); | |
1407 | out: | |
1408 | return r; | |
1409 | } | |
1410 | ||
1411 | /** | |
1412 | * mpt3sas_config_get_phy_pg0 - obtain phy page 0 | |
1413 | * @ioc: per adapter object | |
1414 | * @mpi_reply: reply mf payload returned from firmware | |
1415 | * @config_page: contents of the config page | |
1416 | * @phy_number: phy number | |
1417 | * Context: sleep. | |
1418 | * | |
4beb4867 | 1419 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1420 | */ |
1421 | int | |
1422 | mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1423 | *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) | |
1424 | { | |
1425 | Mpi2ConfigRequest_t mpi_request; | |
1426 | int r; | |
1427 | ||
1428 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1429 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1430 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1431 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1432 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; | |
1433 | mpi_request.Header.PageNumber = 0; | |
1434 | mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; | |
1435 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1436 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1437 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1438 | if (r) | |
1439 | goto out; | |
1440 | ||
1441 | mpi_request.PageAddress = | |
1442 | cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); | |
1443 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1444 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1445 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1446 | sizeof(*config_page)); | |
1447 | out: | |
1448 | return r; | |
1449 | } | |
1450 | ||
1451 | /** | |
1452 | * mpt3sas_config_get_phy_pg1 - obtain phy page 1 | |
1453 | * @ioc: per adapter object | |
1454 | * @mpi_reply: reply mf payload returned from firmware | |
1455 | * @config_page: contents of the config page | |
1456 | * @phy_number: phy number | |
1457 | * Context: sleep. | |
1458 | * | |
4beb4867 | 1459 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1460 | */ |
1461 | int | |
1462 | mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1463 | *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) | |
1464 | { | |
1465 | Mpi2ConfigRequest_t mpi_request; | |
1466 | int r; | |
1467 | ||
1468 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1469 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1470 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1471 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1472 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; | |
1473 | mpi_request.Header.PageNumber = 1; | |
1474 | mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; | |
1475 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1476 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1477 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1478 | if (r) | |
1479 | goto out; | |
1480 | ||
1481 | mpi_request.PageAddress = | |
1482 | cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); | |
1483 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1484 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1485 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1486 | sizeof(*config_page)); | |
1487 | out: | |
1488 | return r; | |
1489 | } | |
1490 | ||
1491 | /** | |
1492 | * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1 | |
1493 | * @ioc: per adapter object | |
1494 | * @mpi_reply: reply mf payload returned from firmware | |
1495 | * @config_page: contents of the config page | |
1496 | * @form: GET_NEXT_HANDLE or HANDLE | |
1497 | * @handle: volume handle | |
1498 | * Context: sleep. | |
1499 | * | |
4beb4867 | 1500 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1501 | */ |
1502 | int | |
1503 | mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, | |
1504 | Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, | |
1505 | u32 handle) | |
1506 | { | |
1507 | Mpi2ConfigRequest_t mpi_request; | |
1508 | int r; | |
1509 | ||
1510 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1511 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1512 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1513 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; | |
1514 | mpi_request.Header.PageNumber = 1; | |
1515 | mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; | |
1516 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1517 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1518 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1519 | if (r) | |
1520 | goto out; | |
1521 | ||
1522 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1523 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1524 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1525 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1526 | sizeof(*config_page)); | |
1527 | out: | |
1528 | return r; | |
1529 | } | |
1530 | ||
1531 | /** | |
1532 | * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume | |
1533 | * @ioc: per adapter object | |
1534 | * @handle: volume handle | |
1535 | * @num_pds: returns pds count | |
1536 | * Context: sleep. | |
1537 | * | |
4beb4867 | 1538 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1539 | */ |
1540 | int | |
1541 | mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |
1542 | u8 *num_pds) | |
1543 | { | |
1544 | Mpi2ConfigRequest_t mpi_request; | |
1545 | Mpi2RaidVolPage0_t config_page; | |
1546 | Mpi2ConfigReply_t mpi_reply; | |
1547 | int r; | |
1548 | u16 ioc_status; | |
1549 | ||
1550 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1551 | *num_pds = 0; | |
1552 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1553 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1554 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; | |
1555 | mpi_request.Header.PageNumber = 0; | |
1556 | mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; | |
1557 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1558 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1559 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1560 | if (r) | |
1561 | goto out; | |
1562 | ||
1563 | mpi_request.PageAddress = | |
1564 | cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); | |
1565 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1566 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1567 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, | |
1568 | sizeof(Mpi2RaidVolPage0_t)); | |
1569 | if (!r) { | |
1570 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | |
1571 | MPI2_IOCSTATUS_MASK; | |
1572 | if (ioc_status == MPI2_IOCSTATUS_SUCCESS) | |
1573 | *num_pds = config_page.NumPhysDisks; | |
1574 | } | |
1575 | ||
1576 | out: | |
1577 | return r; | |
1578 | } | |
1579 | ||
1580 | /** | |
1581 | * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0 | |
1582 | * @ioc: per adapter object | |
1583 | * @mpi_reply: reply mf payload returned from firmware | |
1584 | * @config_page: contents of the config page | |
1585 | * @form: GET_NEXT_HANDLE or HANDLE | |
1586 | * @handle: volume handle | |
1587 | * @sz: size of buffer passed in config_page | |
1588 | * Context: sleep. | |
1589 | * | |
4beb4867 | 1590 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1591 | */ |
1592 | int | |
1593 | mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, | |
1594 | Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, | |
1595 | u32 handle, u16 sz) | |
1596 | { | |
1597 | Mpi2ConfigRequest_t mpi_request; | |
1598 | int r; | |
1599 | ||
1600 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1601 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1602 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1603 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; | |
1604 | mpi_request.Header.PageNumber = 0; | |
1605 | mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; | |
1606 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1607 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1608 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1609 | if (r) | |
1610 | goto out; | |
1611 | ||
1612 | mpi_request.PageAddress = cpu_to_le32(form | handle); | |
1613 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1614 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1615 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | |
1616 | out: | |
1617 | return r; | |
1618 | } | |
1619 | ||
1620 | /** | |
1621 | * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0 | |
1622 | * @ioc: per adapter object | |
1623 | * @mpi_reply: reply mf payload returned from firmware | |
1624 | * @config_page: contents of the config page | |
1625 | * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE | |
1626 | * @form_specific: specific to the form | |
1627 | * Context: sleep. | |
1628 | * | |
4beb4867 | 1629 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1630 | */ |
1631 | int | |
1632 | mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |
1633 | *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, | |
1634 | u32 form_specific) | |
1635 | { | |
1636 | Mpi2ConfigRequest_t mpi_request; | |
1637 | int r; | |
1638 | ||
1639 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1640 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1641 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1642 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; | |
1643 | mpi_request.Header.PageNumber = 0; | |
1644 | mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; | |
1645 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1646 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1647 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1648 | if (r) | |
1649 | goto out; | |
1650 | ||
1651 | mpi_request.PageAddress = cpu_to_le32(form | form_specific); | |
1652 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1653 | r = _config_request(ioc, &mpi_request, mpi_reply, | |
1654 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1655 | sizeof(*config_page)); | |
1656 | out: | |
1657 | return r; | |
1658 | } | |
1659 | ||
1660 | /** | |
1661 | * mpt3sas_config_get_volume_handle - returns volume handle for give hidden | |
1662 | * raid components | |
1663 | * @ioc: per adapter object | |
1664 | * @pd_handle: phys disk handle | |
1665 | * @volume_handle: volume handle | |
1666 | * Context: sleep. | |
1667 | * | |
4beb4867 | 1668 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1669 | */ |
1670 | int | |
1671 | mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, | |
1672 | u16 *volume_handle) | |
1673 | { | |
1674 | Mpi2RaidConfigurationPage0_t *config_page = NULL; | |
1675 | Mpi2ConfigRequest_t mpi_request; | |
1676 | Mpi2ConfigReply_t mpi_reply; | |
1677 | int r, i, config_page_sz; | |
1678 | u16 ioc_status; | |
1679 | int config_num; | |
1680 | u16 element_type; | |
1681 | u16 phys_disk_dev_handle; | |
1682 | ||
1683 | *volume_handle = 0; | |
1684 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | |
1685 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | |
1686 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | |
1687 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | |
1688 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; | |
1689 | mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; | |
1690 | mpi_request.Header.PageNumber = 0; | |
1691 | ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); | |
1692 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1693 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | |
1694 | if (r) | |
1695 | goto out; | |
1696 | ||
1697 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; | |
1698 | config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); | |
1699 | config_page = kmalloc(config_page_sz, GFP_KERNEL); | |
1700 | if (!config_page) { | |
1701 | r = -1; | |
1702 | goto out; | |
1703 | } | |
1704 | ||
1705 | config_num = 0xff; | |
1706 | while (1) { | |
1707 | mpi_request.PageAddress = cpu_to_le32(config_num + | |
1708 | MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); | |
1709 | r = _config_request(ioc, &mpi_request, &mpi_reply, | |
1710 | MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, | |
1711 | config_page_sz); | |
1712 | if (r) | |
1713 | goto out; | |
1714 | r = -1; | |
1715 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | |
1716 | MPI2_IOCSTATUS_MASK; | |
1717 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | |
1718 | goto out; | |
1719 | for (i = 0; i < config_page->NumElements; i++) { | |
1720 | element_type = le16_to_cpu(config_page-> | |
1721 | ConfigElement[i].ElementFlags) & | |
1722 | MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; | |
1723 | if (element_type == | |
1724 | MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || | |
1725 | element_type == | |
1726 | MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { | |
1727 | phys_disk_dev_handle = | |
1728 | le16_to_cpu(config_page->ConfigElement[i]. | |
1729 | PhysDiskDevHandle); | |
1730 | if (phys_disk_dev_handle == pd_handle) { | |
1731 | *volume_handle = | |
1732 | le16_to_cpu(config_page-> | |
1733 | ConfigElement[i].VolDevHandle); | |
1734 | r = 0; | |
1735 | goto out; | |
1736 | } | |
1737 | } else if (element_type == | |
1738 | MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { | |
1739 | *volume_handle = 0; | |
1740 | r = 0; | |
1741 | goto out; | |
1742 | } | |
1743 | } | |
1744 | config_num = config_page->ConfigNum; | |
1745 | } | |
1746 | out: | |
1747 | kfree(config_page); | |
1748 | return r; | |
1749 | } | |
1750 | ||
1751 | /** | |
1752 | * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle | |
1753 | * @ioc: per adapter object | |
1754 | * @volume_handle: volume handle | |
1755 | * @wwid: volume wwid | |
1756 | * Context: sleep. | |
1757 | * | |
4beb4867 | 1758 | * Return: 0 for success, non-zero for failure. |
f92363d1 SR |
1759 | */ |
1760 | int | |
1761 | mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, | |
1762 | u64 *wwid) | |
1763 | { | |
1764 | Mpi2ConfigReply_t mpi_reply; | |
1765 | Mpi2RaidVolPage1_t raid_vol_pg1; | |
1766 | ||
1767 | *wwid = 0; | |
1768 | if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | |
1769 | &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, | |
1770 | volume_handle))) { | |
1771 | *wwid = le64_to_cpu(raid_vol_pg1.WWID); | |
1772 | return 0; | |
1773 | } else | |
1774 | return -1; | |
1775 | } |