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