1 /*
2 * This module provides common API for accessing firmware configuration pages
3 *
4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
5 * Copyright (C) 2012-2014 LSI Corporation
6 * Copyright (C) 2013-2014 Avago Technologies
7 * (mailto: MPT-FusionLinux.pdl@avagotech.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
45 #include <linux/module.h>
46 #include <linux/kernel.h>
47 #include <linux/init.h>
48 #include <linux/errno.h>
49 #include <linux/blkdev.h>
50 #include <linux/sched.h>
51 #include <linux/workqueue.h>
52 #include <linux/delay.h>
53 #include <linux/pci.h>
54
55 #include "mpt3sas_base.h"
56
57 /* local definitions */
58
59 /* Timeout for config page request (in seconds) */
60 #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15
61
62 /* Common sgl flags for READING a config page. */
63 #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
64 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
65 | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
66
67 /* Common sgl flags for WRITING a config page. */
68 #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
69 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
70 | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
71 << MPI2_SGE_FLAGS_SHIFT)
72
73 /**
74 * struct config_request - obtain dma memory via routine
75 * @sz: size
76 * @page: virt pointer
77 * @page_dma: phys pointer
78 *
79 */
80 struct config_request {
81 u16 sz;
82 void *page;
83 dma_addr_t page_dma;
84 };
85
86 /**
87 * _config_display_some_debug - debug routine
88 * @ioc: per adapter object
89 * @smid: system request message index
90 * @calling_function_name: string pass from calling function
91 * @mpi_reply: reply message frame
92 * Context: none.
93 *
94 * Function for displaying debug info helpful when debugging issues
95 * in this module.
96 */
97 static void
_config_display_some_debug(struct MPT3SAS_ADAPTER * ioc,u16 smid,char * calling_function_name,MPI2DefaultReply_t * mpi_reply)98 _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
99 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
100 {
101 Mpi2ConfigRequest_t *mpi_request;
102 char *desc = NULL;
103
104 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:
119 desc = "manufacturing";
120 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:
148 desc = "driver_mapping";
149 break;
150 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;
168 }
169 break;
170 }
171
172 if (!desc)
173 return;
174
175 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);
179
180 if (!mpi_reply)
181 return;
182
183 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
184 ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
185 le16_to_cpu(mpi_reply->IOCStatus),
186 le32_to_cpu(mpi_reply->IOCLogInfo));
187 }
188
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 *
196 * Return: 0 for success, non-zero for failure.
197 */
198 static int
_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER * ioc,struct config_request * mem)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) {
208 ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
209 __func__, mem->sz);
210 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 }
216 ioc->config_vaddr = mem->page;
217 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 *
227 * Return: 0 for success, non-zero for failure.
228 */
229 static void
_config_free_config_dma_memory(struct MPT3SAS_ADAPTER * ioc,struct config_request * mem)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 *
248 * Return: 1 meaning mf should be freed from _base_interrupt
249 * 0 means the mf is freed from this function.
250 */
251 u8
mpt3sas_config_done(struct MPT3SAS_ADAPTER * ioc,u16 smid,u8 msix_index,u32 reply)252 mpt3sas_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;
269 if (ioc->logging_level & MPT_DEBUG_CONFIG)
270 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
271 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 *
293 * Return: 0 for success, non-zero for failure.
294 */
295 static int
_config_request(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigRequest_t * mpi_request,Mpi2ConfigReply_t * mpi_reply,int timeout,void * config_page,u16 config_page_sz)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;
301 Mpi2ConfigRequest_t *config_request;
302 int r;
303 u8 retry_count, issue_host_reset = 0;
304 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) {
309 ioc_err(ioc, "%s: config_cmd in use\n", __func__);
310 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 }
357 ioc_info(ioc, "%s: attempting retry (%d)\n",
358 __func__, retry_count);
359 }
360
361 r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
362 if (r) {
363 if (r == -ETIME)
364 issue_host_reset = 1;
365 goto free_mem;
366 }
367
368 smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
369 if (!smid) {
370 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
371 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
372 r = -EAGAIN;
373 goto free_mem;
374 }
375
376 r = 0;
377 memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
378 ioc->config_cmds.status = MPT3_CMD_PENDING;
379 config_request = mpt3sas_base_get_msg_frame(ioc, smid);
380 ioc->config_cmds.smid = smid;
381 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
382 if (ioc->logging_level & MPT_DEBUG_CONFIG)
383 _config_display_some_debug(ioc, smid, "config_request", NULL);
384 init_completion(&ioc->config_cmds.done);
385 ioc->put_smid_default(ioc, smid);
386 wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
387 if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
388 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
389 _config_display_some_debug(ioc,
390 smid, "config_request", NULL);
391 ioc_err(ioc, "%s: command timeout\n", __func__);
392 mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
393 mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
394 retry_count++;
395 if (ioc->config_cmds.smid == smid)
396 mpt3sas_base_free_smid(ioc, smid);
397 if (ioc->config_cmds.status & MPT3_CMD_RESET)
398 goto retry_config;
399 if (ioc->shost_recovery || ioc->pci_error_recovery) {
400 issue_host_reset = 0;
401 r = -EFAULT;
402 } else
403 issue_host_reset = 1;
404 goto free_mem;
405 }
406
407 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
408 memcpy(mpi_reply, ioc->config_cmds.reply,
409 sizeof(Mpi2ConfigReply_t));
410
411 /* Reply Frame Sanity Checks to workaround FW issues */
412 if ((mpi_request->Header.PageType & 0xF) !=
413 (mpi_reply->Header.PageType & 0xF)) {
414 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
415 _config_display_some_debug(ioc,
416 smid, "config_request", NULL);
417 _debug_dump_mf(mpi_request, ioc->request_sz/4);
418 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
419 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
420 ioc->name, __func__,
421 mpi_request->Header.PageType & 0xF,
422 mpi_reply->Header.PageType & 0xF);
423 }
424
425 if (((mpi_request->Header.PageType & 0xF) ==
426 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
427 mpi_request->ExtPageType != mpi_reply->ExtPageType) {
428 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
429 _config_display_some_debug(ioc,
430 smid, "config_request", NULL);
431 _debug_dump_mf(mpi_request, ioc->request_sz/4);
432 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
433 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
434 ioc->name, __func__,
435 mpi_request->ExtPageType,
436 mpi_reply->ExtPageType);
437 }
438 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
439 & MPI2_IOCSTATUS_MASK;
440 }
441
442 if (retry_count)
443 ioc_info(ioc, "%s: retry (%d) completed!!\n",
444 __func__, retry_count);
445
446 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
447 config_page && mpi_request->Action ==
448 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
449 u8 *p = (u8 *)mem.page;
450
451 /* Config Page Sanity Checks to workaround FW issues */
452 if (p) {
453 if ((mpi_request->Header.PageType & 0xF) !=
454 (p[3] & 0xF)) {
455 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
456 _config_display_some_debug(ioc,
457 smid, "config_request", NULL);
458 _debug_dump_mf(mpi_request, ioc->request_sz/4);
459 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
460 _debug_dump_config(p, min_t(u16, mem.sz,
461 config_page_sz)/4);
462 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
463 ioc->name, __func__,
464 mpi_request->Header.PageType & 0xF,
465 p[3] & 0xF);
466 }
467
468 if (((mpi_request->Header.PageType & 0xF) ==
469 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
470 (mpi_request->ExtPageType != p[6])) {
471 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
472 _config_display_some_debug(ioc,
473 smid, "config_request", NULL);
474 _debug_dump_mf(mpi_request, ioc->request_sz/4);
475 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
476 _debug_dump_config(p, min_t(u16, mem.sz,
477 config_page_sz)/4);
478 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
479 ioc->name, __func__,
480 mpi_request->ExtPageType, p[6]);
481 }
482 }
483 memcpy(config_page, mem.page, min_t(u16, mem.sz,
484 config_page_sz));
485 }
486
487 free_mem:
488 if (config_page)
489 _config_free_config_dma_memory(ioc, &mem);
490 out:
491 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
492 mutex_unlock(&ioc->config_cmds.mutex);
493
494 if (issue_host_reset) {
495 if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {
496 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
497 r = -EFAULT;
498 } else {
499 if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))
500 return -EFAULT;
501 r = -EAGAIN;
502 }
503 }
504 return r;
505 }
506
507 /**
508 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
509 * @ioc: per adapter object
510 * @mpi_reply: reply mf payload returned from firmware
511 * @config_page: contents of the config page
512 * Context: sleep.
513 *
514 * Return: 0 for success, non-zero for failure.
515 */
516 int
mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ManufacturingPage0_t * config_page)517 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
518 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
519 {
520 Mpi2ConfigRequest_t mpi_request;
521 int r;
522
523 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
524 mpi_request.Function = MPI2_FUNCTION_CONFIG;
525 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
526 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
527 mpi_request.Header.PageNumber = 0;
528 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
529 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
530 r = _config_request(ioc, &mpi_request, mpi_reply,
531 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
532 if (r)
533 goto out;
534
535 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
536 r = _config_request(ioc, &mpi_request, mpi_reply,
537 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
538 sizeof(*config_page));
539 out:
540 return r;
541 }
542
543 /**
544 * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1
545 * @ioc: per adapter object
546 * @mpi_reply: reply mf payload returned from firmware
547 * @config_page: contents of the config page
548 * Context: sleep.
549 *
550 * Return: 0 for success, non-zero for failure.
551 */
552 int
mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ManufacturingPage1_t * config_page)553 mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc,
554 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page)
555 {
556 Mpi2ConfigRequest_t mpi_request;
557 int r;
558
559 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
560 mpi_request.Function = MPI2_FUNCTION_CONFIG;
561 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
562 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
563 mpi_request.Header.PageNumber = 1;
564 mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION;
565 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
566 r = _config_request(ioc, &mpi_request, mpi_reply,
567 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
568 if (r)
569 goto out;
570
571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
572 r = _config_request(ioc, &mpi_request, mpi_reply,
573 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
574 sizeof(*config_page));
575 out:
576 return r;
577 }
578
579 /**
580 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
581 * @ioc: per adapter object
582 * @mpi_reply: reply mf payload returned from firmware
583 * @config_page: contents of the config page
584 * Context: sleep.
585 *
586 * Return: 0 for success, non-zero for failure.
587 */
588 int
mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage10_t * config_page)589 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
590 Mpi2ConfigReply_t *mpi_reply,
591 struct Mpi2ManufacturingPage10_t *config_page)
592 {
593 Mpi2ConfigRequest_t mpi_request;
594 int r;
595
596 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
597 mpi_request.Function = MPI2_FUNCTION_CONFIG;
598 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
599 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
600 mpi_request.Header.PageNumber = 10;
601 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
602 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
603 r = _config_request(ioc, &mpi_request, mpi_reply,
604 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
605 if (r)
606 goto out;
607
608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
609 r = _config_request(ioc, &mpi_request, mpi_reply,
610 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
611 sizeof(*config_page));
612 out:
613 return r;
614 }
615
616 /**
617 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
618 * @ioc: per adapter object
619 * @mpi_reply: reply mf payload returned from firmware
620 * @config_page: contents of the config page
621 * Context: sleep.
622 *
623 * Return: 0 for success, non-zero for failure.
624 */
625 int
mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage11_t * config_page)626 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
627 Mpi2ConfigReply_t *mpi_reply,
628 struct Mpi2ManufacturingPage11_t *config_page)
629 {
630 Mpi2ConfigRequest_t mpi_request;
631 int r;
632
633 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
634 mpi_request.Function = MPI2_FUNCTION_CONFIG;
635 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
636 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
637 mpi_request.Header.PageNumber = 11;
638 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
639 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
640 r = _config_request(ioc, &mpi_request, mpi_reply,
641 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
642 if (r)
643 goto out;
644
645 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
646 r = _config_request(ioc, &mpi_request, mpi_reply,
647 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
648 sizeof(*config_page));
649 out:
650 return r;
651 }
652
653 /**
654 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
655 * @ioc: per adapter object
656 * @mpi_reply: reply mf payload returned from firmware
657 * @config_page: contents of the config page
658 * Context: sleep.
659 *
660 * Return: 0 for success, non-zero for failure.
661 */
662 int
mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage11_t * config_page)663 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
664 Mpi2ConfigReply_t *mpi_reply,
665 struct Mpi2ManufacturingPage11_t *config_page)
666 {
667 Mpi2ConfigRequest_t mpi_request;
668 int r;
669
670 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
671 mpi_request.Function = MPI2_FUNCTION_CONFIG;
672 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
673 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
674 mpi_request.Header.PageNumber = 11;
675 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
676 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
677 r = _config_request(ioc, &mpi_request, mpi_reply,
678 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
679 if (r)
680 goto out;
681
682 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
683 r = _config_request(ioc, &mpi_request, mpi_reply,
684 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
685 sizeof(*config_page));
686 out:
687 return r;
688 }
689
690 /**
691 * mpt3sas_config_get_bios_pg2 - obtain bios page 2
692 * @ioc: per adapter object
693 * @mpi_reply: reply mf payload returned from firmware
694 * @config_page: contents of the config page
695 * Context: sleep.
696 *
697 * Return: 0 for success, non-zero for failure.
698 */
699 int
mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage2_t * config_page)700 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
701 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
702 {
703 Mpi2ConfigRequest_t mpi_request;
704 int r;
705
706 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
707 mpi_request.Function = MPI2_FUNCTION_CONFIG;
708 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
709 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
710 mpi_request.Header.PageNumber = 2;
711 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
712 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
713 r = _config_request(ioc, &mpi_request, mpi_reply,
714 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
715 if (r)
716 goto out;
717
718 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
719 r = _config_request(ioc, &mpi_request, mpi_reply,
720 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
721 sizeof(*config_page));
722 out:
723 return r;
724 }
725
726 /**
727 * mpt3sas_config_get_bios_pg3 - obtain bios page 3
728 * @ioc: per adapter object
729 * @mpi_reply: reply mf payload returned from firmware
730 * @config_page: contents of the config page
731 * Context: sleep.
732 *
733 * Return: 0 for success, non-zero for failure.
734 */
735 int
mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage3_t * config_page)736 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
737 *mpi_reply, Mpi2BiosPage3_t *config_page)
738 {
739 Mpi2ConfigRequest_t mpi_request;
740 int r;
741
742 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
743 mpi_request.Function = MPI2_FUNCTION_CONFIG;
744 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
745 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
746 mpi_request.Header.PageNumber = 3;
747 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
748 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
749 r = _config_request(ioc, &mpi_request, mpi_reply,
750 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
751 if (r)
752 goto out;
753
754 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
755 r = _config_request(ioc, &mpi_request, mpi_reply,
756 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
757 sizeof(*config_page));
758
759 out:
760 return r;
761 }
762
763 /**
764 * mpt3sas_config_set_bios_pg4 - write out bios page 4
765 * @ioc: per adapter object
766 * @mpi_reply: reply mf payload returned from firmware
767 * @config_page: contents of the config page
768 * @sz_config_pg: sizeof the config page
769 * Context: sleep.
770 *
771 * Return: 0 for success, non-zero for failure.
772 */
773 int
mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage4_t * config_page,int sz_config_pg)774 mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
775 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
776 int sz_config_pg)
777 {
778 Mpi2ConfigRequest_t mpi_request;
779 int r;
780
781 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
782
783 mpi_request.Function = MPI2_FUNCTION_CONFIG;
784 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
785 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
786 mpi_request.Header.PageNumber = 4;
787 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;
788
789 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
790
791 r = _config_request(ioc, &mpi_request, mpi_reply,
792 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
793 if (r)
794 goto out;
795
796 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
797 r = _config_request(ioc, &mpi_request, mpi_reply,
798 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
799 sz_config_pg);
800 out:
801 return r;
802 }
803
804 /**
805 * mpt3sas_config_get_bios_pg4 - read bios page 4
806 * @ioc: per adapter object
807 * @mpi_reply: reply mf payload returned from firmware
808 * @config_page: contents of the config page
809 * @sz_config_pg: sizeof the config page
810 * Context: sleep.
811 *
812 * Return: 0 for success, non-zero for failure.
813 */
814 int
mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage4_t * config_page,int sz_config_pg)815 mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
816 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
817 int sz_config_pg)
818 {
819 Mpi2ConfigRequest_t mpi_request;
820 int r;
821
822 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
823 mpi_request.Function = MPI2_FUNCTION_CONFIG;
824 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
825 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
826 mpi_request.Header.PageNumber = 4;
827 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;
828 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
829 r = _config_request(ioc, &mpi_request, mpi_reply,
830 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
831 if (r)
832 goto out;
833
834 /*
835 * The sizeof the page is variable. Allow for just the
836 * size to be returned
837 */
838 if (config_page && sz_config_pg) {
839 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
840
841 r = _config_request(ioc, &mpi_request, mpi_reply,
842 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
843 sz_config_pg);
844 }
845
846 out:
847 return r;
848 }
849
850 /**
851 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
852 * @ioc: per adapter object
853 * @mpi_reply: reply mf payload returned from firmware
854 * @config_page: contents of the config page
855 * Context: sleep.
856 *
857 * Return: 0 for success, non-zero for failure.
858 */
859 int
mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage0_t * config_page)860 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
861 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
862 {
863 Mpi2ConfigRequest_t mpi_request;
864 int r;
865
866 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
867 mpi_request.Function = MPI2_FUNCTION_CONFIG;
868 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
869 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
870 mpi_request.Header.PageNumber = 0;
871 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
872 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
873 r = _config_request(ioc, &mpi_request, mpi_reply,
874 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
875 if (r)
876 goto out;
877
878 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
879 r = _config_request(ioc, &mpi_request, mpi_reply,
880 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
881 sizeof(*config_page));
882 out:
883 return r;
884 }
885
886 /**
887 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
888 * @ioc: per adapter object
889 * @mpi_reply: reply mf payload returned from firmware
890 * @config_page: contents of the config page
891 * Context: sleep.
892 *
893 * Return: 0 for success, non-zero for failure.
894 */
895 int
mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage1_t * config_page)896 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
897 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
898 {
899 Mpi2ConfigRequest_t mpi_request;
900 int r;
901
902 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
903 mpi_request.Function = MPI2_FUNCTION_CONFIG;
904 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
905 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
906 mpi_request.Header.PageNumber = 1;
907 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
908 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
909 r = _config_request(ioc, &mpi_request, mpi_reply,
910 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
911 if (r)
912 goto out;
913
914 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
915 r = _config_request(ioc, &mpi_request, mpi_reply,
916 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
917 sizeof(*config_page));
918 out:
919 return r;
920 }
921
922 /**
923 * mpt3sas_config_set_iounit_pg1 - set iounit page 1
924 * @ioc: per adapter object
925 * @mpi_reply: reply mf payload returned from firmware
926 * @config_page: contents of the config page
927 * Context: sleep.
928 *
929 * Return: 0 for success, non-zero for failure.
930 */
931 int
mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage1_t * config_page)932 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
933 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
934 {
935 Mpi2ConfigRequest_t mpi_request;
936 int r;
937
938 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
939 mpi_request.Function = MPI2_FUNCTION_CONFIG;
940 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
941 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
942 mpi_request.Header.PageNumber = 1;
943 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
944 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
945 r = _config_request(ioc, &mpi_request, mpi_reply,
946 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
947 if (r)
948 goto out;
949
950 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
951 r = _config_request(ioc, &mpi_request, mpi_reply,
952 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
953 sizeof(*config_page));
954 out:
955 return r;
956 }
957
958 /**
959 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
960 * @ioc: per adapter object
961 * @mpi_reply: reply mf payload returned from firmware
962 * @config_page: contents of the config page
963 * @sz: size of buffer passed in config_page
964 * Context: sleep.
965 *
966 * Return: 0 for success, non-zero for failure.
967 */
968 int
mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage3_t * config_page,u16 sz)969 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
970 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
971 {
972 Mpi2ConfigRequest_t mpi_request;
973 int r;
974
975 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
976 mpi_request.Function = MPI2_FUNCTION_CONFIG;
977 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
978 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
979 mpi_request.Header.PageNumber = 3;
980 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
981 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
982 r = _config_request(ioc, &mpi_request, mpi_reply,
983 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
984 if (r)
985 goto out;
986
987 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
988 r = _config_request(ioc, &mpi_request, mpi_reply,
989 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
990 out:
991 return r;
992 }
993
994 /**
995 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
996 * @ioc: per adapter object
997 * @mpi_reply: reply mf payload returned from firmware
998 * @config_page: contents of the config page
999 * Context: sleep.
1000 *
1001 * Return: 0 for success, non-zero for failure.
1002 */
1003 int
mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage8_t * config_page)1004 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
1005 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
1006 {
1007 Mpi2ConfigRequest_t mpi_request;
1008 int r;
1009
1010 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1011 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1012 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1013 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
1014 mpi_request.Header.PageNumber = 8;
1015 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
1016 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1017 r = _config_request(ioc, &mpi_request, mpi_reply,
1018 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1019 if (r)
1020 goto out;
1021
1022 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1023 r = _config_request(ioc, &mpi_request, mpi_reply,
1024 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1025 sizeof(*config_page));
1026 out:
1027 return r;
1028 }
1029
1030 /**
1031 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
1032 * @ioc: per adapter object
1033 * @mpi_reply: reply mf payload returned from firmware
1034 * @config_page: contents of the config page
1035 * Context: sleep.
1036 *
1037 * Return: 0 for success, non-zero for failure.
1038 */
1039 int
mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage8_t * config_page)1040 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
1041 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
1042 {
1043 Mpi2ConfigRequest_t mpi_request;
1044 int r;
1045
1046 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1047 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1048 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1049 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1050 mpi_request.Header.PageNumber = 8;
1051 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1052 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1053 r = _config_request(ioc, &mpi_request, mpi_reply,
1054 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1055 if (r)
1056 goto out;
1057
1058 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1059 r = _config_request(ioc, &mpi_request, mpi_reply,
1060 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1061 sizeof(*config_page));
1062 out:
1063 return r;
1064 }
1065 /**
1066 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
1067 * @ioc: per adapter object
1068 * @mpi_reply: reply mf payload returned from firmware
1069 * @config_page: contents of the config page
1070 * Context: sleep.
1071 *
1072 * Return: 0 for success, non-zero for failure.
1073 */
1074 int
mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage1_t * config_page)1075 mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1076 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1077 {
1078 Mpi2ConfigRequest_t mpi_request;
1079 int r;
1080
1081 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1082 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1083 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1084 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1085 mpi_request.Header.PageNumber = 1;
1086 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1087 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1088 r = _config_request(ioc, &mpi_request, mpi_reply,
1089 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1090 if (r)
1091 goto out;
1092
1093 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1094 r = _config_request(ioc, &mpi_request, mpi_reply,
1095 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1096 sizeof(*config_page));
1097 out:
1098 return r;
1099 }
1100
1101 /**
1102 * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
1103 * @ioc: per adapter object
1104 * @mpi_reply: reply mf payload returned from firmware
1105 * @config_page: contents of the config page
1106 * Context: sleep.
1107 *
1108 * Return: 0 for success, non-zero for failure.
1109 */
1110 int
mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage1_t * config_page)1111 mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1112 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1113 {
1114 Mpi2ConfigRequest_t mpi_request;
1115 int r;
1116
1117 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1118 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1119 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1120 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1121 mpi_request.Header.PageNumber = 1;
1122 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1123 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1124 r = _config_request(ioc, &mpi_request, mpi_reply,
1125 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1126 if (r)
1127 goto out;
1128
1129 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1130 r = _config_request(ioc, &mpi_request, mpi_reply,
1131 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1132 sizeof(*config_page));
1133 out:
1134 return r;
1135 }
1136
1137 /**
1138 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1139 * @ioc: per adapter object
1140 * @mpi_reply: reply mf payload returned from firmware
1141 * @config_page: contents of the config page
1142 * @form: GET_NEXT_HANDLE or HANDLE
1143 * @handle: device handle
1144 * Context: sleep.
1145 *
1146 * Return: 0 for success, non-zero for failure.
1147 */
1148 int
mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasDevicePage0_t * config_page,u32 form,u32 handle)1149 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1150 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1151 u32 form, u32 handle)
1152 {
1153 Mpi2ConfigRequest_t mpi_request;
1154 int r;
1155
1156 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1157 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1158 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1159 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1160 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1161 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1162 mpi_request.Header.PageNumber = 0;
1163 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1164 r = _config_request(ioc, &mpi_request, mpi_reply,
1165 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1166 if (r)
1167 goto out;
1168
1169 mpi_request.PageAddress = cpu_to_le32(form | handle);
1170 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1171 r = _config_request(ioc, &mpi_request, mpi_reply,
1172 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1173 sizeof(*config_page));
1174 out:
1175 return r;
1176 }
1177
1178 /**
1179 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1180 * @ioc: per adapter object
1181 * @mpi_reply: reply mf payload returned from firmware
1182 * @config_page: contents of the config page
1183 * @form: GET_NEXT_HANDLE or HANDLE
1184 * @handle: device handle
1185 * Context: sleep.
1186 *
1187 * Return: 0 for success, non-zero for failure.
1188 */
1189 int
mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage0_t * config_page,u32 form,u32 handle)1190 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1191 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1192 u32 form, u32 handle)
1193 {
1194 Mpi2ConfigRequest_t mpi_request;
1195 int r;
1196
1197 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1198 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1199 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1200 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1201 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1202 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1203 mpi_request.Header.PageNumber = 0;
1204 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1205 r = _config_request(ioc, &mpi_request, mpi_reply,
1206 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1207 if (r)
1208 goto out;
1209
1210 mpi_request.PageAddress = cpu_to_le32(form | handle);
1211 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1212 r = _config_request(ioc, &mpi_request, mpi_reply,
1213 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1214 sizeof(*config_page));
1215 out:
1216 return r;
1217 }
1218
1219 /**
1220 * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1
1221 * @ioc: per adapter object
1222 * @mpi_reply: reply mf payload returned from firmware
1223 * @config_page: contents of the config page
1224 * @sz: size of buffer passed in config_page
1225 * Context: sleep.
1226 *
1227 * Returns 0 for success, non-zero for failure.
1228 */
1229 int
mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeIOUnitPage1_t * config_page,u16 sz)1230 mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1231 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,
1232 u16 sz)
1233 {
1234 Mpi2ConfigRequest_t mpi_request;
1235 int r;
1236
1237 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1238 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1239 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1240 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1241 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;
1242 mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;
1243 mpi_request.Header.PageNumber = 1;
1244 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1245 r = _config_request(ioc, &mpi_request, mpi_reply,
1246 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1247 if (r)
1248 goto out;
1249 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1250 r = _config_request(ioc, &mpi_request, mpi_reply,
1251 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1252 out:
1253 return r;
1254 }
1255
1256 /**
1257 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1258 * @ioc: per adapter object
1259 * @mpi_reply: reply mf payload returned from firmware
1260 * @config_page: contents of the config page
1261 * @form: GET_NEXT_HANDLE or HANDLE
1262 * @handle: device handle
1263 * Context: sleep.
1264 *
1265 * Return: 0 for success, non-zero for failure.
1266 */
1267 int
mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage2_t * config_page,u32 form,u32 handle)1268 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1269 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1270 u32 form, u32 handle)
1271 {
1272 Mpi2ConfigRequest_t mpi_request;
1273 int r;
1274
1275 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1276 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1277 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1278 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1279 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1280 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1281 mpi_request.Header.PageNumber = 2;
1282 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1283 r = _config_request(ioc, &mpi_request, mpi_reply,
1284 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1285 if (r)
1286 goto out;
1287
1288 mpi_request.PageAddress = cpu_to_le32(form | handle);
1289 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1290 r = _config_request(ioc, &mpi_request, mpi_reply,
1291 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1292 sizeof(*config_page));
1293 out:
1294 return r;
1295 }
1296
1297 /**
1298 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1299 * @ioc: per adapter object
1300 * @num_phys: pointer returned with the number of phys
1301 * Context: sleep.
1302 *
1303 * Return: 0 for success, non-zero for failure.
1304 */
1305 int
mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER * ioc,u8 * num_phys)1306 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1307 {
1308 Mpi2ConfigRequest_t mpi_request;
1309 int r;
1310 u16 ioc_status;
1311 Mpi2ConfigReply_t mpi_reply;
1312 Mpi2SasIOUnitPage0_t config_page;
1313
1314 *num_phys = 0;
1315 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1316 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1317 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1318 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1319 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1320 mpi_request.Header.PageNumber = 0;
1321 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1322 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1323 r = _config_request(ioc, &mpi_request, &mpi_reply,
1324 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1325 if (r)
1326 goto out;
1327
1328 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1329 r = _config_request(ioc, &mpi_request, &mpi_reply,
1330 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1331 sizeof(Mpi2SasIOUnitPage0_t));
1332 if (!r) {
1333 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1334 MPI2_IOCSTATUS_MASK;
1335 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1336 *num_phys = config_page.NumPhys;
1337 }
1338 out:
1339 return r;
1340 }
1341
1342 /**
1343 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1344 * @ioc: per adapter object
1345 * @mpi_reply: reply mf payload returned from firmware
1346 * @config_page: contents of the config page
1347 * @sz: size of buffer passed in config_page
1348 * Context: sleep.
1349 *
1350 * Calling function should call config_get_number_hba_phys prior to
1351 * this function, so enough memory is allocated for config_page.
1352 *
1353 * Return: 0 for success, non-zero for failure.
1354 */
1355 int
mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage0_t * config_page,u16 sz)1356 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1357 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1358 u16 sz)
1359 {
1360 Mpi2ConfigRequest_t mpi_request;
1361 int r;
1362
1363 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1364 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1365 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1366 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1367 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1368 mpi_request.Header.PageNumber = 0;
1369 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1370 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1371 r = _config_request(ioc, &mpi_request, mpi_reply,
1372 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1373 if (r)
1374 goto out;
1375
1376 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1377 r = _config_request(ioc, &mpi_request, mpi_reply,
1378 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1379 out:
1380 return r;
1381 }
1382
1383 /**
1384 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1385 * @ioc: per adapter object
1386 * @mpi_reply: reply mf payload returned from firmware
1387 * @config_page: contents of the config page
1388 * @sz: size of buffer passed in config_page
1389 * Context: sleep.
1390 *
1391 * Calling function should call config_get_number_hba_phys prior to
1392 * this function, so enough memory is allocated for config_page.
1393 *
1394 * Return: 0 for success, non-zero for failure.
1395 */
1396 int
mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage1_t * config_page,u16 sz)1397 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1398 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1399 u16 sz)
1400 {
1401 Mpi2ConfigRequest_t mpi_request;
1402 int r;
1403
1404 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1405 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1406 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1407 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1408 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1409 mpi_request.Header.PageNumber = 1;
1410 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1411 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1412 r = _config_request(ioc, &mpi_request, mpi_reply,
1413 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1414 if (r)
1415 goto out;
1416
1417 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1418 r = _config_request(ioc, &mpi_request, mpi_reply,
1419 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1420 out:
1421 return r;
1422 }
1423
1424 /**
1425 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1426 * @ioc: per adapter object
1427 * @mpi_reply: reply mf payload returned from firmware
1428 * @config_page: contents of the config page
1429 * @sz: size of buffer passed in config_page
1430 * Context: sleep.
1431 *
1432 * Calling function should call config_get_number_hba_phys prior to
1433 * this function, so enough memory is allocated for config_page.
1434 *
1435 * Return: 0 for success, non-zero for failure.
1436 */
1437 int
mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage1_t * config_page,u16 sz)1438 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1439 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1440 u16 sz)
1441 {
1442 Mpi2ConfigRequest_t mpi_request;
1443 int r;
1444
1445 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1446 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1447 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1448 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1449 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1450 mpi_request.Header.PageNumber = 1;
1451 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1452 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1453 r = _config_request(ioc, &mpi_request, mpi_reply,
1454 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1455 if (r)
1456 goto out;
1457
1458 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1459 _config_request(ioc, &mpi_request, mpi_reply,
1460 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1461 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1462 r = _config_request(ioc, &mpi_request, mpi_reply,
1463 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1464 out:
1465 return r;
1466 }
1467
1468 /**
1469 * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1470 * @ioc: per adapter object
1471 * @mpi_reply: reply mf payload returned from firmware
1472 * @config_page: contents of the config page
1473 * @form: GET_NEXT_HANDLE or HANDLE
1474 * @handle: expander handle
1475 * Context: sleep.
1476 *
1477 * Return: 0 for success, non-zero for failure.
1478 */
1479 int
mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ExpanderPage0_t * config_page,u32 form,u32 handle)1480 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1481 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1482 {
1483 Mpi2ConfigRequest_t mpi_request;
1484 int r;
1485
1486 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1487 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1488 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1489 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1490 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1491 mpi_request.Header.PageNumber = 0;
1492 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1493 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1494 r = _config_request(ioc, &mpi_request, mpi_reply,
1495 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1496 if (r)
1497 goto out;
1498
1499 mpi_request.PageAddress = cpu_to_le32(form | handle);
1500 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1501 r = _config_request(ioc, &mpi_request, mpi_reply,
1502 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1503 sizeof(*config_page));
1504 out:
1505 return r;
1506 }
1507
1508 /**
1509 * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1510 * @ioc: per adapter object
1511 * @mpi_reply: reply mf payload returned from firmware
1512 * @config_page: contents of the config page
1513 * @phy_number: phy number
1514 * @handle: expander handle
1515 * Context: sleep.
1516 *
1517 * Return: 0 for success, non-zero for failure.
1518 */
1519 int
mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ExpanderPage1_t * config_page,u32 phy_number,u16 handle)1520 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1521 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1522 u16 handle)
1523 {
1524 Mpi2ConfigRequest_t mpi_request;
1525 int r;
1526
1527 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1528 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1529 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1530 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1531 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1532 mpi_request.Header.PageNumber = 1;
1533 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1534 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1535 r = _config_request(ioc, &mpi_request, mpi_reply,
1536 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1537 if (r)
1538 goto out;
1539
1540 mpi_request.PageAddress =
1541 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1542 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1543 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1544 r = _config_request(ioc, &mpi_request, mpi_reply,
1545 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1546 sizeof(*config_page));
1547 out:
1548 return r;
1549 }
1550
1551 /**
1552 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1553 * @ioc: per adapter object
1554 * @mpi_reply: reply mf payload returned from firmware
1555 * @config_page: contents of the config page
1556 * @form: GET_NEXT_HANDLE or HANDLE
1557 * @handle: expander handle
1558 * Context: sleep.
1559 *
1560 * Return: 0 for success, non-zero for failure.
1561 */
1562 int
mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasEnclosurePage0_t * config_page,u32 form,u32 handle)1563 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1564 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1565 {
1566 Mpi2ConfigRequest_t mpi_request;
1567 int r;
1568
1569 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1570 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1572 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1573 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1574 mpi_request.Header.PageNumber = 0;
1575 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1576 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1577 r = _config_request(ioc, &mpi_request, mpi_reply,
1578 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1579 if (r)
1580 goto out;
1581
1582 mpi_request.PageAddress = cpu_to_le32(form | handle);
1583 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1584 r = _config_request(ioc, &mpi_request, mpi_reply,
1585 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1586 sizeof(*config_page));
1587 out:
1588 return r;
1589 }
1590
1591 /**
1592 * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1593 * @ioc: per adapter object
1594 * @mpi_reply: reply mf payload returned from firmware
1595 * @config_page: contents of the config page
1596 * @phy_number: phy number
1597 * Context: sleep.
1598 *
1599 * Return: 0 for success, non-zero for failure.
1600 */
1601 int
mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasPhyPage0_t * config_page,u32 phy_number)1602 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1603 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1604 {
1605 Mpi2ConfigRequest_t mpi_request;
1606 int r;
1607
1608 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1609 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1610 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1611 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1612 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1613 mpi_request.Header.PageNumber = 0;
1614 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1615 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1616 r = _config_request(ioc, &mpi_request, mpi_reply,
1617 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1618 if (r)
1619 goto out;
1620
1621 mpi_request.PageAddress =
1622 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1623 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1624 r = _config_request(ioc, &mpi_request, mpi_reply,
1625 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1626 sizeof(*config_page));
1627 out:
1628 return r;
1629 }
1630
1631 /**
1632 * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1633 * @ioc: per adapter object
1634 * @mpi_reply: reply mf payload returned from firmware
1635 * @config_page: contents of the config page
1636 * @phy_number: phy number
1637 * Context: sleep.
1638 *
1639 * Return: 0 for success, non-zero for failure.
1640 */
1641 int
mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasPhyPage1_t * config_page,u32 phy_number)1642 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1643 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1644 {
1645 Mpi2ConfigRequest_t mpi_request;
1646 int r;
1647
1648 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1649 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1650 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1651 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1652 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1653 mpi_request.Header.PageNumber = 1;
1654 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1655 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1656 r = _config_request(ioc, &mpi_request, mpi_reply,
1657 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1658 if (r)
1659 goto out;
1660
1661 mpi_request.PageAddress =
1662 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1663 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1664 r = _config_request(ioc, &mpi_request, mpi_reply,
1665 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1666 sizeof(*config_page));
1667 out:
1668 return r;
1669 }
1670
1671 /**
1672 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1673 * @ioc: per adapter object
1674 * @mpi_reply: reply mf payload returned from firmware
1675 * @config_page: contents of the config page
1676 * @form: GET_NEXT_HANDLE or HANDLE
1677 * @handle: volume handle
1678 * Context: sleep.
1679 *
1680 * Return: 0 for success, non-zero for failure.
1681 */
1682 int
mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage1_t * config_page,u32 form,u32 handle)1683 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1684 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1685 u32 handle)
1686 {
1687 Mpi2ConfigRequest_t mpi_request;
1688 int r;
1689
1690 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1691 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1692 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1693 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1694 mpi_request.Header.PageNumber = 1;
1695 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1696 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1697 r = _config_request(ioc, &mpi_request, mpi_reply,
1698 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1699 if (r)
1700 goto out;
1701
1702 mpi_request.PageAddress = cpu_to_le32(form | handle);
1703 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1704 r = _config_request(ioc, &mpi_request, mpi_reply,
1705 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1706 sizeof(*config_page));
1707 out:
1708 return r;
1709 }
1710
1711 /**
1712 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1713 * @ioc: per adapter object
1714 * @handle: volume handle
1715 * @num_pds: returns pds count
1716 * Context: sleep.
1717 *
1718 * Return: 0 for success, non-zero for failure.
1719 */
1720 int
mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER * ioc,u16 handle,u8 * num_pds)1721 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1722 u8 *num_pds)
1723 {
1724 Mpi2ConfigRequest_t mpi_request;
1725 Mpi2RaidVolPage0_t config_page;
1726 Mpi2ConfigReply_t mpi_reply;
1727 int r;
1728 u16 ioc_status;
1729
1730 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1731 *num_pds = 0;
1732 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1733 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1734 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1735 mpi_request.Header.PageNumber = 0;
1736 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1737 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1738 r = _config_request(ioc, &mpi_request, &mpi_reply,
1739 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1740 if (r)
1741 goto out;
1742
1743 mpi_request.PageAddress =
1744 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1745 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1746 r = _config_request(ioc, &mpi_request, &mpi_reply,
1747 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1748 sizeof(Mpi2RaidVolPage0_t));
1749 if (!r) {
1750 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1751 MPI2_IOCSTATUS_MASK;
1752 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1753 *num_pds = config_page.NumPhysDisks;
1754 }
1755
1756 out:
1757 return r;
1758 }
1759
1760 /**
1761 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1762 * @ioc: per adapter object
1763 * @mpi_reply: reply mf payload returned from firmware
1764 * @config_page: contents of the config page
1765 * @form: GET_NEXT_HANDLE or HANDLE
1766 * @handle: volume handle
1767 * @sz: size of buffer passed in config_page
1768 * Context: sleep.
1769 *
1770 * Return: 0 for success, non-zero for failure.
1771 */
1772 int
mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage0_t * config_page,u32 form,u32 handle,u16 sz)1773 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1774 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1775 u32 handle, u16 sz)
1776 {
1777 Mpi2ConfigRequest_t mpi_request;
1778 int r;
1779
1780 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1781 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1782 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1783 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1784 mpi_request.Header.PageNumber = 0;
1785 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1786 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1787 r = _config_request(ioc, &mpi_request, mpi_reply,
1788 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1789 if (r)
1790 goto out;
1791
1792 mpi_request.PageAddress = cpu_to_le32(form | handle);
1793 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1794 r = _config_request(ioc, &mpi_request, mpi_reply,
1795 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1796 out:
1797 return r;
1798 }
1799
1800 /**
1801 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1802 * @ioc: per adapter object
1803 * @mpi_reply: reply mf payload returned from firmware
1804 * @config_page: contents of the config page
1805 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1806 * @form_specific: specific to the form
1807 * Context: sleep.
1808 *
1809 * Return: 0 for success, non-zero for failure.
1810 */
1811 int
mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidPhysDiskPage0_t * config_page,u32 form,u32 form_specific)1812 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1813 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1814 u32 form_specific)
1815 {
1816 Mpi2ConfigRequest_t mpi_request;
1817 int r;
1818
1819 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1820 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1821 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1822 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1823 mpi_request.Header.PageNumber = 0;
1824 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1825 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1826 r = _config_request(ioc, &mpi_request, mpi_reply,
1827 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1828 if (r)
1829 goto out;
1830
1831 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1832 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1833 r = _config_request(ioc, &mpi_request, mpi_reply,
1834 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1835 sizeof(*config_page));
1836 out:
1837 return r;
1838 }
1839
1840 /**
1841 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
1842 * @ioc: per adapter object
1843 * @mpi_reply: reply mf payload returned from firmware
1844 * @config_page: contents of the config page
1845 * Context: sleep.
1846 *
1847 * Returns 0 for success, non-zero for failure.
1848 */
1849 int
mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage0_t * config_page)1850 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1851 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1852 {
1853 Mpi2ConfigRequest_t mpi_request;
1854 int r;
1855
1856 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1857 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1858 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1859 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1860 mpi_request.ExtPageType =
1861 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1862 mpi_request.Header.PageNumber = 0;
1863 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1864 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1865 r = _config_request(ioc, &mpi_request, mpi_reply,
1866 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1867 if (r)
1868 goto out;
1869
1870 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1871 r = _config_request(ioc, &mpi_request, mpi_reply,
1872 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1873 sizeof(*config_page));
1874 out:
1875 return r;
1876 }
1877
1878 /**
1879 * _config_set_driver_trigger_pg0 - write driver trigger page 0
1880 * @ioc: per adapter object
1881 * @mpi_reply: reply mf payload returned from firmware
1882 * @config_page: contents of the config page
1883 * Context: sleep.
1884 *
1885 * Returns 0 for success, non-zero for failure.
1886 */
1887 static int
_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage0_t * config_page)1888 _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1889 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1890 {
1891 Mpi2ConfigRequest_t mpi_request;
1892 int r;
1893
1894 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1895 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1896 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1897 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1898 mpi_request.ExtPageType =
1899 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1900 mpi_request.Header.PageNumber = 0;
1901 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1902 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1903 r = _config_request(ioc, &mpi_request, mpi_reply,
1904 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1905 if (r)
1906 goto out;
1907
1908 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1909 _config_request(ioc, &mpi_request, mpi_reply,
1910 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1911 sizeof(*config_page));
1912 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1913 r = _config_request(ioc, &mpi_request, mpi_reply,
1914 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1915 sizeof(*config_page));
1916 out:
1917 return r;
1918 }
1919
1920 /**
1921 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
1922 * @ioc: per adapter object
1923 * @trigger_flag: trigger type bit map
1924 * @set: set ot clear trigger values
1925 * Context: sleep.
1926 *
1927 * Returns 0 for success, non-zero for failure.
1928 */
1929 static int
mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,u16 trigger_flag,bool set)1930 mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1931 u16 trigger_flag, bool set)
1932 {
1933 Mpi26DriverTriggerPage0_t tg_pg0;
1934 Mpi2ConfigReply_t mpi_reply;
1935 int rc;
1936 u16 flags, ioc_status;
1937
1938 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1939 if (rc)
1940 return rc;
1941 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1942 MPI2_IOCSTATUS_MASK;
1943 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1944 dcprintk(ioc,
1945 ioc_err(ioc,
1946 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
1947 __func__, ioc_status));
1948 return -EFAULT;
1949 }
1950
1951 if (set)
1952 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
1953 else
1954 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
1955
1956 tg_pg0.TriggerFlags = cpu_to_le16(flags);
1957
1958 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1959 if (rc)
1960 return rc;
1961 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1962 MPI2_IOCSTATUS_MASK;
1963 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1964 dcprintk(ioc,
1965 ioc_err(ioc,
1966 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
1967 __func__, ioc_status));
1968 return -EFAULT;
1969 }
1970
1971 return 0;
1972 }
1973
1974 /**
1975 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
1976 * @ioc: per adapter object
1977 * @mpi_reply: reply mf payload returned from firmware
1978 * @config_page: contents of the config page
1979 * Context: sleep.
1980 *
1981 * Returns 0 for success, non-zero for failure.
1982 */
1983 int
mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage1_t * config_page)1984 mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1985 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1986 {
1987 Mpi2ConfigRequest_t mpi_request;
1988 int r;
1989
1990 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1991 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1992 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1993 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1994 mpi_request.ExtPageType =
1995 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1996 mpi_request.Header.PageNumber = 1;
1997 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1998 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1999 r = _config_request(ioc, &mpi_request, mpi_reply,
2000 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2001 if (r)
2002 goto out;
2003
2004 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2005 r = _config_request(ioc, &mpi_request, mpi_reply,
2006 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2007 sizeof(*config_page));
2008 out:
2009 return r;
2010 }
2011
2012 /**
2013 * _config_set_driver_trigger_pg1 - write driver trigger page 1
2014 * @ioc: per adapter object
2015 * @mpi_reply: reply mf payload returned from firmware
2016 * @config_page: contents of the config page
2017 * Context: sleep.
2018 *
2019 * Returns 0 for success, non-zero for failure.
2020 */
2021 static int
_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage1_t * config_page)2022 _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2023 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
2024 {
2025 Mpi2ConfigRequest_t mpi_request;
2026 int r;
2027
2028 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2029 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2030 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2031 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2032 mpi_request.ExtPageType =
2033 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2034 mpi_request.Header.PageNumber = 1;
2035 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
2036 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2037 r = _config_request(ioc, &mpi_request, mpi_reply,
2038 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2039 if (r)
2040 goto out;
2041
2042 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2043 _config_request(ioc, &mpi_request, mpi_reply,
2044 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2045 sizeof(*config_page));
2046 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2047 r = _config_request(ioc, &mpi_request, mpi_reply,
2048 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2049 sizeof(*config_page));
2050 out:
2051 return r;
2052 }
2053
2054 /**
2055 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
2056 * @ioc: per adapter object
2057 * @master_tg: Master trigger bit map
2058 * @set: set ot clear trigger values
2059 * Context: sleep.
2060 *
2061 * Returns 0 for success, non-zero for failure.
2062 */
2063 int
mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_MASTER_TRIGGER_T * master_tg,bool set)2064 mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2065 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
2066 {
2067 Mpi26DriverTriggerPage1_t tg_pg1;
2068 Mpi2ConfigReply_t mpi_reply;
2069 int rc;
2070 u16 ioc_status;
2071
2072 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2073 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
2074 if (rc)
2075 return rc;
2076
2077 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2078 if (rc)
2079 goto out;
2080
2081 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2082 MPI2_IOCSTATUS_MASK;
2083 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2084 dcprintk(ioc,
2085 ioc_err(ioc,
2086 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2087 __func__, ioc_status));
2088 rc = -EFAULT;
2089 goto out;
2090 }
2091
2092 if (set) {
2093 tg_pg1.NumMasterTrigger = cpu_to_le16(1);
2094 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
2095 master_tg->MasterData);
2096 } else {
2097 tg_pg1.NumMasterTrigger = 0;
2098 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
2099 }
2100
2101 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2102 if (rc)
2103 goto out;
2104
2105 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2106 MPI2_IOCSTATUS_MASK;
2107 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2108 dcprintk(ioc,
2109 ioc_err(ioc,
2110 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2111 __func__, ioc_status));
2112 rc = -EFAULT;
2113 goto out;
2114 }
2115
2116 return 0;
2117
2118 out:
2119 mpt3sas_config_update_driver_trigger_pg0(ioc,
2120 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
2121
2122 return rc;
2123 }
2124
2125 /**
2126 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
2127 * @ioc: per adapter object
2128 * @mpi_reply: reply mf payload returned from firmware
2129 * @config_page: contents of the config page
2130 * Context: sleep.
2131 *
2132 * Returns 0 for success, non-zero for failure.
2133 */
2134 int
mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage2_t * config_page)2135 mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2136 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2137 {
2138 Mpi2ConfigRequest_t mpi_request;
2139 int r;
2140
2141 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2142 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2143 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2144 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2145 mpi_request.ExtPageType =
2146 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2147 mpi_request.Header.PageNumber = 2;
2148 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2149 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2150 r = _config_request(ioc, &mpi_request, mpi_reply,
2151 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2152 if (r)
2153 goto out;
2154
2155 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2156 r = _config_request(ioc, &mpi_request, mpi_reply,
2157 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2158 sizeof(*config_page));
2159 out:
2160 return r;
2161 }
2162
2163 /**
2164 * _config_set_driver_trigger_pg2 - write driver trigger page 2
2165 * @ioc: per adapter object
2166 * @mpi_reply: reply mf payload returned from firmware
2167 * @config_page: contents of the config page
2168 * Context: sleep.
2169 *
2170 * Returns 0 for success, non-zero for failure.
2171 */
2172 static int
_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage2_t * config_page)2173 _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2174 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2175 {
2176 Mpi2ConfigRequest_t mpi_request;
2177 int r;
2178
2179 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2180 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2181 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2182 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2183 mpi_request.ExtPageType =
2184 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2185 mpi_request.Header.PageNumber = 2;
2186 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2187 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2188 r = _config_request(ioc, &mpi_request, mpi_reply,
2189 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2190 if (r)
2191 goto out;
2192
2193 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2194 _config_request(ioc, &mpi_request, mpi_reply,
2195 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2196 sizeof(*config_page));
2197 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2198 r = _config_request(ioc, &mpi_request, mpi_reply,
2199 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2200 sizeof(*config_page));
2201 out:
2202 return r;
2203 }
2204
2205 /**
2206 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
2207 * @ioc: per adapter object
2208 * @event_tg: list of Event Triggers
2209 * @set: set ot clear trigger values
2210 * Context: sleep.
2211 *
2212 * Returns 0 for success, non-zero for failure.
2213 */
2214 int
mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_EVENT_TRIGGERS_T * event_tg,bool set)2215 mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2216 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
2217 {
2218 Mpi26DriverTriggerPage2_t tg_pg2;
2219 Mpi2ConfigReply_t mpi_reply;
2220 int rc, i, count;
2221 u16 ioc_status;
2222
2223 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2224 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
2225 if (rc)
2226 return rc;
2227
2228 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2229 if (rc)
2230 goto out;
2231
2232 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2233 MPI2_IOCSTATUS_MASK;
2234 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2235 dcprintk(ioc,
2236 ioc_err(ioc,
2237 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2238 __func__, ioc_status));
2239 rc = -EFAULT;
2240 goto out;
2241 }
2242
2243 if (set) {
2244 count = event_tg->ValidEntries;
2245 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
2246 for (i = 0; i < count; i++) {
2247 tg_pg2.MPIEventTriggers[i].MPIEventCode =
2248 cpu_to_le16(
2249 event_tg->EventTriggerEntry[i].EventValue);
2250 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
2251 cpu_to_le16(
2252 event_tg->EventTriggerEntry[i].LogEntryQualifier);
2253 }
2254 } else {
2255 tg_pg2.NumMPIEventTrigger = 0;
2256 memset(&tg_pg2.MPIEventTriggers[0], 0,
2257 NUM_VALID_ENTRIES * sizeof(
2258 MPI26_DRIVER_MPI_EVENT_TRIGGER_ENTRY));
2259 }
2260
2261 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2262 if (rc)
2263 goto out;
2264
2265 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2266 MPI2_IOCSTATUS_MASK;
2267 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2268 dcprintk(ioc,
2269 ioc_err(ioc,
2270 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2271 __func__, ioc_status));
2272 rc = -EFAULT;
2273 goto out;
2274 }
2275
2276 return 0;
2277
2278 out:
2279 mpt3sas_config_update_driver_trigger_pg0(ioc,
2280 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
2281
2282 return rc;
2283 }
2284
2285 /**
2286 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
2287 * @ioc: per adapter object
2288 * @mpi_reply: reply mf payload returned from firmware
2289 * @config_page: contents of the config page
2290 * Context: sleep.
2291 *
2292 * Returns 0 for success, non-zero for failure.
2293 */
2294 int
mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage3_t * config_page)2295 mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2296 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2297 {
2298 Mpi2ConfigRequest_t mpi_request;
2299 int r;
2300
2301 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2302 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2303 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2304 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2305 mpi_request.ExtPageType =
2306 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2307 mpi_request.Header.PageNumber = 3;
2308 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2309 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2310 r = _config_request(ioc, &mpi_request, mpi_reply,
2311 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2312 if (r)
2313 goto out;
2314
2315 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2316 r = _config_request(ioc, &mpi_request, mpi_reply,
2317 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2318 sizeof(*config_page));
2319 out:
2320 return r;
2321 }
2322
2323 /**
2324 * _config_set_driver_trigger_pg3 - write driver trigger page 3
2325 * @ioc: per adapter object
2326 * @mpi_reply: reply mf payload returned from firmware
2327 * @config_page: contents of the config page
2328 * Context: sleep.
2329 *
2330 * Returns 0 for success, non-zero for failure.
2331 */
2332 static int
_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage3_t * config_page)2333 _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2334 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2335 {
2336 Mpi2ConfigRequest_t mpi_request;
2337 int r;
2338
2339 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2340 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2341 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2342 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2343 mpi_request.ExtPageType =
2344 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2345 mpi_request.Header.PageNumber = 3;
2346 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2347 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2348 r = _config_request(ioc, &mpi_request, mpi_reply,
2349 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2350 if (r)
2351 goto out;
2352
2353 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2354 _config_request(ioc, &mpi_request, mpi_reply,
2355 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2356 sizeof(*config_page));
2357 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2358 r = _config_request(ioc, &mpi_request, mpi_reply,
2359 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2360 sizeof(*config_page));
2361 out:
2362 return r;
2363 }
2364
2365 /**
2366 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
2367 * @ioc: per adapter object
2368 * @scsi_tg: scsi trigger list
2369 * @set: set ot clear trigger values
2370 * Context: sleep.
2371 *
2372 * Returns 0 for success, non-zero for failure.
2373 */
2374 int
mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_SCSI_TRIGGERS_T * scsi_tg,bool set)2375 mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2376 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
2377 {
2378 Mpi26DriverTriggerPage3_t tg_pg3;
2379 Mpi2ConfigReply_t mpi_reply;
2380 int rc, i, count;
2381 u16 ioc_status;
2382
2383 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2384 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
2385 if (rc)
2386 return rc;
2387
2388 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2389 if (rc)
2390 goto out;
2391
2392 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2393 MPI2_IOCSTATUS_MASK;
2394 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2395 dcprintk(ioc,
2396 ioc_err(ioc,
2397 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2398 __func__, ioc_status));
2399 return -EFAULT;
2400 }
2401
2402 if (set) {
2403 count = scsi_tg->ValidEntries;
2404 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
2405 for (i = 0; i < count; i++) {
2406 tg_pg3.SCSISenseTriggers[i].ASCQ =
2407 scsi_tg->SCSITriggerEntry[i].ASCQ;
2408 tg_pg3.SCSISenseTriggers[i].ASC =
2409 scsi_tg->SCSITriggerEntry[i].ASC;
2410 tg_pg3.SCSISenseTriggers[i].SenseKey =
2411 scsi_tg->SCSITriggerEntry[i].SenseKey;
2412 }
2413 } else {
2414 tg_pg3.NumSCSISenseTrigger = 0;
2415 memset(&tg_pg3.SCSISenseTriggers[0], 0,
2416 NUM_VALID_ENTRIES * sizeof(
2417 MPI26_DRIVER_SCSI_SENSE_TRIGGER_ENTRY));
2418 }
2419
2420 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2421 if (rc)
2422 goto out;
2423
2424 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2425 MPI2_IOCSTATUS_MASK;
2426 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2427 dcprintk(ioc,
2428 ioc_err(ioc,
2429 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2430 __func__, ioc_status));
2431 return -EFAULT;
2432 }
2433
2434 return 0;
2435 out:
2436 mpt3sas_config_update_driver_trigger_pg0(ioc,
2437 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
2438
2439 return rc;
2440 }
2441
2442 /**
2443 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
2444 * @ioc: per adapter object
2445 * @mpi_reply: reply mf payload returned from firmware
2446 * @config_page: contents of the config page
2447 * Context: sleep.
2448 *
2449 * Returns 0 for success, non-zero for failure.
2450 */
2451 int
mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage4_t * config_page)2452 mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2453 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2454 {
2455 Mpi2ConfigRequest_t mpi_request;
2456 int r;
2457
2458 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2459 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2460 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2461 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2462 mpi_request.ExtPageType =
2463 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2464 mpi_request.Header.PageNumber = 4;
2465 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2466 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2467 r = _config_request(ioc, &mpi_request, mpi_reply,
2468 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2469 if (r)
2470 goto out;
2471
2472 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2473 r = _config_request(ioc, &mpi_request, mpi_reply,
2474 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2475 sizeof(*config_page));
2476 out:
2477 return r;
2478 }
2479
2480 /**
2481 * _config_set_driver_trigger_pg4 - write driver trigger page 4
2482 * @ioc: per adapter object
2483 * @mpi_reply: reply mf payload returned from firmware
2484 * @config_page: contents of the config page
2485 * Context: sleep.
2486 *
2487 * Returns 0 for success, non-zero for failure.
2488 */
2489 static int
_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage4_t * config_page)2490 _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2491 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2492 {
2493 Mpi2ConfigRequest_t mpi_request;
2494 int r;
2495
2496 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2497 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2498 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2499 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2500 mpi_request.ExtPageType =
2501 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2502 mpi_request.Header.PageNumber = 4;
2503 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2504 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2505 r = _config_request(ioc, &mpi_request, mpi_reply,
2506 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2507 if (r)
2508 goto out;
2509
2510 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2511 _config_request(ioc, &mpi_request, mpi_reply,
2512 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2513 sizeof(*config_page));
2514 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2515 r = _config_request(ioc, &mpi_request, mpi_reply,
2516 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2517 sizeof(*config_page));
2518 out:
2519 return r;
2520 }
2521
2522 /**
2523 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
2524 * @ioc: per adapter object
2525 * @mpi_tg: mpi trigger list
2526 * @set: set ot clear trigger values
2527 * Context: sleep.
2528 *
2529 * Returns 0 for success, non-zero for failure.
2530 */
2531 int
mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_MPI_TRIGGERS_T * mpi_tg,bool set)2532 mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2533 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
2534 {
2535 Mpi26DriverTriggerPage4_t tg_pg4;
2536 Mpi2ConfigReply_t mpi_reply;
2537 int rc, i, count;
2538 u16 ioc_status;
2539
2540 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2541 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
2542 if (rc)
2543 return rc;
2544
2545 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2546 if (rc)
2547 goto out;
2548
2549 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2550 MPI2_IOCSTATUS_MASK;
2551 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2552 dcprintk(ioc,
2553 ioc_err(ioc,
2554 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2555 __func__, ioc_status));
2556 rc = -EFAULT;
2557 goto out;
2558 }
2559
2560 if (set) {
2561 count = mpi_tg->ValidEntries;
2562 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
2563 for (i = 0; i < count; i++) {
2564 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
2565 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
2566 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
2567 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
2568 }
2569 } else {
2570 tg_pg4.NumIOCStatusLogInfoTrigger = 0;
2571 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
2572 NUM_VALID_ENTRIES * sizeof(
2573 MPI26_DRIVER_IOCSTATUS_LOGINFO_TRIGGER_ENTRY));
2574 }
2575
2576 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2577 if (rc)
2578 goto out;
2579
2580 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2581 MPI2_IOCSTATUS_MASK;
2582 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2583 dcprintk(ioc,
2584 ioc_err(ioc,
2585 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2586 __func__, ioc_status));
2587 rc = -EFAULT;
2588 goto out;
2589 }
2590
2591 return 0;
2592
2593 out:
2594 mpt3sas_config_update_driver_trigger_pg0(ioc,
2595 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
2596
2597 return rc;
2598 }
2599
2600 /**
2601 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
2602 * raid components
2603 * @ioc: per adapter object
2604 * @pd_handle: phys disk handle
2605 * @volume_handle: volume handle
2606 * Context: sleep.
2607 *
2608 * Return: 0 for success, non-zero for failure.
2609 */
2610 int
mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER * ioc,u16 pd_handle,u16 * volume_handle)2611 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
2612 u16 *volume_handle)
2613 {
2614 Mpi2RaidConfigurationPage0_t *config_page = NULL;
2615 Mpi2ConfigRequest_t mpi_request;
2616 Mpi2ConfigReply_t mpi_reply;
2617 int r, i, config_page_sz;
2618 u16 ioc_status;
2619 int config_num;
2620 u16 element_type;
2621 u16 phys_disk_dev_handle;
2622
2623 *volume_handle = 0;
2624 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2625 mpi_request.Function = MPI2_FUNCTION_CONFIG;
2626 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2627 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2628 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
2629 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
2630 mpi_request.Header.PageNumber = 0;
2631 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2632 r = _config_request(ioc, &mpi_request, &mpi_reply,
2633 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2634 if (r)
2635 goto out;
2636
2637 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2638 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
2639 config_page = kmalloc(config_page_sz, GFP_KERNEL);
2640 if (!config_page) {
2641 r = -1;
2642 goto out;
2643 }
2644
2645 config_num = 0xff;
2646 while (1) {
2647 mpi_request.PageAddress = cpu_to_le32(config_num +
2648 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
2649 r = _config_request(ioc, &mpi_request, &mpi_reply,
2650 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2651 config_page_sz);
2652 if (r)
2653 goto out;
2654 r = -1;
2655 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2656 MPI2_IOCSTATUS_MASK;
2657 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
2658 goto out;
2659 for (i = 0; i < config_page->NumElements; i++) {
2660 element_type = le16_to_cpu(config_page->
2661 ConfigElement[i].ElementFlags) &
2662 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
2663 if (element_type ==
2664 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
2665 element_type ==
2666 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
2667 phys_disk_dev_handle =
2668 le16_to_cpu(config_page->ConfigElement[i].
2669 PhysDiskDevHandle);
2670 if (phys_disk_dev_handle == pd_handle) {
2671 *volume_handle =
2672 le16_to_cpu(config_page->
2673 ConfigElement[i].VolDevHandle);
2674 r = 0;
2675 goto out;
2676 }
2677 } else if (element_type ==
2678 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
2679 *volume_handle = 0;
2680 r = 0;
2681 goto out;
2682 }
2683 }
2684 config_num = config_page->ConfigNum;
2685 }
2686 out:
2687 kfree(config_page);
2688 return r;
2689 }
2690
2691 /**
2692 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
2693 * @ioc: per adapter object
2694 * @volume_handle: volume handle
2695 * @wwid: volume wwid
2696 * Context: sleep.
2697 *
2698 * Return: 0 for success, non-zero for failure.
2699 */
2700 int
mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER * ioc,u16 volume_handle,u64 * wwid)2701 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
2702 u64 *wwid)
2703 {
2704 Mpi2ConfigReply_t mpi_reply;
2705 Mpi2RaidVolPage1_t raid_vol_pg1;
2706
2707 *wwid = 0;
2708 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
2709 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
2710 volume_handle))) {
2711 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
2712 return 0;
2713 } else
2714 return -1;
2715 }
2716