blob: 55cd329089246b5fff550db5f14724718196e170 [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
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530104 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
105 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
106 case MPI2_CONFIG_PAGETYPE_IO_UNIT:
107 desc = "io_unit";
108 break;
109 case MPI2_CONFIG_PAGETYPE_IOC:
110 desc = "ioc";
111 break;
112 case MPI2_CONFIG_PAGETYPE_BIOS:
113 desc = "bios";
114 break;
115 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
116 desc = "raid_volume";
117 break;
118 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
Colin Ian King8700bc72018-11-28 15:30:48 +0000119 desc = "manufacturing";
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530120 break;
121 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
122 desc = "physdisk";
123 break;
124 case MPI2_CONFIG_PAGETYPE_EXTENDED:
125 switch (mpi_request->ExtPageType) {
126 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
127 desc = "sas_io_unit";
128 break;
129 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
130 desc = "sas_expander";
131 break;
132 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
133 desc = "sas_device";
134 break;
135 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
136 desc = "sas_phy";
137 break;
138 case MPI2_CONFIG_EXTPAGETYPE_LOG:
139 desc = "log";
140 break;
141 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
142 desc = "enclosure";
143 break;
144 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
145 desc = "raid_config";
146 break;
147 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
Masanari Iida07f42252013-03-20 11:00:34 +0900148 desc = "driver_mapping";
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530149 break;
Suganath Prabu Subramanic102e002017-10-31 18:02:30 +0530150 case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
151 desc = "sas_port";
152 break;
153 case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
154 desc = "ext_manufacturing";
155 break;
156 case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
157 desc = "pcie_io_unit";
158 break;
159 case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
160 desc = "pcie_switch";
161 break;
162 case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
163 desc = "pcie_device";
164 break;
165 case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
166 desc = "pcie_link";
167 break;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530168 }
169 break;
170 }
171
172 if (!desc)
173 return;
174
Joe Perches919d8a32018-09-17 08:01:09 -0700175 ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",
176 calling_function_name, desc,
177 mpi_request->Header.PageNumber, mpi_request->Action,
178 le32_to_cpu(mpi_request->PageAddress), smid);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530179
180 if (!mpi_reply)
181 return;
182
183 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
Joe Perches919d8a32018-09-17 08:01:09 -0700184 ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
185 le16_to_cpu(mpi_reply->IOCStatus),
186 le32_to_cpu(mpi_reply->IOCLogInfo));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530187}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530188
189/**
190 * _config_alloc_config_dma_memory - obtain physical memory
191 * @ioc: per adapter object
192 * @mem: struct config_request
193 *
194 * A wrapper for obtaining dma-able memory for config page request.
195 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700196 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530197 */
198static int
199_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
200 struct config_request *mem)
201{
202 int r = 0;
203
204 if (mem->sz > ioc->config_page_sz) {
205 mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
206 &mem->page_dma, GFP_KERNEL);
207 if (!mem->page) {
Joe Perches919d8a32018-09-17 08:01:09 -0700208 ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
209 __func__, mem->sz);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530210 r = -ENOMEM;
211 }
212 } else { /* use tmp buffer if less than 512 bytes */
213 mem->page = ioc->config_page;
214 mem->page_dma = ioc->config_page_dma;
215 }
Suganath Prabu Subramani182ac782018-02-07 02:51:48 -0800216 ioc->config_vaddr = mem->page;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530217 return r;
218}
219
220/**
221 * _config_free_config_dma_memory - wrapper to free the memory
222 * @ioc: per adapter object
223 * @mem: struct config_request
224 *
225 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
226 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700227 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530228 */
229static void
230_config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
231 struct config_request *mem)
232{
233 if (mem->sz > ioc->config_page_sz)
234 dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
235 mem->page_dma);
236}
237
238/**
239 * mpt3sas_config_done - config page completion routine
240 * @ioc: per adapter object
241 * @smid: system request message index
242 * @msix_index: MSIX table index supplied by the OS
243 * @reply: reply message frame(lower 32bit addr)
244 * Context: none.
245 *
246 * The callback handler when using _config_request.
247 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700248 * Return: 1 meaning mf should be freed from _base_interrupt
249 * 0 means the mf is freed from this function.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530250 */
251u8
252mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
253 u32 reply)
254{
255 MPI2DefaultReply_t *mpi_reply;
256
257 if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)
258 return 1;
259 if (ioc->config_cmds.smid != smid)
260 return 1;
261 ioc->config_cmds.status |= MPT3_CMD_COMPLETE;
262 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
263 if (mpi_reply) {
264 ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;
265 memcpy(ioc->config_cmds.reply, mpi_reply,
266 mpi_reply->MsgLength*4);
267 }
268 ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500269 if (ioc->logging_level & MPT_DEBUG_CONFIG)
270 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530271 ioc->config_cmds.smid = USHRT_MAX;
272 complete(&ioc->config_cmds.done);
273 return 1;
274}
275
276/**
277 * _config_request - main routine for sending config page requests
278 * @ioc: per adapter object
279 * @mpi_request: request message frame
280 * @mpi_reply: reply mf payload returned from firmware
281 * @timeout: timeout in seconds
282 * @config_page: contents of the config page
283 * @config_page_sz: size of config page
284 * Context: sleep
285 *
286 * A generic API for config page requests to firmware.
287 *
288 * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
289 * this API.
290 *
291 * The callback index is set inside `ioc->config_cb_idx.
292 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700293 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530294 */
295static int
296_config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
297 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
298 void *config_page, u16 config_page_sz)
299{
300 u16 smid;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530301 Mpi2ConfigRequest_t *config_request;
302 int r;
303 u8 retry_count, issue_host_reset = 0;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530304 struct config_request mem;
305 u32 ioc_status = UINT_MAX;
306
307 mutex_lock(&ioc->config_cmds.mutex);
308 if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
Joe Perches919d8a32018-09-17 08:01:09 -0700309 ioc_err(ioc, "%s: config_cmd in use\n", __func__);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530310 mutex_unlock(&ioc->config_cmds.mutex);
311 return -EAGAIN;
312 }
313
314 retry_count = 0;
315 memset(&mem, 0, sizeof(struct config_request));
316
317 mpi_request->VF_ID = 0; /* TODO */
318 mpi_request->VP_ID = 0;
319
320 if (config_page) {
321 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
322 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
323 mpi_request->Header.PageType = mpi_reply->Header.PageType;
324 mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
325 mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
326 mpi_request->ExtPageType = mpi_reply->ExtPageType;
327 if (mpi_request->Header.PageLength)
328 mem.sz = mpi_request->Header.PageLength * 4;
329 else
330 mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
331 r = _config_alloc_config_dma_memory(ioc, &mem);
332 if (r != 0)
333 goto out;
334 if (mpi_request->Action ==
335 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
336 mpi_request->Action ==
337 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
338 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
339 MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
340 mem.page_dma);
341 memcpy(mem.page, config_page, min_t(u16, mem.sz,
342 config_page_sz));
343 } else {
344 memset(config_page, 0, config_page_sz);
345 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
346 MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
347 memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
348 }
349 }
350
351 retry_config:
352 if (retry_count) {
353 if (retry_count > 2) { /* attempt only 2 retries */
354 r = -EFAULT;
355 goto free_mem;
356 }
Joe Perches919d8a32018-09-17 08:01:09 -0700357 ioc_info(ioc, "%s: attempting retry (%d)\n",
358 __func__, retry_count);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530359 }
Suganath Prabuf4305742018-10-31 18:53:33 +0530360
361 r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
362 if (r)
363 goto free_mem;
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530364
365 smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
366 if (!smid) {
Joe Perches919d8a32018-09-17 08:01:09 -0700367 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530368 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
369 r = -EAGAIN;
370 goto free_mem;
371 }
372
373 r = 0;
Suganath Prabu Sf09219e2020-07-30 13:33:43 +0530374 memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530375 ioc->config_cmds.status = MPT3_CMD_PENDING;
376 config_request = mpt3sas_base_get_msg_frame(ioc, smid);
377 ioc->config_cmds.smid = smid;
378 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500379 if (ioc->logging_level & MPT_DEBUG_CONFIG)
380 _config_display_some_debug(ioc, smid, "config_request", NULL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530381 init_completion(&ioc->config_cmds.done);
Suganath Prabu S078a4cc2019-05-31 08:14:34 -0400382 ioc->put_smid_default(ioc, smid);
Calvin Owens8bbb1cf2016-07-28 21:38:22 -0700383 wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530384 if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500385 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
386 _config_display_some_debug(ioc,
387 smid, "config_request", NULL);
Damien Le Moal2eab3eb2020-07-06 21:33:56 +0900388 ioc_err(ioc, "%s: command timeout\n", __func__);
389 mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
390 mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530391 retry_count++;
392 if (ioc->config_cmds.smid == smid)
393 mpt3sas_base_free_smid(ioc, smid);
394 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
395 MPT3_CMD_RESET) || ioc->pci_error_recovery)
396 goto retry_config;
397 issue_host_reset = 1;
398 r = -EFAULT;
399 goto free_mem;
400 }
401
402 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
403 memcpy(mpi_reply, ioc->config_cmds.reply,
404 sizeof(Mpi2ConfigReply_t));
405
406 /* Reply Frame Sanity Checks to workaround FW issues */
407 if ((mpi_request->Header.PageType & 0xF) !=
408 (mpi_reply->Header.PageType & 0xF)) {
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500409 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
410 _config_display_some_debug(ioc,
411 smid, "config_request", NULL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530412 _debug_dump_mf(mpi_request, ioc->request_sz/4);
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500413 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
Joe Perches506f7f62018-09-17 08:01:12 -0700414 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
415 ioc->name, __func__,
416 mpi_request->Header.PageType & 0xF,
417 mpi_reply->Header.PageType & 0xF);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530418 }
419
420 if (((mpi_request->Header.PageType & 0xF) ==
421 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
422 mpi_request->ExtPageType != mpi_reply->ExtPageType) {
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500423 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
424 _config_display_some_debug(ioc,
425 smid, "config_request", NULL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530426 _debug_dump_mf(mpi_request, ioc->request_sz/4);
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500427 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
Joe Perches506f7f62018-09-17 08:01:12 -0700428 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
429 ioc->name, __func__,
430 mpi_request->ExtPageType,
431 mpi_reply->ExtPageType);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530432 }
433 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
434 & MPI2_IOCSTATUS_MASK;
435 }
436
437 if (retry_count)
Joe Perches919d8a32018-09-17 08:01:09 -0700438 ioc_info(ioc, "%s: retry (%d) completed!!\n",
439 __func__, retry_count);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530440
441 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
442 config_page && mpi_request->Action ==
443 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
444 u8 *p = (u8 *)mem.page;
445
446 /* Config Page Sanity Checks to workaround FW issues */
447 if (p) {
448 if ((mpi_request->Header.PageType & 0xF) !=
449 (p[3] & 0xF)) {
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500450 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
451 _config_display_some_debug(ioc,
452 smid, "config_request", NULL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530453 _debug_dump_mf(mpi_request, ioc->request_sz/4);
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500454 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530455 _debug_dump_config(p, min_t(u16, mem.sz,
456 config_page_sz)/4);
Joe Perches506f7f62018-09-17 08:01:12 -0700457 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
458 ioc->name, __func__,
459 mpi_request->Header.PageType & 0xF,
460 p[3] & 0xF);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530461 }
462
463 if (((mpi_request->Header.PageType & 0xF) ==
464 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
465 (mpi_request->ExtPageType != p[6])) {
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500466 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
467 _config_display_some_debug(ioc,
468 smid, "config_request", NULL);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530469 _debug_dump_mf(mpi_request, ioc->request_sz/4);
Sreekanth Reddy5b061982019-12-26 06:13:30 -0500470 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530471 _debug_dump_config(p, min_t(u16, mem.sz,
472 config_page_sz)/4);
Joe Perches506f7f62018-09-17 08:01:12 -0700473 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
474 ioc->name, __func__,
475 mpi_request->ExtPageType, p[6]);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530476 }
477 }
478 memcpy(config_page, mem.page, min_t(u16, mem.sz,
479 config_page_sz));
480 }
481
482 free_mem:
483 if (config_page)
484 _config_free_config_dma_memory(ioc, &mem);
485 out:
486 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
487 mutex_unlock(&ioc->config_cmds.mutex);
488
489 if (issue_host_reset)
Calvin Owens98c56ad2016-07-28 21:38:21 -0700490 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530491 return r;
492}
493
494/**
495 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
496 * @ioc: per adapter object
497 * @mpi_reply: reply mf payload returned from firmware
498 * @config_page: contents of the config page
499 * Context: sleep.
500 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700501 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530502 */
503int
504mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
505 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
506{
507 Mpi2ConfigRequest_t mpi_request;
508 int r;
509
510 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
511 mpi_request.Function = MPI2_FUNCTION_CONFIG;
512 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
513 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
514 mpi_request.Header.PageNumber = 0;
515 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
516 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
517 r = _config_request(ioc, &mpi_request, mpi_reply,
518 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
519 if (r)
520 goto out;
521
522 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
523 r = _config_request(ioc, &mpi_request, mpi_reply,
524 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
525 sizeof(*config_page));
526 out:
527 return r;
528}
529
530/**
531 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
532 * @ioc: per adapter object
533 * @mpi_reply: reply mf payload returned from firmware
534 * @config_page: contents of the config page
535 * @sz: size of buffer passed in config_page
536 * Context: sleep.
537 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700538 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530539 */
540int
541mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
542 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
543 u16 sz)
544{
545 Mpi2ConfigRequest_t mpi_request;
546 int r;
547
548 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
549 mpi_request.Function = MPI2_FUNCTION_CONFIG;
550 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
551 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
552 mpi_request.Header.PageNumber = 7;
553 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
554 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
555 r = _config_request(ioc, &mpi_request, mpi_reply,
556 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
557 if (r)
558 goto out;
559
560 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
561 r = _config_request(ioc, &mpi_request, mpi_reply,
562 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
563 sz);
564 out:
565 return r;
566}
567
568/**
569 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
570 * @ioc: per adapter object
571 * @mpi_reply: reply mf payload returned from firmware
572 * @config_page: contents of the config page
573 * Context: sleep.
574 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700575 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530576 */
577int
578mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
579 Mpi2ConfigReply_t *mpi_reply,
580 struct Mpi2ManufacturingPage10_t *config_page)
581{
582 Mpi2ConfigRequest_t mpi_request;
583 int r;
584
585 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
586 mpi_request.Function = MPI2_FUNCTION_CONFIG;
587 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
588 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
589 mpi_request.Header.PageNumber = 10;
590 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
591 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
592 r = _config_request(ioc, &mpi_request, mpi_reply,
593 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
594 if (r)
595 goto out;
596
597 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
598 r = _config_request(ioc, &mpi_request, mpi_reply,
599 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
600 sizeof(*config_page));
601 out:
602 return r;
603}
604
605/**
606 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
607 * @ioc: per adapter object
608 * @mpi_reply: reply mf payload returned from firmware
609 * @config_page: contents of the config page
610 * Context: sleep.
611 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700612 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530613 */
614int
615mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
616 Mpi2ConfigReply_t *mpi_reply,
617 struct Mpi2ManufacturingPage11_t *config_page)
618{
619 Mpi2ConfigRequest_t mpi_request;
620 int r;
621
622 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
623 mpi_request.Function = MPI2_FUNCTION_CONFIG;
624 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
625 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
626 mpi_request.Header.PageNumber = 11;
627 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
628 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
629 r = _config_request(ioc, &mpi_request, mpi_reply,
630 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
631 if (r)
632 goto out;
633
634 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635 r = _config_request(ioc, &mpi_request, mpi_reply,
636 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
637 sizeof(*config_page));
638 out:
639 return r;
640}
641
642/**
643 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
644 * @ioc: per adapter object
645 * @mpi_reply: reply mf payload returned from firmware
646 * @config_page: contents of the config page
647 * Context: sleep.
648 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700649 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530650 */
651int
652mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
653 Mpi2ConfigReply_t *mpi_reply,
654 struct Mpi2ManufacturingPage11_t *config_page)
655{
656 Mpi2ConfigRequest_t mpi_request;
657 int r;
658
659 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
660 mpi_request.Function = MPI2_FUNCTION_CONFIG;
661 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
662 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
663 mpi_request.Header.PageNumber = 11;
664 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
665 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
666 r = _config_request(ioc, &mpi_request, mpi_reply,
667 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
668 if (r)
669 goto out;
670
671 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
672 r = _config_request(ioc, &mpi_request, mpi_reply,
673 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
674 sizeof(*config_page));
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530675 out:
676 return r;
677}
678
679/**
680 * mpt3sas_config_get_bios_pg2 - obtain bios page 2
681 * @ioc: per adapter object
682 * @mpi_reply: reply mf payload returned from firmware
683 * @config_page: contents of the config page
684 * Context: sleep.
685 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700686 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530687 */
688int
689mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
690 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
691{
692 Mpi2ConfigRequest_t mpi_request;
693 int r;
694
695 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
696 mpi_request.Function = MPI2_FUNCTION_CONFIG;
697 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
698 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
699 mpi_request.Header.PageNumber = 2;
700 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
701 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
702 r = _config_request(ioc, &mpi_request, mpi_reply,
703 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
704 if (r)
705 goto out;
706
707 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
708 r = _config_request(ioc, &mpi_request, mpi_reply,
709 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
710 sizeof(*config_page));
711 out:
712 return r;
713}
714
715/**
716 * mpt3sas_config_get_bios_pg3 - obtain bios page 3
717 * @ioc: per adapter object
718 * @mpi_reply: reply mf payload returned from firmware
719 * @config_page: contents of the config page
720 * Context: sleep.
721 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700722 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530723 */
724int
725mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
726 *mpi_reply, Mpi2BiosPage3_t *config_page)
727{
728 Mpi2ConfigRequest_t mpi_request;
729 int r;
730
731 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
732 mpi_request.Function = MPI2_FUNCTION_CONFIG;
733 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
734 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
735 mpi_request.Header.PageNumber = 3;
736 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
737 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
738 r = _config_request(ioc, &mpi_request, mpi_reply,
739 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
740 if (r)
741 goto out;
742
743 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
744 r = _config_request(ioc, &mpi_request, mpi_reply,
745 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
746 sizeof(*config_page));
747 out:
748 return r;
749}
750
751/**
752 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
753 * @ioc: per adapter object
754 * @mpi_reply: reply mf payload returned from firmware
755 * @config_page: contents of the config page
756 * Context: sleep.
757 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700758 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530759 */
760int
761mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
762 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
763{
764 Mpi2ConfigRequest_t mpi_request;
765 int r;
766
767 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
768 mpi_request.Function = MPI2_FUNCTION_CONFIG;
769 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
770 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
771 mpi_request.Header.PageNumber = 0;
772 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
773 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
774 r = _config_request(ioc, &mpi_request, mpi_reply,
775 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
776 if (r)
777 goto out;
778
779 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
780 r = _config_request(ioc, &mpi_request, mpi_reply,
781 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
782 sizeof(*config_page));
783 out:
784 return r;
785}
786
787/**
788 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
789 * @ioc: per adapter object
790 * @mpi_reply: reply mf payload returned from firmware
791 * @config_page: contents of the config page
792 * Context: sleep.
793 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700794 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530795 */
796int
797mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
798 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
799{
800 Mpi2ConfigRequest_t mpi_request;
801 int r;
802
803 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
804 mpi_request.Function = MPI2_FUNCTION_CONFIG;
805 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
806 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
807 mpi_request.Header.PageNumber = 1;
808 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
809 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
810 r = _config_request(ioc, &mpi_request, mpi_reply,
811 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
812 if (r)
813 goto out;
814
815 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
816 r = _config_request(ioc, &mpi_request, mpi_reply,
817 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
818 sizeof(*config_page));
819 out:
820 return r;
821}
822
823/**
824 * mpt3sas_config_set_iounit_pg1 - set iounit page 1
825 * @ioc: per adapter object
826 * @mpi_reply: reply mf payload returned from firmware
827 * @config_page: contents of the config page
828 * Context: sleep.
829 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700830 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530831 */
832int
833mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
834 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
835{
836 Mpi2ConfigRequest_t mpi_request;
837 int r;
838
839 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
840 mpi_request.Function = MPI2_FUNCTION_CONFIG;
841 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
842 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
843 mpi_request.Header.PageNumber = 1;
844 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
845 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
846 r = _config_request(ioc, &mpi_request, mpi_reply,
847 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
848 if (r)
849 goto out;
850
851 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
852 r = _config_request(ioc, &mpi_request, mpi_reply,
853 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
854 sizeof(*config_page));
855 out:
856 return r;
857}
858
Sreekanth Reddy42263092015-11-11 17:30:29 +0530859/**
860 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
861 * @ioc: per adapter object
862 * @mpi_reply: reply mf payload returned from firmware
863 * @config_page: contents of the config page
864 * @sz: size of buffer passed in config_page
865 * Context: sleep.
866 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700867 * Return: 0 for success, non-zero for failure.
Sreekanth Reddy42263092015-11-11 17:30:29 +0530868 */
869int
870mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
871 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
872{
873 Mpi2ConfigRequest_t mpi_request;
874 int r;
875
876 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
877 mpi_request.Function = MPI2_FUNCTION_CONFIG;
878 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
879 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
880 mpi_request.Header.PageNumber = 3;
881 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
882 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
883 r = _config_request(ioc, &mpi_request, mpi_reply,
884 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
885 if (r)
886 goto out;
887
888 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
889 r = _config_request(ioc, &mpi_request, mpi_reply,
890 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
891 out:
892 return r;
893}
Sreekanth Reddy42263092015-11-11 17:30:29 +0530894
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530895/**
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +0530896 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
897 * @ioc: per adapter object
898 * @mpi_reply: reply mf payload returned from firmware
899 * @config_page: contents of the config page
900 * Context: sleep.
901 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700902 * Return: 0 for success, non-zero for failure.
Sreekanth Reddy2d8ce8c2015-01-12 11:38:56 +0530903 */
904int
905mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
906 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
907{
908 Mpi2ConfigRequest_t mpi_request;
909 int r;
910
911 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
912 mpi_request.Function = MPI2_FUNCTION_CONFIG;
913 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
914 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
915 mpi_request.Header.PageNumber = 8;
916 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
917 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
918 r = _config_request(ioc, &mpi_request, mpi_reply,
919 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
920 if (r)
921 goto out;
922
923 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
924 r = _config_request(ioc, &mpi_request, mpi_reply,
925 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
926 sizeof(*config_page));
927 out:
928 return r;
929}
930
931/**
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530932 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
933 * @ioc: per adapter object
934 * @mpi_reply: reply mf payload returned from firmware
935 * @config_page: contents of the config page
936 * Context: sleep.
937 *
Bart Van Assche4beb4862018-06-15 14:42:01 -0700938 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +0530939 */
940int
941mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
942 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
943{
944 Mpi2ConfigRequest_t mpi_request;
945 int r;
946
947 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
948 mpi_request.Function = MPI2_FUNCTION_CONFIG;
949 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
950 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
951 mpi_request.Header.PageNumber = 8;
952 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
953 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
954 r = _config_request(ioc, &mpi_request, mpi_reply,
955 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
956 if (r)
957 goto out;
958
959 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
960 r = _config_request(ioc, &mpi_request, mpi_reply,
961 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
962 sizeof(*config_page));
963 out:
964 return r;
965}
Suganath Prabu S2426f202019-05-31 08:14:41 -0400966/**
967 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
968 * @ioc: per adapter object
969 * @mpi_reply: reply mf payload returned from firmware
970 * @config_page: contents of the config page
971 * Context: sleep.
972 *
973 * Return: 0 for success, non-zero for failure.
974 */
975int
976mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
977 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
978{
979 Mpi2ConfigRequest_t mpi_request;
980 int r;
981
982 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
983 mpi_request.Function = MPI2_FUNCTION_CONFIG;
984 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
985 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
986 mpi_request.Header.PageNumber = 1;
987 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
988 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
989 r = _config_request(ioc, &mpi_request, mpi_reply,
990 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
991 if (r)
992 goto out;
993
994 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
995 r = _config_request(ioc, &mpi_request, mpi_reply,
996 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
997 sizeof(*config_page));
998 out:
999 return r;
1000}
1001
1002/**
1003 * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
1004 * @ioc: per adapter object
1005 * @mpi_reply: reply mf payload returned from firmware
1006 * @config_page: contents of the config page
1007 * Context: sleep.
1008 *
1009 * Return: 0 for success, non-zero for failure.
1010 */
1011int
1012mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1013 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1014{
1015 Mpi2ConfigRequest_t mpi_request;
1016 int r;
1017
1018 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1019 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1020 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1021 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1022 mpi_request.Header.PageNumber = 1;
1023 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1024 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1025 r = _config_request(ioc, &mpi_request, mpi_reply,
1026 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1027 if (r)
1028 goto out;
1029
1030 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1031 r = _config_request(ioc, &mpi_request, mpi_reply,
1032 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1033 sizeof(*config_page));
1034 out:
1035 return r;
1036}
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301037
1038/**
1039 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1040 * @ioc: per adapter object
1041 * @mpi_reply: reply mf payload returned from firmware
1042 * @config_page: contents of the config page
1043 * @form: GET_NEXT_HANDLE or HANDLE
1044 * @handle: device handle
1045 * Context: sleep.
1046 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001047 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301048 */
1049int
1050mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1051 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1052 u32 form, u32 handle)
1053{
1054 Mpi2ConfigRequest_t mpi_request;
1055 int r;
1056
1057 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1058 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1059 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1060 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1061 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1062 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1063 mpi_request.Header.PageNumber = 0;
1064 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1065 r = _config_request(ioc, &mpi_request, mpi_reply,
1066 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1067 if (r)
1068 goto out;
1069
1070 mpi_request.PageAddress = cpu_to_le32(form | handle);
1071 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1072 r = _config_request(ioc, &mpi_request, mpi_reply,
1073 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1074 sizeof(*config_page));
1075 out:
1076 return r;
1077}
1078
1079/**
1080 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1081 * @ioc: per adapter object
1082 * @mpi_reply: reply mf payload returned from firmware
1083 * @config_page: contents of the config page
1084 * @form: GET_NEXT_HANDLE or HANDLE
1085 * @handle: device handle
1086 * Context: sleep.
1087 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001088 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301089 */
1090int
1091mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1092 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1093 u32 form, u32 handle)
1094{
1095 Mpi2ConfigRequest_t mpi_request;
1096 int r;
1097
1098 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1099 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1100 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1101 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1102 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1103 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1104 mpi_request.Header.PageNumber = 1;
1105 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1106 r = _config_request(ioc, &mpi_request, mpi_reply,
1107 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1108 if (r)
1109 goto out;
1110
1111 mpi_request.PageAddress = cpu_to_le32(form | handle);
1112 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1113 r = _config_request(ioc, &mpi_request, mpi_reply,
1114 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1115 sizeof(*config_page));
1116 out:
1117 return r;
1118}
1119
1120/**
Suganath Prabu Subramanic102e002017-10-31 18:02:30 +05301121 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1122 * @ioc: per adapter object
1123 * @mpi_reply: reply mf payload returned from firmware
1124 * @config_page: contents of the config page
1125 * @form: GET_NEXT_HANDLE or HANDLE
1126 * @handle: device handle
1127 * Context: sleep.
1128 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001129 * Return: 0 for success, non-zero for failure.
Suganath Prabu Subramanic102e002017-10-31 18:02:30 +05301130 */
1131int
1132mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1133 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1134 u32 form, u32 handle)
1135{
1136 Mpi2ConfigRequest_t mpi_request;
1137 int r;
1138
1139 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1140 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1141 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1142 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1143 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1144 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1145 mpi_request.Header.PageNumber = 0;
1146 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1147 r = _config_request(ioc, &mpi_request, mpi_reply,
1148 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1149 if (r)
1150 goto out;
1151
1152 mpi_request.PageAddress = cpu_to_le32(form | handle);
1153 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1154 r = _config_request(ioc, &mpi_request, mpi_reply,
1155 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1156 sizeof(*config_page));
1157out:
1158 return r;
1159}
1160
1161/**
1162 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1163 * @ioc: per adapter object
1164 * @mpi_reply: reply mf payload returned from firmware
1165 * @config_page: contents of the config page
1166 * @form: GET_NEXT_HANDLE or HANDLE
1167 * @handle: device handle
1168 * Context: sleep.
1169 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001170 * Return: 0 for success, non-zero for failure.
Suganath Prabu Subramanic102e002017-10-31 18:02:30 +05301171 */
1172int
1173mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1174 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1175 u32 form, u32 handle)
1176{
1177 Mpi2ConfigRequest_t mpi_request;
1178 int r;
1179
1180 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1181 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1182 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1183 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1184 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1185 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1186 mpi_request.Header.PageNumber = 2;
1187 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1188 r = _config_request(ioc, &mpi_request, mpi_reply,
1189 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1190 if (r)
1191 goto out;
1192
1193 mpi_request.PageAddress = cpu_to_le32(form | handle);
1194 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1195 r = _config_request(ioc, &mpi_request, mpi_reply,
1196 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1197 sizeof(*config_page));
1198out:
1199 return r;
1200}
1201
1202/**
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301203 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1204 * @ioc: per adapter object
1205 * @num_phys: pointer returned with the number of phys
1206 * Context: sleep.
1207 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001208 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301209 */
1210int
1211mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1212{
1213 Mpi2ConfigRequest_t mpi_request;
1214 int r;
1215 u16 ioc_status;
1216 Mpi2ConfigReply_t mpi_reply;
1217 Mpi2SasIOUnitPage0_t config_page;
1218
1219 *num_phys = 0;
1220 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1221 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1222 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1223 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1224 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1225 mpi_request.Header.PageNumber = 0;
1226 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1227 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1228 r = _config_request(ioc, &mpi_request, &mpi_reply,
1229 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1230 if (r)
1231 goto out;
1232
1233 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1234 r = _config_request(ioc, &mpi_request, &mpi_reply,
1235 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1236 sizeof(Mpi2SasIOUnitPage0_t));
1237 if (!r) {
1238 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1239 MPI2_IOCSTATUS_MASK;
1240 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1241 *num_phys = config_page.NumPhys;
1242 }
1243 out:
1244 return r;
1245}
1246
1247/**
1248 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1249 * @ioc: per adapter object
1250 * @mpi_reply: reply mf payload returned from firmware
1251 * @config_page: contents of the config page
1252 * @sz: size of buffer passed in config_page
1253 * Context: sleep.
1254 *
1255 * Calling function should call config_get_number_hba_phys prior to
1256 * this function, so enough memory is allocated for config_page.
1257 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001258 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301259 */
1260int
1261mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1262 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1263 u16 sz)
1264{
1265 Mpi2ConfigRequest_t mpi_request;
1266 int r;
1267
1268 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1269 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1270 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1271 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1272 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1273 mpi_request.Header.PageNumber = 0;
1274 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1275 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1276 r = _config_request(ioc, &mpi_request, mpi_reply,
1277 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1278 if (r)
1279 goto out;
1280
1281 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
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_sas_iounit_pg1 - obtain sas iounit page 1
1290 * @ioc: per adapter object
1291 * @mpi_reply: reply mf payload returned from firmware
1292 * @config_page: contents of the config page
1293 * @sz: size of buffer passed in config_page
1294 * Context: sleep.
1295 *
1296 * Calling function should call config_get_number_hba_phys prior to
1297 * this function, so enough memory is allocated for config_page.
1298 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001299 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301300 */
1301int
1302mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1303 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1304 u16 sz)
1305{
1306 Mpi2ConfigRequest_t mpi_request;
1307 int r;
1308
1309 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1310 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1311 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1312 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1313 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1314 mpi_request.Header.PageNumber = 1;
1315 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1316 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1317 r = _config_request(ioc, &mpi_request, mpi_reply,
1318 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1319 if (r)
1320 goto out;
1321
1322 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1323 r = _config_request(ioc, &mpi_request, mpi_reply,
1324 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1325 out:
1326 return r;
1327}
1328
1329/**
1330 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1331 * @ioc: per adapter object
1332 * @mpi_reply: reply mf payload returned from firmware
1333 * @config_page: contents of the config page
1334 * @sz: size of buffer passed in config_page
1335 * Context: sleep.
1336 *
1337 * Calling function should call config_get_number_hba_phys prior to
1338 * this function, so enough memory is allocated for config_page.
1339 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001340 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301341 */
1342int
1343mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1344 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1345 u16 sz)
1346{
1347 Mpi2ConfigRequest_t mpi_request;
1348 int r;
1349
1350 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1351 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1352 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1353 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1354 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1355 mpi_request.Header.PageNumber = 1;
1356 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1357 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1358 r = _config_request(ioc, &mpi_request, mpi_reply,
1359 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1360 if (r)
1361 goto out;
1362
1363 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1364 _config_request(ioc, &mpi_request, mpi_reply,
1365 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1366 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1367 r = _config_request(ioc, &mpi_request, mpi_reply,
1368 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1369 out:
1370 return r;
1371}
1372
1373/**
1374 * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1375 * @ioc: per adapter object
1376 * @mpi_reply: reply mf payload returned from firmware
1377 * @config_page: contents of the config page
1378 * @form: GET_NEXT_HANDLE or HANDLE
1379 * @handle: expander handle
1380 * Context: sleep.
1381 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001382 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301383 */
1384int
1385mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1386 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1387{
1388 Mpi2ConfigRequest_t mpi_request;
1389 int r;
1390
1391 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1392 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1393 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1394 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1395 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1396 mpi_request.Header.PageNumber = 0;
1397 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1398 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1399 r = _config_request(ioc, &mpi_request, mpi_reply,
1400 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1401 if (r)
1402 goto out;
1403
1404 mpi_request.PageAddress = cpu_to_le32(form | handle);
1405 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1406 r = _config_request(ioc, &mpi_request, mpi_reply,
1407 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1408 sizeof(*config_page));
1409 out:
1410 return r;
1411}
1412
1413/**
1414 * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1415 * @ioc: per adapter object
1416 * @mpi_reply: reply mf payload returned from firmware
1417 * @config_page: contents of the config page
1418 * @phy_number: phy number
1419 * @handle: expander handle
1420 * Context: sleep.
1421 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001422 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301423 */
1424int
1425mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1426 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1427 u16 handle)
1428{
1429 Mpi2ConfigRequest_t mpi_request;
1430 int r;
1431
1432 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1433 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1434 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1435 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1436 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1437 mpi_request.Header.PageNumber = 1;
1438 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1439 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1440 r = _config_request(ioc, &mpi_request, mpi_reply,
1441 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1442 if (r)
1443 goto out;
1444
1445 mpi_request.PageAddress =
1446 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1447 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1448 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1449 r = _config_request(ioc, &mpi_request, mpi_reply,
1450 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1451 sizeof(*config_page));
1452 out:
1453 return r;
1454}
1455
1456/**
1457 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1458 * @ioc: per adapter object
1459 * @mpi_reply: reply mf payload returned from firmware
1460 * @config_page: contents of the config page
1461 * @form: GET_NEXT_HANDLE or HANDLE
1462 * @handle: expander handle
1463 * Context: sleep.
1464 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001465 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301466 */
1467int
1468mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1469 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1470{
1471 Mpi2ConfigRequest_t mpi_request;
1472 int r;
1473
1474 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1475 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1476 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1477 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1478 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1479 mpi_request.Header.PageNumber = 0;
1480 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1481 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1482 r = _config_request(ioc, &mpi_request, mpi_reply,
1483 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1484 if (r)
1485 goto out;
1486
1487 mpi_request.PageAddress = cpu_to_le32(form | handle);
1488 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1489 r = _config_request(ioc, &mpi_request, mpi_reply,
1490 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1491 sizeof(*config_page));
1492 out:
1493 return r;
1494}
1495
1496/**
1497 * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1498 * @ioc: per adapter object
1499 * @mpi_reply: reply mf payload returned from firmware
1500 * @config_page: contents of the config page
1501 * @phy_number: phy number
1502 * Context: sleep.
1503 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001504 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301505 */
1506int
1507mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1508 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1509{
1510 Mpi2ConfigRequest_t mpi_request;
1511 int r;
1512
1513 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1514 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1515 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1516 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1517 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1518 mpi_request.Header.PageNumber = 0;
1519 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1520 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1521 r = _config_request(ioc, &mpi_request, mpi_reply,
1522 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1523 if (r)
1524 goto out;
1525
1526 mpi_request.PageAddress =
1527 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1528 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1529 r = _config_request(ioc, &mpi_request, mpi_reply,
1530 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1531 sizeof(*config_page));
1532 out:
1533 return r;
1534}
1535
1536/**
1537 * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1538 * @ioc: per adapter object
1539 * @mpi_reply: reply mf payload returned from firmware
1540 * @config_page: contents of the config page
1541 * @phy_number: phy number
1542 * Context: sleep.
1543 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001544 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301545 */
1546int
1547mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1548 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1549{
1550 Mpi2ConfigRequest_t mpi_request;
1551 int r;
1552
1553 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1554 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1555 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1556 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1557 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1558 mpi_request.Header.PageNumber = 1;
1559 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1560 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1561 r = _config_request(ioc, &mpi_request, mpi_reply,
1562 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1563 if (r)
1564 goto out;
1565
1566 mpi_request.PageAddress =
1567 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1568 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1569 r = _config_request(ioc, &mpi_request, mpi_reply,
1570 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1571 sizeof(*config_page));
1572 out:
1573 return r;
1574}
1575
1576/**
1577 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1578 * @ioc: per adapter object
1579 * @mpi_reply: reply mf payload returned from firmware
1580 * @config_page: contents of the config page
1581 * @form: GET_NEXT_HANDLE or HANDLE
1582 * @handle: volume handle
1583 * Context: sleep.
1584 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001585 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301586 */
1587int
1588mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1589 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1590 u32 handle)
1591{
1592 Mpi2ConfigRequest_t mpi_request;
1593 int r;
1594
1595 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1596 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1597 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1598 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1599 mpi_request.Header.PageNumber = 1;
1600 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1601 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1602 r = _config_request(ioc, &mpi_request, mpi_reply,
1603 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1604 if (r)
1605 goto out;
1606
1607 mpi_request.PageAddress = cpu_to_le32(form | handle);
1608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1609 r = _config_request(ioc, &mpi_request, mpi_reply,
1610 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1611 sizeof(*config_page));
1612 out:
1613 return r;
1614}
1615
1616/**
1617 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1618 * @ioc: per adapter object
1619 * @handle: volume handle
1620 * @num_pds: returns pds count
1621 * Context: sleep.
1622 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001623 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301624 */
1625int
1626mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1627 u8 *num_pds)
1628{
1629 Mpi2ConfigRequest_t mpi_request;
1630 Mpi2RaidVolPage0_t config_page;
1631 Mpi2ConfigReply_t mpi_reply;
1632 int r;
1633 u16 ioc_status;
1634
1635 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1636 *num_pds = 0;
1637 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1638 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1639 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1640 mpi_request.Header.PageNumber = 0;
1641 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1642 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1643 r = _config_request(ioc, &mpi_request, &mpi_reply,
1644 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1645 if (r)
1646 goto out;
1647
1648 mpi_request.PageAddress =
1649 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1650 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1651 r = _config_request(ioc, &mpi_request, &mpi_reply,
1652 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1653 sizeof(Mpi2RaidVolPage0_t));
1654 if (!r) {
1655 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1656 MPI2_IOCSTATUS_MASK;
1657 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1658 *num_pds = config_page.NumPhysDisks;
1659 }
1660
1661 out:
1662 return r;
1663}
1664
1665/**
1666 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1667 * @ioc: per adapter object
1668 * @mpi_reply: reply mf payload returned from firmware
1669 * @config_page: contents of the config page
1670 * @form: GET_NEXT_HANDLE or HANDLE
1671 * @handle: volume handle
1672 * @sz: size of buffer passed in config_page
1673 * Context: sleep.
1674 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001675 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301676 */
1677int
1678mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1679 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1680 u32 handle, u16 sz)
1681{
1682 Mpi2ConfigRequest_t mpi_request;
1683 int r;
1684
1685 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1686 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1687 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1688 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1689 mpi_request.Header.PageNumber = 0;
1690 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
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.PageAddress = cpu_to_le32(form | handle);
1698 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1699 r = _config_request(ioc, &mpi_request, mpi_reply,
1700 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1701 out:
1702 return r;
1703}
1704
1705/**
1706 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1707 * @ioc: per adapter object
1708 * @mpi_reply: reply mf payload returned from firmware
1709 * @config_page: contents of the config page
1710 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1711 * @form_specific: specific to the form
1712 * Context: sleep.
1713 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07001714 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05301715 */
1716int
1717mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1718 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1719 u32 form_specific)
1720{
1721 Mpi2ConfigRequest_t mpi_request;
1722 int r;
1723
1724 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1725 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1726 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1727 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1728 mpi_request.Header.PageNumber = 0;
1729 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1730 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1731 r = _config_request(ioc, &mpi_request, mpi_reply,
1732 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1733 if (r)
1734 goto out;
1735
1736 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1737 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1738 r = _config_request(ioc, &mpi_request, mpi_reply,
1739 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1740 sizeof(*config_page));
1741 out:
1742 return r;
1743}
1744
1745/**
Suganath Prabu Saec93e82020-11-26 15:13:05 +05301746 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
1747 * @ioc: per adapter object
1748 * @mpi_reply: reply mf payload returned from firmware
1749 * @config_page: contents of the config page
1750 * Context: sleep.
1751 *
1752 * Returns 0 for success, non-zero for failure.
1753 */
1754int
1755mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1756 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1757{
1758 Mpi2ConfigRequest_t mpi_request;
1759 int r;
1760
1761 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1762 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1763 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1764 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1765 mpi_request.ExtPageType =
1766 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1767 mpi_request.Header.PageNumber = 0;
1768 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1769 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1770 r = _config_request(ioc, &mpi_request, mpi_reply,
1771 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1772 if (r)
1773 goto out;
1774
1775 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1776 r = _config_request(ioc, &mpi_request, mpi_reply,
1777 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1778 sizeof(*config_page));
1779 out:
1780 return r;
1781}
1782
1783/**
Lee Jonescf9e5752021-03-12 09:47:09 +00001784 * _config_set_driver_trigger_pg0 - write driver trigger page 0
Suganath Prabu Saec93e82020-11-26 15:13:05 +05301785 * @ioc: per adapter object
1786 * @mpi_reply: reply mf payload returned from firmware
1787 * @config_page: contents of the config page
1788 * Context: sleep.
1789 *
1790 * Returns 0 for success, non-zero for failure.
1791 */
1792static int
1793_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1794 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1795{
1796 Mpi2ConfigRequest_t mpi_request;
1797 int r;
1798
1799 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1800 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1801 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1802 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1803 mpi_request.ExtPageType =
1804 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1805 mpi_request.Header.PageNumber = 0;
1806 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1807 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1808 r = _config_request(ioc, &mpi_request, mpi_reply,
1809 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1810 if (r)
1811 goto out;
1812
1813 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1814 _config_request(ioc, &mpi_request, mpi_reply,
1815 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1816 sizeof(*config_page));
1817 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1818 r = _config_request(ioc, &mpi_request, mpi_reply,
1819 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1820 sizeof(*config_page));
1821 out:
1822 return r;
1823}
1824
1825/**
1826 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
1827 * @ioc: per adapter object
1828 * @trigger_flag: trigger type bit map
1829 * @set: set ot clear trigger values
1830 * Context: sleep.
1831 *
1832 * Returns 0 for success, non-zero for failure.
1833 */
1834static int
1835mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1836 u16 trigger_flag, bool set)
1837{
1838 Mpi26DriverTriggerPage0_t tg_pg0;
1839 Mpi2ConfigReply_t mpi_reply;
1840 int rc;
1841 u16 flags, ioc_status;
1842
1843 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1844 if (rc)
1845 return rc;
1846 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1847 MPI2_IOCSTATUS_MASK;
1848 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1849 dcprintk(ioc,
1850 ioc_err(ioc,
1851 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
1852 __func__, ioc_status));
1853 return -EFAULT;
1854 }
1855
1856 if (set)
1857 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
1858 else
1859 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
1860
1861 tg_pg0.TriggerFlags = cpu_to_le16(flags);
1862
1863 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1864 if (rc)
1865 return rc;
1866 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1867 MPI2_IOCSTATUS_MASK;
1868 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1869 dcprintk(ioc,
1870 ioc_err(ioc,
1871 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
1872 __func__, ioc_status));
1873 return -EFAULT;
1874 }
1875
1876 return 0;
1877}
1878
1879/**
Suganath Prabu Sbb855f22020-11-26 15:13:06 +05301880 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
1881 * @ioc: per adapter object
1882 * @mpi_reply: reply mf payload returned from firmware
1883 * @config_page: contents of the config page
1884 * Context: sleep.
1885 *
1886 * Returns 0 for success, non-zero for failure.
1887 */
1888int
1889mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1890 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1891{
1892 Mpi2ConfigRequest_t mpi_request;
1893 int r;
1894
1895 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1896 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1897 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1898 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1899 mpi_request.ExtPageType =
1900 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1901 mpi_request.Header.PageNumber = 1;
1902 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1903 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1904 r = _config_request(ioc, &mpi_request, mpi_reply,
1905 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1906 if (r)
1907 goto out;
1908
1909 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1910 r = _config_request(ioc, &mpi_request, mpi_reply,
1911 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1912 sizeof(*config_page));
1913 out:
1914 return r;
1915}
1916
1917/**
Lee Jonescf9e5752021-03-12 09:47:09 +00001918 * _config_set_driver_trigger_pg1 - write driver trigger page 1
Suganath Prabu Sbb855f22020-11-26 15:13:06 +05301919 * @ioc: per adapter object
1920 * @mpi_reply: reply mf payload returned from firmware
1921 * @config_page: contents of the config page
1922 * Context: sleep.
1923 *
1924 * Returns 0 for success, non-zero for failure.
1925 */
1926static int
1927_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1928 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1929{
1930 Mpi2ConfigRequest_t mpi_request;
1931 int r;
1932
1933 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1934 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1935 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1936 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1937 mpi_request.ExtPageType =
1938 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1939 mpi_request.Header.PageNumber = 1;
1940 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1941 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1942 r = _config_request(ioc, &mpi_request, mpi_reply,
1943 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1944 if (r)
1945 goto out;
1946
1947 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1948 _config_request(ioc, &mpi_request, mpi_reply,
1949 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1950 sizeof(*config_page));
1951 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1952 r = _config_request(ioc, &mpi_request, mpi_reply,
1953 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1954 sizeof(*config_page));
1955 out:
1956 return r;
1957}
1958
1959/**
1960 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
1961 * @ioc: per adapter object
1962 * @master_tg: Master trigger bit map
1963 * @set: set ot clear trigger values
1964 * Context: sleep.
1965 *
1966 * Returns 0 for success, non-zero for failure.
1967 */
1968int
1969mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1970 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
1971{
1972 Mpi26DriverTriggerPage1_t tg_pg1;
1973 Mpi2ConfigReply_t mpi_reply;
1974 int rc;
1975 u16 ioc_status;
1976
1977 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
1978 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
1979 if (rc)
1980 return rc;
1981
1982 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
1983 if (rc)
1984 goto out;
1985
1986 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1987 MPI2_IOCSTATUS_MASK;
1988 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1989 dcprintk(ioc,
1990 ioc_err(ioc,
1991 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
1992 __func__, ioc_status));
1993 rc = -EFAULT;
1994 goto out;
1995 }
1996
1997 if (set) {
1998 tg_pg1.NumMasterTrigger = cpu_to_le16(1);
1999 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
2000 master_tg->MasterData);
2001 } else {
2002 tg_pg1.NumMasterTrigger = 0;
2003 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
2004 }
2005
2006 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2007 if (rc)
2008 goto out;
2009
2010 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2011 MPI2_IOCSTATUS_MASK;
2012 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2013 dcprintk(ioc,
2014 ioc_err(ioc,
2015 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2016 __func__, ioc_status));
2017 rc = -EFAULT;
2018 goto out;
2019 }
2020
2021 return 0;
2022
2023out:
2024 mpt3sas_config_update_driver_trigger_pg0(ioc,
2025 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
2026
2027 return rc;
2028}
2029
2030/**
Suganath Prabu S71b3fb8f2020-11-26 15:13:07 +05302031 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
2032 * @ioc: per adapter object
2033 * @mpi_reply: reply mf payload returned from firmware
2034 * @config_page: contents of the config page
2035 * Context: sleep.
2036 *
2037 * Returns 0 for success, non-zero for failure.
2038 */
2039int
2040mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2041 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2042{
2043 Mpi2ConfigRequest_t mpi_request;
2044 int r;
2045
2046 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2047 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2048 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2049 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2050 mpi_request.ExtPageType =
2051 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2052 mpi_request.Header.PageNumber = 2;
2053 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2054 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2055 r = _config_request(ioc, &mpi_request, mpi_reply,
2056 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2057 if (r)
2058 goto out;
2059
2060 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2061 r = _config_request(ioc, &mpi_request, mpi_reply,
2062 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2063 sizeof(*config_page));
2064 out:
2065 return r;
2066}
2067
2068/**
Lee Jonescf9e5752021-03-12 09:47:09 +00002069 * _config_set_driver_trigger_pg2 - write driver trigger page 2
Suganath Prabu S71b3fb8f2020-11-26 15:13:07 +05302070 * @ioc: per adapter object
2071 * @mpi_reply: reply mf payload returned from firmware
2072 * @config_page: contents of the config page
2073 * Context: sleep.
2074 *
2075 * Returns 0 for success, non-zero for failure.
2076 */
2077static int
2078_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2079 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2080{
2081 Mpi2ConfigRequest_t mpi_request;
2082 int r;
2083
2084 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2085 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2086 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2087 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2088 mpi_request.ExtPageType =
2089 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2090 mpi_request.Header.PageNumber = 2;
2091 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2092 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2093 r = _config_request(ioc, &mpi_request, mpi_reply,
2094 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2095 if (r)
2096 goto out;
2097
2098 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2099 _config_request(ioc, &mpi_request, mpi_reply,
2100 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2101 sizeof(*config_page));
2102 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2103 r = _config_request(ioc, &mpi_request, mpi_reply,
2104 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2105 sizeof(*config_page));
2106 out:
2107 return r;
2108}
2109
2110/**
2111 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
2112 * @ioc: per adapter object
2113 * @event_tg: list of Event Triggers
2114 * @set: set ot clear trigger values
2115 * Context: sleep.
2116 *
2117 * Returns 0 for success, non-zero for failure.
2118 */
2119int
2120mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2121 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
2122{
2123 Mpi26DriverTriggerPage2_t tg_pg2;
2124 Mpi2ConfigReply_t mpi_reply;
2125 int rc, i, count;
2126 u16 ioc_status;
2127
2128 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2129 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
2130 if (rc)
2131 return rc;
2132
2133 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2134 if (rc)
2135 goto out;
2136
2137 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2138 MPI2_IOCSTATUS_MASK;
2139 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2140 dcprintk(ioc,
2141 ioc_err(ioc,
2142 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2143 __func__, ioc_status));
2144 rc = -EFAULT;
2145 goto out;
2146 }
2147
2148 if (set) {
2149 count = event_tg->ValidEntries;
2150 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
2151 for (i = 0; i < count; i++) {
2152 tg_pg2.MPIEventTriggers[i].MPIEventCode =
2153 cpu_to_le16(
2154 event_tg->EventTriggerEntry[i].EventValue);
2155 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
2156 cpu_to_le16(
2157 event_tg->EventTriggerEntry[i].LogEntryQualifier);
2158 }
2159 } else {
2160 tg_pg2.NumMPIEventTrigger = 0;
2161 memset(&tg_pg2.MPIEventTriggers[0], 0,
2162 NUM_VALID_ENTRIES * sizeof(
2163 MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY));
2164 }
2165
2166 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2167 if (rc)
2168 goto out;
2169
2170 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2171 MPI2_IOCSTATUS_MASK;
2172 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2173 dcprintk(ioc,
2174 ioc_err(ioc,
2175 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2176 __func__, ioc_status));
2177 rc = -EFAULT;
2178 goto out;
2179 }
2180
2181 return 0;
2182
2183out:
2184 mpt3sas_config_update_driver_trigger_pg0(ioc,
2185 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
2186
2187 return rc;
2188}
2189
2190/**
Suganath Prabu S2a5c3a32020-11-26 15:13:08 +05302191 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
2192 * @ioc: per adapter object
2193 * @mpi_reply: reply mf payload returned from firmware
2194 * @config_page: contents of the config page
2195 * Context: sleep.
2196 *
2197 * Returns 0 for success, non-zero for failure.
2198 */
2199int
2200mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2201 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2202{
2203 Mpi2ConfigRequest_t mpi_request;
2204 int r;
2205
2206 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2207 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2208 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2209 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2210 mpi_request.ExtPageType =
2211 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2212 mpi_request.Header.PageNumber = 3;
2213 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2214 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2215 r = _config_request(ioc, &mpi_request, mpi_reply,
2216 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2217 if (r)
2218 goto out;
2219
2220 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2221 r = _config_request(ioc, &mpi_request, mpi_reply,
2222 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2223 sizeof(*config_page));
2224 out:
2225 return r;
2226}
2227
2228/**
Lee Jonescf9e5752021-03-12 09:47:09 +00002229 * _config_set_driver_trigger_pg3 - write driver trigger page 3
Suganath Prabu S2a5c3a32020-11-26 15:13:08 +05302230 * @ioc: per adapter object
2231 * @mpi_reply: reply mf payload returned from firmware
2232 * @config_page: contents of the config page
2233 * Context: sleep.
2234 *
2235 * Returns 0 for success, non-zero for failure.
2236 */
2237static int
2238_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2239 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2240{
2241 Mpi2ConfigRequest_t mpi_request;
2242 int r;
2243
2244 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2245 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2246 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2247 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2248 mpi_request.ExtPageType =
2249 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2250 mpi_request.Header.PageNumber = 3;
2251 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2252 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2253 r = _config_request(ioc, &mpi_request, mpi_reply,
2254 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2255 if (r)
2256 goto out;
2257
2258 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2259 _config_request(ioc, &mpi_request, mpi_reply,
2260 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2261 sizeof(*config_page));
2262 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2263 r = _config_request(ioc, &mpi_request, mpi_reply,
2264 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2265 sizeof(*config_page));
2266 out:
2267 return r;
2268}
2269
2270/**
2271 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
2272 * @ioc: per adapter object
2273 * @scsi_tg: scsi trigger list
2274 * @set: set ot clear trigger values
2275 * Context: sleep.
2276 *
2277 * Returns 0 for success, non-zero for failure.
2278 */
2279int
2280mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2281 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
2282{
2283 Mpi26DriverTriggerPage3_t tg_pg3;
2284 Mpi2ConfigReply_t mpi_reply;
2285 int rc, i, count;
2286 u16 ioc_status;
2287
2288 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2289 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
2290 if (rc)
2291 return rc;
2292
2293 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2294 if (rc)
2295 goto out;
2296
2297 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2298 MPI2_IOCSTATUS_MASK;
2299 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2300 dcprintk(ioc,
2301 ioc_err(ioc,
2302 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2303 __func__, ioc_status));
2304 return -EFAULT;
2305 }
2306
2307 if (set) {
2308 count = scsi_tg->ValidEntries;
2309 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
2310 for (i = 0; i < count; i++) {
2311 tg_pg3.SCSISenseTriggers[i].ASCQ =
2312 scsi_tg->SCSITriggerEntry[i].ASCQ;
2313 tg_pg3.SCSISenseTriggers[i].ASC =
2314 scsi_tg->SCSITriggerEntry[i].ASC;
2315 tg_pg3.SCSISenseTriggers[i].SenseKey =
2316 scsi_tg->SCSITriggerEntry[i].SenseKey;
2317 }
2318 } else {
2319 tg_pg3.NumSCSISenseTrigger = 0;
2320 memset(&tg_pg3.SCSISenseTriggers[0], 0,
2321 NUM_VALID_ENTRIES * sizeof(
2322 MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY));
2323 }
2324
2325 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2326 if (rc)
2327 goto out;
2328
2329 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2330 MPI2_IOCSTATUS_MASK;
2331 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2332 dcprintk(ioc,
2333 ioc_err(ioc,
2334 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2335 __func__, ioc_status));
2336 return -EFAULT;
2337 }
2338
2339 return 0;
2340out:
2341 mpt3sas_config_update_driver_trigger_pg0(ioc,
2342 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
2343
2344 return rc;
2345}
2346
2347/**
Suganath Prabu S0e17a872020-11-26 15:13:09 +05302348 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
2349 * @ioc: per adapter object
2350 * @mpi_reply: reply mf payload returned from firmware
2351 * @config_page: contents of the config page
2352 * Context: sleep.
2353 *
2354 * Returns 0 for success, non-zero for failure.
2355 */
2356int
2357mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2358 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2359{
2360 Mpi2ConfigRequest_t mpi_request;
2361 int r;
2362
2363 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2364 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2365 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2366 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2367 mpi_request.ExtPageType =
2368 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2369 mpi_request.Header.PageNumber = 4;
2370 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2371 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2372 r = _config_request(ioc, &mpi_request, mpi_reply,
2373 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2374 if (r)
2375 goto out;
2376
2377 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2378 r = _config_request(ioc, &mpi_request, mpi_reply,
2379 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2380 sizeof(*config_page));
2381 out:
2382 return r;
2383}
2384
2385/**
Lee Jonescf9e5752021-03-12 09:47:09 +00002386 * _config_set_driver_trigger_pg4 - write driver trigger page 4
Suganath Prabu S0e17a872020-11-26 15:13:09 +05302387 * @ioc: per adapter object
2388 * @mpi_reply: reply mf payload returned from firmware
2389 * @config_page: contents of the config page
2390 * Context: sleep.
2391 *
2392 * Returns 0 for success, non-zero for failure.
2393 */
2394static int
2395_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2396 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2397{
2398 Mpi2ConfigRequest_t mpi_request;
2399 int r;
2400
2401 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2402 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2403 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2404 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2405 mpi_request.ExtPageType =
2406 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2407 mpi_request.Header.PageNumber = 4;
2408 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2409 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2410 r = _config_request(ioc, &mpi_request, mpi_reply,
2411 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2412 if (r)
2413 goto out;
2414
2415 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2416 _config_request(ioc, &mpi_request, mpi_reply,
2417 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2418 sizeof(*config_page));
2419 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2420 r = _config_request(ioc, &mpi_request, mpi_reply,
2421 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2422 sizeof(*config_page));
2423 out:
2424 return r;
2425}
2426
2427/**
2428 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
2429 * @ioc: per adapter object
2430 * @mpi_tg: mpi trigger list
2431 * @set: set ot clear trigger values
2432 * Context: sleep.
2433 *
2434 * Returns 0 for success, non-zero for failure.
2435 */
2436int
2437mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2438 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
2439{
2440 Mpi26DriverTriggerPage4_t tg_pg4;
2441 Mpi2ConfigReply_t mpi_reply;
2442 int rc, i, count;
2443 u16 ioc_status;
2444
2445 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2446 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
2447 if (rc)
2448 return rc;
2449
2450 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2451 if (rc)
2452 goto out;
2453
2454 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2455 MPI2_IOCSTATUS_MASK;
2456 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2457 dcprintk(ioc,
2458 ioc_err(ioc,
2459 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2460 __func__, ioc_status));
2461 rc = -EFAULT;
2462 goto out;
2463 }
2464
2465 if (set) {
2466 count = mpi_tg->ValidEntries;
2467 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
2468 for (i = 0; i < count; i++) {
2469 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
2470 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
2471 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
2472 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
2473 }
2474 } else {
2475 tg_pg4.NumIOCStatusLogInfoTrigger = 0;
2476 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
2477 NUM_VALID_ENTRIES * sizeof(
2478 MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY));
2479 }
2480
2481 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2482 if (rc)
2483 goto out;
2484
2485 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2486 MPI2_IOCSTATUS_MASK;
2487 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2488 dcprintk(ioc,
2489 ioc_err(ioc,
2490 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2491 __func__, ioc_status));
2492 rc = -EFAULT;
2493 goto out;
2494 }
2495
2496 return 0;
2497
2498out:
2499 mpt3sas_config_update_driver_trigger_pg0(ioc,
2500 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
2501
2502 return rc;
2503}
2504
2505/**
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302506 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
2507 * raid components
2508 * @ioc: per adapter object
2509 * @pd_handle: phys disk handle
2510 * @volume_handle: volume handle
2511 * Context: sleep.
2512 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07002513 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302514 */
2515int
2516mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
2517 u16 *volume_handle)
2518{
2519 Mpi2RaidConfigurationPage0_t *config_page = NULL;
2520 Mpi2ConfigRequest_t mpi_request;
2521 Mpi2ConfigReply_t mpi_reply;
2522 int r, i, config_page_sz;
2523 u16 ioc_status;
2524 int config_num;
2525 u16 element_type;
2526 u16 phys_disk_dev_handle;
2527
2528 *volume_handle = 0;
2529 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2530 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2531 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2532 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2533 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
2534 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
2535 mpi_request.Header.PageNumber = 0;
2536 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2537 r = _config_request(ioc, &mpi_request, &mpi_reply,
2538 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2539 if (r)
2540 goto out;
2541
2542 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2543 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
2544 config_page = kmalloc(config_page_sz, GFP_KERNEL);
2545 if (!config_page) {
2546 r = -1;
2547 goto out;
2548 }
2549
2550 config_num = 0xff;
2551 while (1) {
2552 mpi_request.PageAddress = cpu_to_le32(config_num +
2553 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
2554 r = _config_request(ioc, &mpi_request, &mpi_reply,
2555 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2556 config_page_sz);
2557 if (r)
2558 goto out;
2559 r = -1;
2560 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2561 MPI2_IOCSTATUS_MASK;
2562 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
2563 goto out;
2564 for (i = 0; i < config_page->NumElements; i++) {
2565 element_type = le16_to_cpu(config_page->
2566 ConfigElement[i].ElementFlags) &
2567 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
2568 if (element_type ==
2569 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
2570 element_type ==
2571 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
2572 phys_disk_dev_handle =
2573 le16_to_cpu(config_page->ConfigElement[i].
2574 PhysDiskDevHandle);
2575 if (phys_disk_dev_handle == pd_handle) {
2576 *volume_handle =
2577 le16_to_cpu(config_page->
2578 ConfigElement[i].VolDevHandle);
2579 r = 0;
2580 goto out;
2581 }
2582 } else if (element_type ==
2583 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
2584 *volume_handle = 0;
2585 r = 0;
2586 goto out;
2587 }
2588 }
2589 config_num = config_page->ConfigNum;
2590 }
2591 out:
2592 kfree(config_page);
2593 return r;
2594}
2595
2596/**
2597 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
2598 * @ioc: per adapter object
2599 * @volume_handle: volume handle
2600 * @wwid: volume wwid
2601 * Context: sleep.
2602 *
Bart Van Assche4beb4862018-06-15 14:42:01 -07002603 * Return: 0 for success, non-zero for failure.
Sreekanth Reddyf92363d2012-11-30 07:44:21 +05302604 */
2605int
2606mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
2607 u64 *wwid)
2608{
2609 Mpi2ConfigReply_t mpi_reply;
2610 Mpi2RaidVolPage1_t raid_vol_pg1;
2611
2612 *wwid = 0;
2613 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
2614 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
2615 volume_handle))) {
2616 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
2617 return 0;
2618 } else
2619 return -1;
2620}