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