blob: b9f4d0f97e501e41e0dc6aff29c6a08e6748a7b5 [file] [log] [blame]
Eric Moore635374e2009-03-09 01:21:12 -06001/*
2 * This module provides common API for accessing firmware configuration pages
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#include <linux/version.h>
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 "mpt2sas_base.h"
56
57/* local definitions */
58
59/* Timeout for config page request (in seconds) */
60#define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
61
62/* Common sgl flags for READING a config page. */
63#define MPT2_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 MPT2_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 * @config_page_sz: size
76 * @config_page: virt pointer
77 * @config_page_dma: phys pointer
78 *
79 */
80struct config_request{
81 u16 config_page_sz;
82 void *config_page;
83 dma_addr_t config_page_dma;
84};
85
86#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
87/**
88 * _config_display_some_debug - debug routine
89 * @ioc: per adapter object
90 * @smid: system request message index
91 * @calling_function_name: string pass from calling function
92 * @mpi_reply: reply message frame
93 * Context: none.
94 *
95 * Function for displaying debug info helpfull when debugging issues
96 * in this module.
97 */
98static void
99_config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
100 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
101{
102 Mpi2ConfigRequest_t *mpi_request;
103 char *desc = NULL;
104
105 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
106 return;
107
108 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
109 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
110 case MPI2_CONFIG_PAGETYPE_IO_UNIT:
111 desc = "io_unit";
112 break;
113 case MPI2_CONFIG_PAGETYPE_IOC:
114 desc = "ioc";
115 break;
116 case MPI2_CONFIG_PAGETYPE_BIOS:
117 desc = "bios";
118 break;
119 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
120 desc = "raid_volume";
121 break;
122 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
123 desc = "manufaucturing";
124 break;
125 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
126 desc = "physdisk";
127 break;
128 case MPI2_CONFIG_PAGETYPE_EXTENDED:
129 switch (mpi_request->ExtPageType) {
130 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
131 desc = "sas_io_unit";
132 break;
133 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
134 desc = "sas_expander";
135 break;
136 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
137 desc = "sas_device";
138 break;
139 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
140 desc = "sas_phy";
141 break;
142 case MPI2_CONFIG_EXTPAGETYPE_LOG:
143 desc = "log";
144 break;
145 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
146 desc = "enclosure";
147 break;
148 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
149 desc = "raid_config";
150 break;
151 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
152 desc = "driver_mappping";
153 break;
154 }
155 break;
156 }
157
158 if (!desc)
159 return;
160
161 printk(MPT2SAS_DEBUG_FMT "%s: %s(%d), action(%d), form(0x%08x), "
162 "smid(%d)\n", 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 printk(MPT2SAS_DEBUG_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}
175#endif
176
177/**
178 * mpt2sas_config_done - config page completion routine
179 * @ioc: per adapter object
180 * @smid: system request message index
181 * @VF_ID: virtual function id
182 * @reply: reply message frame(lower 32bit addr)
183 * Context: none.
184 *
185 * The callback handler when using _config_request.
186 *
187 * Return nothing.
188 */
189void
190mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
191{
192 MPI2DefaultReply_t *mpi_reply;
193
194 if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
195 return;
196 if (ioc->config_cmds.smid != smid)
197 return;
198 ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
199 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
200 if (mpi_reply) {
201 ioc->config_cmds.status |= MPT2_CMD_REPLY_VALID;
202 memcpy(ioc->config_cmds.reply, mpi_reply,
203 mpi_reply->MsgLength*4);
204 }
205 ioc->config_cmds.status &= ~MPT2_CMD_PENDING;
206#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
207 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
208#endif
209 complete(&ioc->config_cmds.done);
210}
211
212/**
213 * _config_request - main routine for sending config page requests
214 * @ioc: per adapter object
215 * @mpi_request: request message frame
216 * @mpi_reply: reply mf payload returned from firmware
217 * @timeout: timeout in seconds
218 * Context: sleep, the calling function needs to acquire the config_cmds.mutex
219 *
220 * A generic API for config page requests to firmware.
221 *
222 * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
223 * this API.
224 *
225 * The callback index is set inside `ioc->config_cb_idx.
226 *
227 * Returns 0 for success, non-zero for failure.
228 */
229static int
230_config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
231 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout)
232{
233 u16 smid;
234 u32 ioc_state;
235 unsigned long timeleft;
236 Mpi2ConfigRequest_t *config_request;
237 int r;
238 u8 retry_count;
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530239 u8 issue_host_reset = 0;
Eric Moore635374e2009-03-09 01:21:12 -0600240 u16 wait_state_count;
241
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530242 mutex_lock(&ioc->config_cmds.mutex);
Eric Moore635374e2009-03-09 01:21:12 -0600243 if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
244 printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
245 ioc->name, __func__);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530246 mutex_unlock(&ioc->config_cmds.mutex);
Eric Moore635374e2009-03-09 01:21:12 -0600247 return -EAGAIN;
248 }
249 retry_count = 0;
250
251 retry_config:
Kashyap, Desai6bd4e1e2009-08-07 19:37:14 +0530252 if (retry_count) {
253 if (retry_count > 2) /* attempt only 2 retries */
254 return -EFAULT;
255 printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
256 ioc->name, __func__, retry_count);
257 }
Eric Moore635374e2009-03-09 01:21:12 -0600258 wait_state_count = 0;
259 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
260 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
261 if (wait_state_count++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT) {
262 printk(MPT2SAS_ERR_FMT
263 "%s: failed due to ioc not operational\n",
264 ioc->name, __func__);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530265 r = -EFAULT;
266 goto out;
Eric Moore635374e2009-03-09 01:21:12 -0600267 }
268 ssleep(1);
269 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
270 printk(MPT2SAS_INFO_FMT "%s: waiting for "
271 "operational state(count=%d)\n", ioc->name,
272 __func__, wait_state_count);
273 }
274 if (wait_state_count)
275 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
276 ioc->name, __func__);
277
278 smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx);
279 if (!smid) {
280 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
281 ioc->name, __func__);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530282 r = -EAGAIN;
283 goto out;
Eric Moore635374e2009-03-09 01:21:12 -0600284 }
285
286 r = 0;
287 memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
288 ioc->config_cmds.status = MPT2_CMD_PENDING;
289 config_request = mpt2sas_base_get_msg_frame(ioc, smid);
290 ioc->config_cmds.smid = smid;
291 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
292#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
293 _config_display_some_debug(ioc, smid, "config_request", NULL);
294#endif
295 mpt2sas_base_put_smid_default(ioc, smid, config_request->VF_ID);
296 timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
297 timeout*HZ);
298 if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
299 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
300 ioc->name, __func__);
301 _debug_dump_mf(mpi_request,
302 sizeof(Mpi2ConfigRequest_t)/4);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530303 retry_count++;
304 if (ioc->config_cmds.smid == smid)
305 mpt2sas_base_free_smid(ioc, smid);
306 if ((ioc->shost_recovery) ||
307 (ioc->config_cmds.status & MPT2_CMD_RESET))
308 goto retry_config;
309 issue_host_reset = 1;
310 r = -EFAULT;
311 goto out;
Eric Moore635374e2009-03-09 01:21:12 -0600312 }
313 if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
314 memcpy(mpi_reply, ioc->config_cmds.reply,
315 sizeof(Mpi2ConfigReply_t));
316 if (retry_count)
317 printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
318 ioc->name, __func__);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530319out:
Eric Moore635374e2009-03-09 01:21:12 -0600320 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530321 mutex_unlock(&ioc->config_cmds.mutex);
322 if (issue_host_reset)
Eric Moore635374e2009-03-09 01:21:12 -0600323 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
324 FORCE_BIG_HAMMER);
Kashyap, Desai388ce4b2009-08-14 15:01:35 +0530325 return r;
Eric Moore635374e2009-03-09 01:21:12 -0600326}
327
328/**
329 * _config_alloc_config_dma_memory - obtain physical memory
330 * @ioc: per adapter object
331 * @mem: struct config_request
332 *
333 * A wrapper for obtaining dma-able memory for config page request.
334 *
335 * Returns 0 for success, non-zero for failure.
336 */
337static int
338_config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
339 struct config_request *mem)
340{
341 int r = 0;
342
343 mem->config_page = pci_alloc_consistent(ioc->pdev, mem->config_page_sz,
344 &mem->config_page_dma);
345 if (!mem->config_page)
346 r = -ENOMEM;
347 return r;
348}
349
350/**
351 * _config_free_config_dma_memory - wrapper to free the memory
352 * @ioc: per adapter object
353 * @mem: struct config_request
354 *
355 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
356 *
357 * Returns 0 for success, non-zero for failure.
358 */
359static void
360_config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
361 struct config_request *mem)
362{
363 pci_free_consistent(ioc->pdev, mem->config_page_sz, mem->config_page,
364 mem->config_page_dma);
365}
366
367/**
368 * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
369 * @ioc: per adapter object
370 * @mpi_reply: reply mf payload returned from firmware
371 * @config_page: contents of the config page
372 * Context: sleep.
373 *
374 * Returns 0 for success, non-zero for failure.
375 */
376int
377mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
378 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
379{
380 Mpi2ConfigRequest_t mpi_request;
381 int r;
382 struct config_request mem;
383
Eric Moore635374e2009-03-09 01:21:12 -0600384 memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
385 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
386 mpi_request.Function = MPI2_FUNCTION_CONFIG;
387 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
388 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
389 mpi_request.Header.PageNumber = 0;
390 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
391 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
392 r = _config_request(ioc, &mpi_request, mpi_reply,
393 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
394 if (r)
395 goto out;
396
397 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
398 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
399 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
400 mpi_request.Header.PageType = mpi_reply->Header.PageType;
401 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
402 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
403 if (mem.config_page_sz > ioc->config_page_sz) {
404 r = _config_alloc_config_dma_memory(ioc, &mem);
405 if (r)
406 goto out;
407 } else {
408 mem.config_page_dma = ioc->config_page_dma;
409 mem.config_page = ioc->config_page;
410 }
411 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
412 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
413 mem.config_page_dma);
414 r = _config_request(ioc, &mpi_request, mpi_reply,
415 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
416 if (!r)
417 memcpy(config_page, mem.config_page,
418 min_t(u16, mem.config_page_sz,
419 sizeof(Mpi2ManufacturingPage0_t)));
420
421 if (mem.config_page_sz > ioc->config_page_sz)
422 _config_free_config_dma_memory(ioc, &mem);
423
424 out:
Eric Moore635374e2009-03-09 01:21:12 -0600425 return r;
426}
427
428/**
Kashyap, Desaied79f122009-08-20 13:23:49 +0530429 * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
430 * @ioc: per adapter object
431 * @mpi_reply: reply mf payload returned from firmware
432 * @config_page: contents of the config page
433 * Context: sleep.
434 *
435 * Returns 0 for success, non-zero for failure.
436 */
437int
438mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
439 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page)
440{
441 Mpi2ConfigRequest_t mpi_request;
442 int r;
443 struct config_request mem;
444
445 memset(config_page, 0, sizeof(Mpi2ManufacturingPage10_t));
446 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
447 mpi_request.Function = MPI2_FUNCTION_CONFIG;
448 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
449 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
450 mpi_request.Header.PageNumber = 10;
451 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
452 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
453 r = _config_request(ioc, &mpi_request, mpi_reply,
454 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
455 if (r)
456 goto out;
457
458 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
459 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
460 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
461 mpi_request.Header.PageType = mpi_reply->Header.PageType;
462 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
463 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
464 if (mem.config_page_sz > ioc->config_page_sz) {
465 r = _config_alloc_config_dma_memory(ioc, &mem);
466 if (r)
467 goto out;
468 } else {
469 mem.config_page_dma = ioc->config_page_dma;
470 mem.config_page = ioc->config_page;
471 }
472 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
473 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
474 mem.config_page_dma);
475 r = _config_request(ioc, &mpi_request, mpi_reply,
476 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
477 if (!r)
478 memcpy(config_page, mem.config_page,
479 min_t(u16, mem.config_page_sz,
480 sizeof(Mpi2ManufacturingPage10_t)));
481
482 if (mem.config_page_sz > ioc->config_page_sz)
483 _config_free_config_dma_memory(ioc, &mem);
484
485 out:
486 return r;
487}
488
489/**
Eric Moore635374e2009-03-09 01:21:12 -0600490 * mpt2sas_config_get_bios_pg2 - obtain bios page 2
491 * @ioc: per adapter object
492 * @mpi_reply: reply mf payload returned from firmware
493 * @config_page: contents of the config page
494 * Context: sleep.
495 *
496 * Returns 0 for success, non-zero for failure.
497 */
498int
499mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
500 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
501{
502 Mpi2ConfigRequest_t mpi_request;
503 int r;
504 struct config_request mem;
505
Eric Moore635374e2009-03-09 01:21:12 -0600506 memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
507 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
508 mpi_request.Function = MPI2_FUNCTION_CONFIG;
509 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
510 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
511 mpi_request.Header.PageNumber = 2;
512 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
513 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
514 r = _config_request(ioc, &mpi_request, mpi_reply,
515 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
516 if (r)
517 goto out;
518
519 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
520 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
521 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
522 mpi_request.Header.PageType = mpi_reply->Header.PageType;
523 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
524 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
525 if (mem.config_page_sz > ioc->config_page_sz) {
526 r = _config_alloc_config_dma_memory(ioc, &mem);
527 if (r)
528 goto out;
529 } else {
530 mem.config_page_dma = ioc->config_page_dma;
531 mem.config_page = ioc->config_page;
532 }
533 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
534 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
535 mem.config_page_dma);
536 r = _config_request(ioc, &mpi_request, mpi_reply,
537 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
538 if (!r)
539 memcpy(config_page, mem.config_page,
540 min_t(u16, mem.config_page_sz,
541 sizeof(Mpi2BiosPage2_t)));
542
543 if (mem.config_page_sz > ioc->config_page_sz)
544 _config_free_config_dma_memory(ioc, &mem);
545
546 out:
Eric Moore635374e2009-03-09 01:21:12 -0600547 return r;
548}
549
550/**
551 * mpt2sas_config_get_bios_pg3 - obtain bios page 3
552 * @ioc: per adapter object
553 * @mpi_reply: reply mf payload returned from firmware
554 * @config_page: contents of the config page
555 * Context: sleep.
556 *
557 * Returns 0 for success, non-zero for failure.
558 */
559int
560mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
561 *mpi_reply, Mpi2BiosPage3_t *config_page)
562{
563 Mpi2ConfigRequest_t mpi_request;
564 int r;
565 struct config_request mem;
566
Eric Moore635374e2009-03-09 01:21:12 -0600567 memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
568 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
569 mpi_request.Function = MPI2_FUNCTION_CONFIG;
570 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
571 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
572 mpi_request.Header.PageNumber = 3;
573 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
574 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
575 r = _config_request(ioc, &mpi_request, mpi_reply,
576 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
577 if (r)
578 goto out;
579
580 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
581 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
582 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
583 mpi_request.Header.PageType = mpi_reply->Header.PageType;
584 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
585 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
586 if (mem.config_page_sz > ioc->config_page_sz) {
587 r = _config_alloc_config_dma_memory(ioc, &mem);
588 if (r)
589 goto out;
590 } else {
591 mem.config_page_dma = ioc->config_page_dma;
592 mem.config_page = ioc->config_page;
593 }
594 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
595 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
596 mem.config_page_dma);
597 r = _config_request(ioc, &mpi_request, mpi_reply,
598 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
599 if (!r)
600 memcpy(config_page, mem.config_page,
601 min_t(u16, mem.config_page_sz,
602 sizeof(Mpi2BiosPage3_t)));
603
604 if (mem.config_page_sz > ioc->config_page_sz)
605 _config_free_config_dma_memory(ioc, &mem);
606
607 out:
Eric Moore635374e2009-03-09 01:21:12 -0600608 return r;
609}
610
611/**
612 * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
613 * @ioc: per adapter object
614 * @mpi_reply: reply mf payload returned from firmware
615 * @config_page: contents of the config page
616 * Context: sleep.
617 *
618 * Returns 0 for success, non-zero for failure.
619 */
620int
621mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
622 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
623{
624 Mpi2ConfigRequest_t mpi_request;
625 int r;
626 struct config_request mem;
627
Eric Moore635374e2009-03-09 01:21:12 -0600628 memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
629 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
630 mpi_request.Function = MPI2_FUNCTION_CONFIG;
631 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
632 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
633 mpi_request.Header.PageNumber = 0;
634 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
635 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
636 r = _config_request(ioc, &mpi_request, mpi_reply,
637 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
638 if (r)
639 goto out;
640
641 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
642 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
643 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
644 mpi_request.Header.PageType = mpi_reply->Header.PageType;
645 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
646 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
647 if (mem.config_page_sz > ioc->config_page_sz) {
648 r = _config_alloc_config_dma_memory(ioc, &mem);
649 if (r)
650 goto out;
651 } else {
652 mem.config_page_dma = ioc->config_page_dma;
653 mem.config_page = ioc->config_page;
654 }
655 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
656 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
657 mem.config_page_dma);
658 r = _config_request(ioc, &mpi_request, mpi_reply,
659 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
660 if (!r)
661 memcpy(config_page, mem.config_page,
662 min_t(u16, mem.config_page_sz,
663 sizeof(Mpi2IOUnitPage0_t)));
664
665 if (mem.config_page_sz > ioc->config_page_sz)
666 _config_free_config_dma_memory(ioc, &mem);
667
668 out:
Eric Moore635374e2009-03-09 01:21:12 -0600669 return r;
670}
671
672/**
673 * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
674 * @ioc: per adapter object
675 * @mpi_reply: reply mf payload returned from firmware
676 * @config_page: contents of the config page
677 * Context: sleep.
678 *
679 * Returns 0 for success, non-zero for failure.
680 */
681int
682mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
683 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
684{
685 Mpi2ConfigRequest_t mpi_request;
686 int r;
687 struct config_request mem;
688
Eric Moore635374e2009-03-09 01:21:12 -0600689 memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
690 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
691 mpi_request.Function = MPI2_FUNCTION_CONFIG;
692 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
693 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
694 mpi_request.Header.PageNumber = 1;
695 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
696 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
697 r = _config_request(ioc, &mpi_request, mpi_reply,
698 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
699 if (r)
700 goto out;
701
702 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
703 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
704 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
705 mpi_request.Header.PageType = mpi_reply->Header.PageType;
706 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
707 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
708 if (mem.config_page_sz > ioc->config_page_sz) {
709 r = _config_alloc_config_dma_memory(ioc, &mem);
710 if (r)
711 goto out;
712 } else {
713 mem.config_page_dma = ioc->config_page_dma;
714 mem.config_page = ioc->config_page;
715 }
716 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
717 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
718 mem.config_page_dma);
719 r = _config_request(ioc, &mpi_request, mpi_reply,
720 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
721 if (!r)
722 memcpy(config_page, mem.config_page,
723 min_t(u16, mem.config_page_sz,
724 sizeof(Mpi2IOUnitPage1_t)));
725
726 if (mem.config_page_sz > ioc->config_page_sz)
727 _config_free_config_dma_memory(ioc, &mem);
728
729 out:
Eric Moore635374e2009-03-09 01:21:12 -0600730 return r;
731}
732
733/**
734 * mpt2sas_config_set_iounit_pg1 - set iounit page 1
735 * @ioc: per adapter object
736 * @mpi_reply: reply mf payload returned from firmware
737 * @config_page: contents of the config page
738 * Context: sleep.
739 *
740 * Returns 0 for success, non-zero for failure.
741 */
742int
743mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
744 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t config_page)
745{
746 Mpi2ConfigRequest_t mpi_request;
747 int r;
748 struct config_request mem;
749
Eric Moore635374e2009-03-09 01:21:12 -0600750 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
751 mpi_request.Function = MPI2_FUNCTION_CONFIG;
752 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
753 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
754 mpi_request.Header.PageNumber = 1;
755 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
756 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
757 r = _config_request(ioc, &mpi_request, mpi_reply,
758 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
759 if (r)
760 goto out;
761
762 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
763 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
764 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
765 mpi_request.Header.PageType = mpi_reply->Header.PageType;
766 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
767 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
768 if (mem.config_page_sz > ioc->config_page_sz) {
769 r = _config_alloc_config_dma_memory(ioc, &mem);
770 if (r)
771 goto out;
772 } else {
773 mem.config_page_dma = ioc->config_page_dma;
774 mem.config_page = ioc->config_page;
775 }
776
777 memset(mem.config_page, 0, mem.config_page_sz);
778 memcpy(mem.config_page, &config_page,
779 sizeof(Mpi2IOUnitPage1_t));
780
781 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
782 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.config_page_sz,
783 mem.config_page_dma);
784 r = _config_request(ioc, &mpi_request, mpi_reply,
785 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
786
787 if (mem.config_page_sz > ioc->config_page_sz)
788 _config_free_config_dma_memory(ioc, &mem);
789
790 out:
Eric Moore635374e2009-03-09 01:21:12 -0600791 return r;
792}
793
794/**
795 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
796 * @ioc: per adapter object
797 * @mpi_reply: reply mf payload returned from firmware
798 * @config_page: contents of the config page
799 * Context: sleep.
800 *
801 * Returns 0 for success, non-zero for failure.
802 */
803int
804mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
805 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
806{
807 Mpi2ConfigRequest_t mpi_request;
808 int r;
809 struct config_request mem;
810
Eric Moore635374e2009-03-09 01:21:12 -0600811 memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
812 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
813 mpi_request.Function = MPI2_FUNCTION_CONFIG;
814 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
815 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
816 mpi_request.Header.PageNumber = 8;
817 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
818 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
819 r = _config_request(ioc, &mpi_request, mpi_reply,
820 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
821 if (r)
822 goto out;
823
824 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
825 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
826 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
827 mpi_request.Header.PageType = mpi_reply->Header.PageType;
828 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
829 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
830 if (mem.config_page_sz > ioc->config_page_sz) {
831 r = _config_alloc_config_dma_memory(ioc, &mem);
832 if (r)
833 goto out;
834 } else {
835 mem.config_page_dma = ioc->config_page_dma;
836 mem.config_page = ioc->config_page;
837 }
838 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
839 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
840 mem.config_page_dma);
841 r = _config_request(ioc, &mpi_request, mpi_reply,
842 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
843 if (!r)
844 memcpy(config_page, mem.config_page,
845 min_t(u16, mem.config_page_sz,
846 sizeof(Mpi2IOCPage8_t)));
847
848 if (mem.config_page_sz > ioc->config_page_sz)
849 _config_free_config_dma_memory(ioc, &mem);
850
851 out:
Eric Moore635374e2009-03-09 01:21:12 -0600852 return r;
853}
854
855/**
856 * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
857 * @ioc: per adapter object
858 * @mpi_reply: reply mf payload returned from firmware
859 * @config_page: contents of the config page
860 * @form: GET_NEXT_HANDLE or HANDLE
861 * @handle: device handle
862 * Context: sleep.
863 *
864 * Returns 0 for success, non-zero for failure.
865 */
866int
867mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
868 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle)
869{
870 Mpi2ConfigRequest_t mpi_request;
871 int r;
872 struct config_request mem;
873
Eric Moore635374e2009-03-09 01:21:12 -0600874 memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
875 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
876 mpi_request.Function = MPI2_FUNCTION_CONFIG;
877 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
878 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
879 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
880 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
881 mpi_request.Header.PageNumber = 0;
882 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
883 r = _config_request(ioc, &mpi_request, mpi_reply,
884 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
885 if (r)
886 goto out;
887
888 mpi_request.PageAddress = cpu_to_le32(form | handle);
889 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
890 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
891 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
892 mpi_request.Header.PageType = mpi_reply->Header.PageType;
893 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
894 mpi_request.ExtPageType = mpi_reply->ExtPageType;
895 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
896 if (mem.config_page_sz > ioc->config_page_sz) {
897 r = _config_alloc_config_dma_memory(ioc, &mem);
898 if (r)
899 goto out;
900 } else {
901 mem.config_page_dma = ioc->config_page_dma;
902 mem.config_page = ioc->config_page;
903 }
904 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
905 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
906 mem.config_page_dma);
907 r = _config_request(ioc, &mpi_request, mpi_reply,
908 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
909 if (!r)
910 memcpy(config_page, mem.config_page,
911 min_t(u16, mem.config_page_sz,
912 sizeof(Mpi2SasDevicePage0_t)));
913
914 if (mem.config_page_sz > ioc->config_page_sz)
915 _config_free_config_dma_memory(ioc, &mem);
916
917 out:
Eric Moore635374e2009-03-09 01:21:12 -0600918 return r;
919}
920
921/**
922 * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
923 * @ioc: per adapter object
924 * @mpi_reply: reply mf payload returned from firmware
925 * @config_page: contents of the config page
926 * @form: GET_NEXT_HANDLE or HANDLE
927 * @handle: device handle
928 * Context: sleep.
929 *
930 * Returns 0 for success, non-zero for failure.
931 */
932int
933mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
934 *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle)
935{
936 Mpi2ConfigRequest_t mpi_request;
937 int r;
938 struct config_request mem;
939
Eric Moore635374e2009-03-09 01:21:12 -0600940 memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
941 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
942 mpi_request.Function = MPI2_FUNCTION_CONFIG;
943 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
944 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
945 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
946 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
947 mpi_request.Header.PageNumber = 1;
948 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
949 r = _config_request(ioc, &mpi_request, mpi_reply,
950 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
951 if (r)
952 goto out;
953
954 mpi_request.PageAddress = cpu_to_le32(form | handle);
955 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
956 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
957 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
958 mpi_request.Header.PageType = mpi_reply->Header.PageType;
959 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
960 mpi_request.ExtPageType = mpi_reply->ExtPageType;
961 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
962 if (mem.config_page_sz > ioc->config_page_sz) {
963 r = _config_alloc_config_dma_memory(ioc, &mem);
964 if (r)
965 goto out;
966 } else {
967 mem.config_page_dma = ioc->config_page_dma;
968 mem.config_page = ioc->config_page;
969 }
970 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
971 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
972 mem.config_page_dma);
973 r = _config_request(ioc, &mpi_request, mpi_reply,
974 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
975 if (!r)
976 memcpy(config_page, mem.config_page,
977 min_t(u16, mem.config_page_sz,
978 sizeof(Mpi2SasDevicePage1_t)));
979
980 if (mem.config_page_sz > ioc->config_page_sz)
981 _config_free_config_dma_memory(ioc, &mem);
982
983 out:
Eric Moore635374e2009-03-09 01:21:12 -0600984 return r;
985}
986
987/**
988 * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
989 * @ioc: per adapter object
990 * @num_phys: pointer returned with the number of phys
991 * Context: sleep.
992 *
993 * Returns 0 for success, non-zero for failure.
994 */
995int
996mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
997{
998 Mpi2ConfigRequest_t mpi_request;
999 int r;
1000 struct config_request mem;
1001 u16 ioc_status;
1002 Mpi2ConfigReply_t mpi_reply;
1003 Mpi2SasIOUnitPage0_t config_page;
1004
Eric Moore635374e2009-03-09 01:21:12 -06001005 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1006 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1007 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1008 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1009 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1010 mpi_request.Header.PageNumber = 0;
1011 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1012 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1013 r = _config_request(ioc, &mpi_request, &mpi_reply,
1014 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1015 if (r)
1016 goto out;
1017
1018 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1019 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1020 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1021 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1022 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
1023 mpi_request.ExtPageType = mpi_reply.ExtPageType;
1024 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
1025 if (mem.config_page_sz > ioc->config_page_sz) {
1026 r = _config_alloc_config_dma_memory(ioc, &mem);
1027 if (r)
1028 goto out;
1029 } else {
1030 mem.config_page_dma = ioc->config_page_dma;
1031 mem.config_page = ioc->config_page;
1032 }
1033 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1034 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1035 mem.config_page_dma);
1036 r = _config_request(ioc, &mpi_request, &mpi_reply,
1037 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1038 if (!r) {
1039 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1040 MPI2_IOCSTATUS_MASK;
1041 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1042 memcpy(&config_page, mem.config_page,
1043 min_t(u16, mem.config_page_sz,
1044 sizeof(Mpi2SasIOUnitPage0_t)));
1045 *num_phys = config_page.NumPhys;
1046 }
1047 }
1048
1049 if (mem.config_page_sz > ioc->config_page_sz)
1050 _config_free_config_dma_memory(ioc, &mem);
1051
1052 out:
Eric Moore635374e2009-03-09 01:21:12 -06001053 return r;
1054}
1055
1056/**
1057 * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1058 * @ioc: per adapter object
1059 * @mpi_reply: reply mf payload returned from firmware
1060 * @config_page: contents of the config page
1061 * @sz: size of buffer passed in config_page
1062 * Context: sleep.
1063 *
1064 * Calling function should call config_get_number_hba_phys prior to
1065 * this function, so enough memory is allocated for config_page.
1066 *
1067 * Returns 0 for success, non-zero for failure.
1068 */
1069int
1070mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1071 *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz)
1072{
1073 Mpi2ConfigRequest_t mpi_request;
1074 int r;
1075 struct config_request mem;
Eric Moore635374e2009-03-09 01:21:12 -06001076 memset(config_page, 0, sz);
1077 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1078 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1079 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1080 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1081 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1082 mpi_request.Header.PageNumber = 0;
1083 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1084 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1085 r = _config_request(ioc, &mpi_request, mpi_reply,
1086 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1087 if (r)
1088 goto out;
1089
1090 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1091 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1092 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1093 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1094 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1095 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1096 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1097 if (mem.config_page_sz > ioc->config_page_sz) {
1098 r = _config_alloc_config_dma_memory(ioc, &mem);
1099 if (r)
1100 goto out;
1101 } else {
1102 mem.config_page_dma = ioc->config_page_dma;
1103 mem.config_page = ioc->config_page;
1104 }
1105 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1106 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1107 mem.config_page_dma);
1108 r = _config_request(ioc, &mpi_request, mpi_reply,
1109 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1110 if (!r)
1111 memcpy(config_page, mem.config_page,
1112 min_t(u16, sz, mem.config_page_sz));
1113
1114 if (mem.config_page_sz > ioc->config_page_sz)
1115 _config_free_config_dma_memory(ioc, &mem);
1116
1117 out:
Eric Moore635374e2009-03-09 01:21:12 -06001118 return r;
1119}
1120
1121/**
1122 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0
1123 * @ioc: per adapter object
1124 * @mpi_reply: reply mf payload returned from firmware
1125 * @config_page: contents of the config page
1126 * @sz: size of buffer passed in config_page
1127 * Context: sleep.
1128 *
1129 * Calling function should call config_get_number_hba_phys prior to
1130 * this function, so enough memory is allocated for config_page.
1131 *
1132 * Returns 0 for success, non-zero for failure.
1133 */
1134int
1135mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1136 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
1137{
1138 Mpi2ConfigRequest_t mpi_request;
1139 int r;
1140 struct config_request mem;
1141
Eric Moore635374e2009-03-09 01:21:12 -06001142 memset(config_page, 0, sz);
1143 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1144 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1145 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1146 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1147 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1148 mpi_request.Header.PageNumber = 1;
1149 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1150 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1151 r = _config_request(ioc, &mpi_request, mpi_reply,
1152 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1153 if (r)
1154 goto out;
1155
1156 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1157 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1158 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1159 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1160 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1161 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1162 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1163 if (mem.config_page_sz > ioc->config_page_sz) {
1164 r = _config_alloc_config_dma_memory(ioc, &mem);
1165 if (r)
1166 goto out;
1167 } else {
1168 mem.config_page_dma = ioc->config_page_dma;
1169 mem.config_page = ioc->config_page;
1170 }
1171 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1172 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1173 mem.config_page_dma);
1174 r = _config_request(ioc, &mpi_request, mpi_reply,
1175 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1176 if (!r)
1177 memcpy(config_page, mem.config_page,
1178 min_t(u16, sz, mem.config_page_sz));
1179
1180 if (mem.config_page_sz > ioc->config_page_sz)
1181 _config_free_config_dma_memory(ioc, &mem);
1182
1183 out:
Eric Moore635374e2009-03-09 01:21:12 -06001184 return r;
1185}
1186
1187/**
1188 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
1189 * @ioc: per adapter object
1190 * @mpi_reply: reply mf payload returned from firmware
1191 * @config_page: contents of the config page
1192 * @form: GET_NEXT_HANDLE or HANDLE
1193 * @handle: expander handle
1194 * Context: sleep.
1195 *
1196 * Returns 0 for success, non-zero for failure.
1197 */
1198int
1199mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1200 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1201{
1202 Mpi2ConfigRequest_t mpi_request;
1203 int r;
1204 struct config_request mem;
1205
Eric Moore635374e2009-03-09 01:21:12 -06001206 memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
1207 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1208 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1209 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1210 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1211 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1212 mpi_request.Header.PageNumber = 0;
1213 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1214 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1215 r = _config_request(ioc, &mpi_request, mpi_reply,
1216 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1217 if (r)
1218 goto out;
1219
1220 mpi_request.PageAddress = cpu_to_le32(form | handle);
1221 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1222 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1223 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1224 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1225 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1226 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1227 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1228 if (mem.config_page_sz > ioc->config_page_sz) {
1229 r = _config_alloc_config_dma_memory(ioc, &mem);
1230 if (r)
1231 goto out;
1232 } else {
1233 mem.config_page_dma = ioc->config_page_dma;
1234 mem.config_page = ioc->config_page;
1235 }
1236 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1237 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1238 mem.config_page_dma);
1239 r = _config_request(ioc, &mpi_request, mpi_reply,
1240 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1241 if (!r)
1242 memcpy(config_page, mem.config_page,
1243 min_t(u16, mem.config_page_sz,
1244 sizeof(Mpi2ExpanderPage0_t)));
1245
1246 if (mem.config_page_sz > ioc->config_page_sz)
1247 _config_free_config_dma_memory(ioc, &mem);
1248
1249 out:
Eric Moore635374e2009-03-09 01:21:12 -06001250 return r;
1251}
1252
1253/**
1254 * mpt2sas_config_get_expander_pg1 - obtain expander page 1
1255 * @ioc: per adapter object
1256 * @mpi_reply: reply mf payload returned from firmware
1257 * @config_page: contents of the config page
1258 * @phy_number: phy number
1259 * @handle: expander handle
1260 * Context: sleep.
1261 *
1262 * Returns 0 for success, non-zero for failure.
1263 */
1264int
1265mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1266 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1267 u16 handle)
1268{
1269 Mpi2ConfigRequest_t mpi_request;
1270 int r;
1271 struct config_request mem;
1272
Eric Moore635374e2009-03-09 01:21:12 -06001273 memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
1274 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1275 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1276 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1277 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1278 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1279 mpi_request.Header.PageNumber = 1;
1280 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1281 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1282 r = _config_request(ioc, &mpi_request, mpi_reply,
1283 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1284 if (r)
1285 goto out;
1286
1287 mpi_request.PageAddress =
1288 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1289 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1290 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1291 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1292 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1293 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1294 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1295 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1296 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1297 if (mem.config_page_sz > ioc->config_page_sz) {
1298 r = _config_alloc_config_dma_memory(ioc, &mem);
1299 if (r)
1300 goto out;
1301 } else {
1302 mem.config_page_dma = ioc->config_page_dma;
1303 mem.config_page = ioc->config_page;
1304 }
1305 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1306 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1307 mem.config_page_dma);
1308 r = _config_request(ioc, &mpi_request, mpi_reply,
1309 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1310 if (!r)
1311 memcpy(config_page, mem.config_page,
1312 min_t(u16, mem.config_page_sz,
1313 sizeof(Mpi2ExpanderPage1_t)));
1314
1315 if (mem.config_page_sz > ioc->config_page_sz)
1316 _config_free_config_dma_memory(ioc, &mem);
1317
1318 out:
Eric Moore635374e2009-03-09 01:21:12 -06001319 return r;
1320}
1321
1322/**
1323 * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
1324 * @ioc: per adapter object
1325 * @mpi_reply: reply mf payload returned from firmware
1326 * @config_page: contents of the config page
1327 * @form: GET_NEXT_HANDLE or HANDLE
1328 * @handle: expander handle
1329 * Context: sleep.
1330 *
1331 * Returns 0 for success, non-zero for failure.
1332 */
1333int
1334mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1335 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1336{
1337 Mpi2ConfigRequest_t mpi_request;
1338 int r;
1339 struct config_request mem;
1340
Eric Moore635374e2009-03-09 01:21:12 -06001341 memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
1342 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1343 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1344 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1345 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1346 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1347 mpi_request.Header.PageNumber = 0;
1348 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1349 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1350 r = _config_request(ioc, &mpi_request, mpi_reply,
1351 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1352 if (r)
1353 goto out;
1354
1355 mpi_request.PageAddress = cpu_to_le32(form | handle);
1356 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1357 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1358 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1359 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1360 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1361 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1362 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1363 if (mem.config_page_sz > ioc->config_page_sz) {
1364 r = _config_alloc_config_dma_memory(ioc, &mem);
1365 if (r)
1366 goto out;
1367 } else {
1368 mem.config_page_dma = ioc->config_page_dma;
1369 mem.config_page = ioc->config_page;
1370 }
1371 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1372 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1373 mem.config_page_dma);
1374 r = _config_request(ioc, &mpi_request, mpi_reply,
1375 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1376 if (!r)
1377 memcpy(config_page, mem.config_page,
1378 min_t(u16, mem.config_page_sz,
1379 sizeof(Mpi2SasEnclosurePage0_t)));
1380
1381 if (mem.config_page_sz > ioc->config_page_sz)
1382 _config_free_config_dma_memory(ioc, &mem);
1383
1384 out:
Eric Moore635374e2009-03-09 01:21:12 -06001385 return r;
1386}
1387
1388/**
1389 * mpt2sas_config_get_phy_pg0 - obtain phy page 0
1390 * @ioc: per adapter object
1391 * @mpi_reply: reply mf payload returned from firmware
1392 * @config_page: contents of the config page
1393 * @phy_number: phy number
1394 * Context: sleep.
1395 *
1396 * Returns 0 for success, non-zero for failure.
1397 */
1398int
1399mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1400 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1401{
1402 Mpi2ConfigRequest_t mpi_request;
1403 int r;
1404 struct config_request mem;
1405
Eric Moore635374e2009-03-09 01:21:12 -06001406 memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
1407 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1408 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1409 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1410 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1411 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1412 mpi_request.Header.PageNumber = 0;
1413 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1414 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1415 r = _config_request(ioc, &mpi_request, mpi_reply,
1416 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1417 if (r)
1418 goto out;
1419
1420 mpi_request.PageAddress =
1421 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1422 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1423 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1424 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1425 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1426 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1427 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1428 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1429 if (mem.config_page_sz > ioc->config_page_sz) {
1430 r = _config_alloc_config_dma_memory(ioc, &mem);
1431 if (r)
1432 goto out;
1433 } else {
1434 mem.config_page_dma = ioc->config_page_dma;
1435 mem.config_page = ioc->config_page;
1436 }
1437 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1438 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1439 mem.config_page_dma);
1440 r = _config_request(ioc, &mpi_request, mpi_reply,
1441 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1442 if (!r)
1443 memcpy(config_page, mem.config_page,
1444 min_t(u16, mem.config_page_sz,
1445 sizeof(Mpi2SasPhyPage0_t)));
1446
1447 if (mem.config_page_sz > ioc->config_page_sz)
1448 _config_free_config_dma_memory(ioc, &mem);
1449
1450 out:
Eric Moore635374e2009-03-09 01:21:12 -06001451 return r;
1452}
1453
1454/**
1455 * mpt2sas_config_get_phy_pg1 - obtain phy page 1
1456 * @ioc: per adapter object
1457 * @mpi_reply: reply mf payload returned from firmware
1458 * @config_page: contents of the config page
1459 * @phy_number: phy number
1460 * Context: sleep.
1461 *
1462 * Returns 0 for success, non-zero for failure.
1463 */
1464int
1465mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1466 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1467{
1468 Mpi2ConfigRequest_t mpi_request;
1469 int r;
1470 struct config_request mem;
1471
Eric Moore635374e2009-03-09 01:21:12 -06001472 memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
1473 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1474 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1475 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1476 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1477 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1478 mpi_request.Header.PageNumber = 1;
1479 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1480 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1481 r = _config_request(ioc, &mpi_request, mpi_reply,
1482 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1483 if (r)
1484 goto out;
1485
1486 mpi_request.PageAddress =
1487 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1488 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1489 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1490 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1491 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1492 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1493 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1494 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1495 if (mem.config_page_sz > ioc->config_page_sz) {
1496 r = _config_alloc_config_dma_memory(ioc, &mem);
1497 if (r)
1498 goto out;
1499 } else {
1500 mem.config_page_dma = ioc->config_page_dma;
1501 mem.config_page = ioc->config_page;
1502 }
1503 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1504 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1505 mem.config_page_dma);
1506 r = _config_request(ioc, &mpi_request, mpi_reply,
1507 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1508 if (!r)
1509 memcpy(config_page, mem.config_page,
1510 min_t(u16, mem.config_page_sz,
1511 sizeof(Mpi2SasPhyPage1_t)));
1512
1513 if (mem.config_page_sz > ioc->config_page_sz)
1514 _config_free_config_dma_memory(ioc, &mem);
1515
1516 out:
Eric Moore635374e2009-03-09 01:21:12 -06001517 return r;
1518}
1519
1520/**
1521 * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1522 * @ioc: per adapter object
1523 * @mpi_reply: reply mf payload returned from firmware
1524 * @config_page: contents of the config page
1525 * @form: GET_NEXT_HANDLE or HANDLE
1526 * @handle: volume handle
1527 * Context: sleep.
1528 *
1529 * Returns 0 for success, non-zero for failure.
1530 */
1531int
1532mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
1533 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1534 u32 handle)
1535{
1536 Mpi2ConfigRequest_t mpi_request;
1537 int r;
1538 struct config_request mem;
1539
Eric Moore635374e2009-03-09 01:21:12 -06001540 memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
1541 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1542 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1543 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1544 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1545 mpi_request.Header.PageNumber = 1;
1546 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1547 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1548 r = _config_request(ioc, &mpi_request, mpi_reply,
1549 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1550 if (r)
1551 goto out;
1552
1553 mpi_request.PageAddress = cpu_to_le32(form | handle);
1554 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1555 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1556 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1557 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1558 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1559 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1560 if (mem.config_page_sz > ioc->config_page_sz) {
1561 r = _config_alloc_config_dma_memory(ioc, &mem);
1562 if (r)
1563 goto out;
1564 } else {
1565 mem.config_page_dma = ioc->config_page_dma;
1566 mem.config_page = ioc->config_page;
1567 }
1568 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1569 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1570 mem.config_page_dma);
1571 r = _config_request(ioc, &mpi_request, mpi_reply,
1572 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1573 if (!r)
1574 memcpy(config_page, mem.config_page,
1575 min_t(u16, mem.config_page_sz,
1576 sizeof(Mpi2RaidVolPage1_t)));
1577
1578 if (mem.config_page_sz > ioc->config_page_sz)
1579 _config_free_config_dma_memory(ioc, &mem);
1580
1581 out:
Eric Moore635374e2009-03-09 01:21:12 -06001582 return r;
1583}
1584
1585/**
1586 * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
1587 * @ioc: per adapter object
1588 * @handle: volume handle
1589 * @num_pds: returns pds count
1590 * Context: sleep.
1591 *
1592 * Returns 0 for success, non-zero for failure.
1593 */
1594int
1595mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
1596 u8 *num_pds)
1597{
1598 Mpi2ConfigRequest_t mpi_request;
1599 Mpi2RaidVolPage0_t *config_page;
1600 Mpi2ConfigReply_t mpi_reply;
1601 int r;
1602 struct config_request mem;
1603 u16 ioc_status;
1604
Eric Moore635374e2009-03-09 01:21:12 -06001605 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1606 *num_pds = 0;
1607 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1609 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1610 mpi_request.Header.PageNumber = 0;
1611 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1612 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1613 r = _config_request(ioc, &mpi_request, &mpi_reply,
1614 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1615 if (r)
1616 goto out;
1617
1618 mpi_request.PageAddress =
1619 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1620 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1621 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1622 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1623 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1624 mpi_request.Header.PageLength = mpi_reply.Header.PageLength;
1625 mem.config_page_sz = le16_to_cpu(mpi_reply.Header.PageLength) * 4;
1626 if (mem.config_page_sz > ioc->config_page_sz) {
1627 r = _config_alloc_config_dma_memory(ioc, &mem);
1628 if (r)
1629 goto out;
1630 } else {
1631 mem.config_page_dma = ioc->config_page_dma;
1632 mem.config_page = ioc->config_page;
1633 }
1634 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1635 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1636 mem.config_page_dma);
1637 r = _config_request(ioc, &mpi_request, &mpi_reply,
1638 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1639 if (!r) {
1640 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1641 MPI2_IOCSTATUS_MASK;
1642 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1643 config_page = mem.config_page;
1644 *num_pds = config_page->NumPhysDisks;
1645 }
1646 }
1647
1648 if (mem.config_page_sz > ioc->config_page_sz)
1649 _config_free_config_dma_memory(ioc, &mem);
1650
1651 out:
Eric Moore635374e2009-03-09 01:21:12 -06001652 return r;
1653}
1654
1655/**
1656 * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1657 * @ioc: per adapter object
1658 * @mpi_reply: reply mf payload returned from firmware
1659 * @config_page: contents of the config page
1660 * @form: GET_NEXT_HANDLE or HANDLE
1661 * @handle: volume handle
1662 * @sz: size of buffer passed in config_page
1663 * Context: sleep.
1664 *
1665 * Returns 0 for success, non-zero for failure.
1666 */
1667int
1668mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
1669 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1670 u32 handle, u16 sz)
1671{
1672 Mpi2ConfigRequest_t mpi_request;
1673 int r;
1674 struct config_request mem;
1675
Eric Moore635374e2009-03-09 01:21:12 -06001676 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1677 memset(config_page, 0, sz);
1678 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1679 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1680 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1681 mpi_request.Header.PageNumber = 0;
1682 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1683 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1684 r = _config_request(ioc, &mpi_request, mpi_reply,
1685 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1686 if (r)
1687 goto out;
1688
1689 mpi_request.PageAddress = cpu_to_le32(form | handle);
1690 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1691 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1692 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1693 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1694 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1695 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1696 if (mem.config_page_sz > ioc->config_page_sz) {
1697 r = _config_alloc_config_dma_memory(ioc, &mem);
1698 if (r)
1699 goto out;
1700 } else {
1701 mem.config_page_dma = ioc->config_page_dma;
1702 mem.config_page = ioc->config_page;
1703 }
1704 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1705 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1706 mem.config_page_dma);
1707 r = _config_request(ioc, &mpi_request, mpi_reply,
1708 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1709 if (!r)
1710 memcpy(config_page, mem.config_page,
1711 min_t(u16, sz, mem.config_page_sz));
1712
1713 if (mem.config_page_sz > ioc->config_page_sz)
1714 _config_free_config_dma_memory(ioc, &mem);
1715
1716 out:
Eric Moore635374e2009-03-09 01:21:12 -06001717 return r;
1718}
1719
1720/**
1721 * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1722 * @ioc: per adapter object
1723 * @mpi_reply: reply mf payload returned from firmware
1724 * @config_page: contents of the config page
1725 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1726 * @form_specific: specific to the form
1727 * Context: sleep.
1728 *
1729 * Returns 0 for success, non-zero for failure.
1730 */
1731int
1732mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1733 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1734 u32 form_specific)
1735{
1736 Mpi2ConfigRequest_t mpi_request;
1737 int r;
1738 struct config_request mem;
1739
Eric Moore635374e2009-03-09 01:21:12 -06001740 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1741 memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
1742 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1743 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1744 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1745 mpi_request.Header.PageNumber = 0;
1746 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1747 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1748 r = _config_request(ioc, &mpi_request, mpi_reply,
1749 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1750 if (r)
1751 goto out;
1752
1753 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1754 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1755 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1756 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1757 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1758 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1759 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1760 if (mem.config_page_sz > ioc->config_page_sz) {
1761 r = _config_alloc_config_dma_memory(ioc, &mem);
1762 if (r)
1763 goto out;
1764 } else {
1765 mem.config_page_dma = ioc->config_page_dma;
1766 mem.config_page = ioc->config_page;
1767 }
1768 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1769 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1770 mem.config_page_dma);
1771 r = _config_request(ioc, &mpi_request, mpi_reply,
1772 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1773 if (!r)
1774 memcpy(config_page, mem.config_page,
1775 min_t(u16, mem.config_page_sz,
1776 sizeof(Mpi2RaidPhysDiskPage0_t)));
1777
1778 if (mem.config_page_sz > ioc->config_page_sz)
1779 _config_free_config_dma_memory(ioc, &mem);
1780
1781 out:
Eric Moore635374e2009-03-09 01:21:12 -06001782 return r;
1783}
1784
1785/**
1786 * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
1787 * @ioc: per adapter object
1788 * @pd_handle: phys disk handle
1789 * @volume_handle: volume handle
1790 * Context: sleep.
1791 *
1792 * Returns 0 for success, non-zero for failure.
1793 */
1794int
1795mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1796 u16 *volume_handle)
1797{
1798 Mpi2RaidConfigurationPage0_t *config_page;
1799 Mpi2ConfigRequest_t mpi_request;
1800 Mpi2ConfigReply_t mpi_reply;
1801 int r, i;
1802 struct config_request mem;
1803 u16 ioc_status;
1804
Eric Moore635374e2009-03-09 01:21:12 -06001805 *volume_handle = 0;
1806 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1807 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1808 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1809 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1810 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1811 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1812 mpi_request.Header.PageNumber = 0;
1813 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1814 r = _config_request(ioc, &mpi_request, &mpi_reply,
1815 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1816 if (r)
1817 goto out;
1818
1819 mpi_request.PageAddress =
1820 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
1821 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1822 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1823 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1824 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1825 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
1826 mpi_request.ExtPageType = mpi_reply.ExtPageType;
1827 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
1828 if (mem.config_page_sz > ioc->config_page_sz) {
1829 r = _config_alloc_config_dma_memory(ioc, &mem);
1830 if (r)
1831 goto out;
1832 } else {
1833 mem.config_page_dma = ioc->config_page_dma;
1834 mem.config_page = ioc->config_page;
1835 }
1836 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1837 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1838 mem.config_page_dma);
1839 r = _config_request(ioc, &mpi_request, &mpi_reply,
1840 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1841 if (r)
1842 goto out;
1843
1844 r = -1;
1845 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
1846 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1847 goto done;
1848 config_page = mem.config_page;
1849 for (i = 0; i < config_page->NumElements; i++) {
1850 if ((config_page->ConfigElement[i].ElementFlags &
1851 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
1852 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
1853 continue;
1854 if (config_page->ConfigElement[i].PhysDiskDevHandle ==
1855 pd_handle) {
1856 *volume_handle = le16_to_cpu(config_page->
1857 ConfigElement[i].VolDevHandle);
1858 r = 0;
1859 goto done;
1860 }
1861 }
1862
1863 done:
1864 if (mem.config_page_sz > ioc->config_page_sz)
1865 _config_free_config_dma_memory(ioc, &mem);
1866
1867 out:
Eric Moore635374e2009-03-09 01:21:12 -06001868 return r;
1869}
1870
1871/**
1872 * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
1873 * @ioc: per adapter object
1874 * @volume_handle: volume handle
1875 * @wwid: volume wwid
1876 * Context: sleep.
1877 *
1878 * Returns 0 for success, non-zero for failure.
1879 */
1880int
1881mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
1882 u64 *wwid)
1883{
1884 Mpi2ConfigReply_t mpi_reply;
1885 Mpi2RaidVolPage1_t raid_vol_pg1;
1886
1887 *wwid = 0;
1888 if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1889 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1890 volume_handle))) {
1891 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
1892 return 0;
1893 } else
1894 return -1;
1895}