Blame view

drivers/scsi/mpt2sas/mpt2sas_config.c 45.8 KB
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1
2
3
4
  /*
   * This module provides common API for accessing firmware configuration pages
   *
   * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
31b7f2e25   Kashyap, Desai   [SCSI] mpt2sas: C...
5
   * Copyright (C) 2007-2010  LSI Corporation
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   *  (mailto:DL-MPTFusionLinux@lsi.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * NO WARRANTY
   * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
   * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
   * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
   * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
   * solely responsible for determining the appropriateness of using and
   * distributing the Program and assumes all risks associated with its
   * exercise of rights under this Agreement, including but not limited to
   * the risks and costs of program errors, damage to or loss of data,
   * programs or equipment, and unavailability or interruption of operations.
  
   * DISCLAIMER OF LIABILITY
   * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
   * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
   * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
   * USA.
   */
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
43
44
45
46
47
48
49
50
51
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/errno.h>
  #include <linux/blkdev.h>
  #include <linux/sched.h>
  #include <linux/workqueue.h>
  #include <linux/delay.h>
  #include <linux/pci.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
52
  #include <linux/slab.h>
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  
  #include "mpt2sas_base.h"
  
  /* local definitions */
  
  /* Timeout for config page request (in seconds) */
  #define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
  
  /* Common sgl flags for READING a config page. */
  #define MPT2_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
      MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
      | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
  
  /* Common sgl flags for WRITING a config page. */
  #define MPT2_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
      MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
      | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
      << MPI2_SGE_FLAGS_SHIFT)
  
  /**
   * struct config_request - obtain dma memory via routine
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
74
75
76
   * @sz: size
   * @page: virt pointer
   * @page_dma: phys pointer
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
77
78
79
   *
   */
  struct config_request{
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
80
81
82
  	u16			sz;
  	void			*page;
  	dma_addr_t		page_dma;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
83
84
85
86
87
88
89
90
91
92
93
  };
  
  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
  /**
   * _config_display_some_debug - debug routine
   * @ioc: per adapter object
   * @smid: system request message index
   * @calling_function_name: string pass from calling function
   * @mpi_reply: reply message frame
   * Context: none.
   *
25985edce   Lucas De Marchi   Fix common misspe...
94
   * Function for displaying debug info helpful when debugging issues
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
   * in this module.
   */
  static void
  _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
      char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
  {
  	Mpi2ConfigRequest_t *mpi_request;
  	char *desc = NULL;
  
  	if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  		return;
  
  	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
  	switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
  	case MPI2_CONFIG_PAGETYPE_IO_UNIT:
  		desc = "io_unit";
  		break;
  	case MPI2_CONFIG_PAGETYPE_IOC:
  		desc = "ioc";
  		break;
  	case MPI2_CONFIG_PAGETYPE_BIOS:
  		desc = "bios";
  		break;
  	case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
  		desc = "raid_volume";
  		break;
  	case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
  		desc = "manufaucturing";
  		break;
  	case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
  		desc = "physdisk";
  		break;
  	case MPI2_CONFIG_PAGETYPE_EXTENDED:
  		switch (mpi_request->ExtPageType) {
  		case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
  			desc = "sas_io_unit";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
  			desc = "sas_expander";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
  			desc = "sas_device";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
  			desc = "sas_phy";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_LOG:
  			desc = "log";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
  			desc = "enclosure";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
  			desc = "raid_config";
  			break;
  		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
  			desc = "driver_mappping";
  			break;
  		}
  		break;
  	}
  
  	if (!desc)
  		return;
eabb08ad2   Kashyap, Desai   [SCSI] mpt2sas: p...
159
  	printk(MPT2SAS_INFO_FMT "%s: %s(%d), action(%d), form(0x%08x), "
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
160
161
162
163
164
165
166
167
168
  	    "smid(%d)
  ", ioc->name, calling_function_name, desc,
  	    mpi_request->Header.PageNumber, mpi_request->Action,
  	    le32_to_cpu(mpi_request->PageAddress), smid);
  
  	if (!mpi_reply)
  		return;
  
  	if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
eabb08ad2   Kashyap, Desai   [SCSI] mpt2sas: p...
169
  		printk(MPT2SAS_INFO_FMT
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
170
171
172
173
174
175
176
177
  		    "\tiocstatus(0x%04x), loginfo(0x%08x)
  ",
  		    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
  		    le32_to_cpu(mpi_reply->IOCLogInfo));
  }
  #endif
  
  /**
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
   * _config_alloc_config_dma_memory - obtain physical memory
   * @ioc: per adapter object
   * @mem: struct config_request
   *
   * A wrapper for obtaining dma-able memory for config page request.
   *
   * Returns 0 for success, non-zero for failure.
   */
  static int
  _config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
      struct config_request *mem)
  {
  	int r = 0;
  
  	if (mem->sz > ioc->config_page_sz) {
  		mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
  		    &mem->page_dma, GFP_KERNEL);
  		if (!mem->page) {
  			printk(MPT2SAS_ERR_FMT "%s: dma_alloc_coherent"
  			    " failed asking for (%d) bytes!!
  ",
  			    ioc->name, __func__, mem->sz);
  			r = -ENOMEM;
  		}
  	} else { /* use tmp buffer if less than 512 bytes */
  		mem->page = ioc->config_page;
  		mem->page_dma = ioc->config_page_dma;
  	}
  	return r;
  }
  
  /**
   * _config_free_config_dma_memory - wrapper to free the memory
   * @ioc: per adapter object
   * @mem: struct config_request
   *
   * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
   *
   * Returns 0 for success, non-zero for failure.
   */
  static void
  _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
      struct config_request *mem)
  {
  	if (mem->sz > ioc->config_page_sz)
  		dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
  		    mem->page_dma);
  }
  
  /**
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
228
229
230
   * mpt2sas_config_done - config page completion routine
   * @ioc: per adapter object
   * @smid: system request message index
7b936b022   Kashyap, Desai   [SCSI] mpt2sas: U...
231
   * @msix_index: MSIX table index supplied by the OS
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
232
233
234
235
236
   * @reply: reply message frame(lower 32bit addr)
   * Context: none.
   *
   * The callback handler when using _config_request.
   *
77e63ed44   Kashyap, Desai   [SCSI] mpt2sas: T...
237
238
   * Return 1 meaning mf should be freed from _base_interrupt
   *        0 means the mf is freed from this function.
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
239
   */
77e63ed44   Kashyap, Desai   [SCSI] mpt2sas: T...
240
  u8
7b936b022   Kashyap, Desai   [SCSI] mpt2sas: U...
241
242
  mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
      u32 reply)
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
243
244
245
246
  {
  	MPI2DefaultReply_t *mpi_reply;
  
  	if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
77e63ed44   Kashyap, Desai   [SCSI] mpt2sas: T...
247
  		return 1;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
248
  	if (ioc->config_cmds.smid != smid)
77e63ed44   Kashyap, Desai   [SCSI] mpt2sas: T...
249
  		return 1;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
250
251
252
253
254
255
256
257
258
259
260
  	ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
  	mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
  	if (mpi_reply) {
  		ioc->config_cmds.status |= MPT2_CMD_REPLY_VALID;
  		memcpy(ioc->config_cmds.reply, mpi_reply,
  		    mpi_reply->MsgLength*4);
  	}
  	ioc->config_cmds.status &= ~MPT2_CMD_PENDING;
  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
  	_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
  #endif
4be929be3   Alexey Dobriyan   kernel-wide: repl...
261
  	ioc->config_cmds.smid = USHRT_MAX;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
262
  	complete(&ioc->config_cmds.done);
77e63ed44   Kashyap, Desai   [SCSI] mpt2sas: T...
263
  	return 1;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
264
265
266
267
268
269
270
271
  }
  
  /**
   * _config_request - main routine for sending config page requests
   * @ioc: per adapter object
   * @mpi_request: request message frame
   * @mpi_reply: reply mf payload returned from firmware
   * @timeout: timeout in seconds
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
272
273
274
   * @config_page: contents of the config page
   * @config_page_sz: size of config page
   * Context: sleep
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
275
276
277
278
279
280
281
282
283
284
285
286
   *
   * A generic API for config page requests to firmware.
   *
   * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
   * this API.
   *
   * The callback index is set inside `ioc->config_cb_idx.
   *
   * Returns 0 for success, non-zero for failure.
   */
  static int
  _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
287
288
      *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
      void *config_page, u16 config_page_sz)
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
289
290
291
292
293
294
  {
  	u16 smid;
  	u32 ioc_state;
  	unsigned long timeleft;
  	Mpi2ConfigRequest_t *config_request;
  	int r;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
295
  	u8 retry_count, issue_host_reset = 0;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
296
  	u16 wait_state_count;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
297
  	struct config_request mem;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
298

388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
299
  	mutex_lock(&ioc->config_cmds.mutex);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
300
301
302
303
  	if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
  		printk(MPT2SAS_ERR_FMT "%s: config_cmd in use
  ",
  		    ioc->name, __func__);
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
304
  		mutex_unlock(&ioc->config_cmds.mutex);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
305
306
  		return -EAGAIN;
  	}
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
307

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
308
  	retry_count = 0;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
309
  	memset(&mem, 0, sizeof(struct config_request));
7b936b022   Kashyap, Desai   [SCSI] mpt2sas: U...
310
311
  	mpi_request->VF_ID = 0; /* TODO */
  	mpi_request->VP_ID = 0;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  	if (config_page) {
  		mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
  		mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
  		mpi_request->Header.PageType = mpi_reply->Header.PageType;
  		mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
  		mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
  		mpi_request->ExtPageType = mpi_reply->ExtPageType;
  		if (mpi_request->Header.PageLength)
  			mem.sz = mpi_request->Header.PageLength * 4;
  		else
  			mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
  		r = _config_alloc_config_dma_memory(ioc, &mem);
  		if (r != 0)
  			goto out;
  		if (mpi_request->Action ==
50d5c6063   Kashyap, Desai   [SCSI] mpt2sas: A...
327
328
329
  		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
  		    mpi_request->Action ==
  		    MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
330
331
332
333
334
335
336
337
338
339
340
  			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
  			    MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
  			    mem.page_dma);
  			memcpy(mem.page, config_page, min_t(u16, mem.sz,
  			    config_page_sz));
  		} else {
  			memset(config_page, 0, config_page_sz);
  			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
  			    MPT2_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
  		}
  	}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
341
342
  
   retry_config:
6bd4e1e4d   Kashyap, Desai   [SCSI] mpt2sas: f...
343
  	if (retry_count) {
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
344
345
346
347
  		if (retry_count > 2) { /* attempt only 2 retries */
  			r = -EFAULT;
  			goto free_mem;
  		}
6bd4e1e4d   Kashyap, Desai   [SCSI] mpt2sas: f...
348
349
350
351
  		printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)
  ",
  		    ioc->name, __func__, retry_count);
  	}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
352
353
354
355
356
357
358
359
  	wait_state_count = 0;
  	ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  	while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
  		if (wait_state_count++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT) {
  			printk(MPT2SAS_ERR_FMT
  			    "%s: failed due to ioc not operational
  ",
  			    ioc->name, __func__);
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
360
  			ioc->config_cmds.status = MPT2_CMD_NOT_USED;
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
361
  			r = -EFAULT;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
362
  			goto free_mem;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  		}
  		ssleep(1);
  		ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
  		printk(MPT2SAS_INFO_FMT "%s: waiting for "
  		    "operational state(count=%d)
  ", ioc->name,
  		    __func__, wait_state_count);
  	}
  	if (wait_state_count)
  		printk(MPT2SAS_INFO_FMT "%s: ioc is operational
  ",
  		    ioc->name, __func__);
  
  	smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx);
  	if (!smid) {
  		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid
  ",
  		    ioc->name, __func__);
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
381
  		ioc->config_cmds.status = MPT2_CMD_NOT_USED;
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
382
  		r = -EAGAIN;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
383
  		goto free_mem;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
384
385
386
387
388
389
390
391
392
393
394
  	}
  
  	r = 0;
  	memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
  	ioc->config_cmds.status = MPT2_CMD_PENDING;
  	config_request = mpt2sas_base_get_msg_frame(ioc, smid);
  	ioc->config_cmds.smid = smid;
  	memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
  	_config_display_some_debug(ioc, smid, "config_request", NULL);
  #endif
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
395
  	init_completion(&ioc->config_cmds.done);
7b936b022   Kashyap, Desai   [SCSI] mpt2sas: U...
396
  	mpt2sas_base_put_smid_default(ioc, smid);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
397
398
399
400
401
402
403
404
  	timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
  	    timeout*HZ);
  	if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
  		printk(MPT2SAS_ERR_FMT "%s: timeout
  ",
  		    ioc->name, __func__);
  		_debug_dump_mf(mpi_request,
  		    sizeof(Mpi2ConfigRequest_t)/4);
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
405
406
407
  		retry_count++;
  		if (ioc->config_cmds.smid == smid)
  			mpt2sas_base_free_smid(ioc, smid);
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
408
  		if ((ioc->shost_recovery) || (ioc->config_cmds.status &
3cb5469a2   Eric Moore   [SCSI] mpt2sas: d...
409
  		    MPT2_CMD_RESET) || ioc->pci_error_recovery)
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
410
411
412
  			goto retry_config;
  		issue_host_reset = 1;
  		r = -EFAULT;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
413
  		goto free_mem;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
414
  	}
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
415

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
416
417
418
419
  	if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
  		memcpy(mpi_reply, ioc->config_cmds.reply,
  		    sizeof(Mpi2ConfigReply_t));
  	if (retry_count)
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
420
421
422
423
424
425
426
427
428
429
430
  		printk(MPT2SAS_INFO_FMT "%s: retry (%d) completed!!
  ",
  		    ioc->name, __func__, retry_count);
  	if (config_page && mpi_request->Action ==
  	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT)
  		memcpy(config_page, mem.page, min_t(u16, mem.sz,
  		    config_page_sz));
   free_mem:
  	if (config_page)
  		_config_free_config_dma_memory(ioc, &mem);
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
431
  	ioc->config_cmds.status = MPT2_CMD_NOT_USED;
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
432
  	mutex_unlock(&ioc->config_cmds.mutex);
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
433

388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
434
  	if (issue_host_reset)
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
435
436
  		mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
  		    FORCE_BIG_HAMMER);
388ce4beb   Kashyap, Desai   [SCSI] mpt2sas: f...
437
  	return r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
438
439
440
  }
  
  /**
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
441
442
443
444
445
446
447
448
449
450
451
452
453
454
   * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
455

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
456
457
458
459
460
461
462
463
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
464
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
465
466
467
468
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
469
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
470
471
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
472
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
473
474
475
476
  	return r;
  }
  
  /**
ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
477
478
479
480
481
482
483
484
485
486
487
488
489
490
   * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
491

ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
492
493
494
495
496
497
498
499
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  	mpi_request.Header.PageNumber = 10;
  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
500
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
501
502
503
504
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
505
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
506
507
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
ed79f1280   Kashyap, Desai   [SCSI] mpt2sas: R...
508
509
510
511
512
   out:
  	return r;
  }
  
  /**
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
   * mpt2sas_config_get_bios_pg2 - obtain bios page 2
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
527

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
528
529
530
531
532
533
534
535
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  	mpi_request.Header.PageNumber = 2;
  	mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
536
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
537
538
539
540
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
541
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
542
543
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
544
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
  	return r;
  }
  
  /**
   * mpt2sas_config_get_bios_pg3 - obtain bios page 3
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2BiosPage3_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
563

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
564
565
566
567
568
569
570
571
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  	mpi_request.Header.PageNumber = 3;
  	mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
572
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
573
574
575
576
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
577
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
578
579
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
580
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
  	return r;
  }
  
  /**
   * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
599

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
600
601
602
603
604
605
606
607
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
608
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
609
610
611
612
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
613
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
614
615
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
616
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
  	return r;
  }
  
  /**
   * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
635

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
636
637
638
639
640
641
642
643
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
644
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
645
646
647
648
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
649
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
650
651
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
652
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
  	return r;
  }
  
  /**
   * mpt2sas_config_set_iounit_pg1 - set iounit page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
667
      Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
668
669
670
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
671

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
672
673
674
675
676
677
678
679
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
680
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
681
682
683
684
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
685
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
686
687
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
688
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
  	return r;
  }
  
  /**
   * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
707

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
708
709
710
711
712
713
714
715
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
  	mpi_request.Header.PageNumber = 8;
  	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
716
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
717
718
719
720
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
721
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
722
723
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
724
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
  	return r;
  }
  
  /**
   * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: device handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
745

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
746
747
748
749
750
751
752
753
754
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  	mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
  	mpi_request.Header.PageNumber = 0;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
755
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
756
757
758
759
760
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
761
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
762
763
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
764
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
  	return r;
  }
  
  /**
   * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: device handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
785

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
786
787
788
789
790
791
792
793
794
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  	mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
  	mpi_request.Header.PageNumber = 1;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
795
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
796
797
798
799
800
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
801
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
802
803
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
804
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  	return r;
  }
  
  /**
   * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
   * @ioc: per adapter object
   * @num_phys: pointer returned with the number of phys
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
821
822
823
  	u16 ioc_status;
  	Mpi2ConfigReply_t mpi_reply;
  	Mpi2SasIOUnitPage0_t config_page;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
824
  	*num_phys = 0;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
825
826
827
828
829
830
831
832
833
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, &mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
834
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
835
836
837
838
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
839
  	r = _config_request(ioc, &mpi_request, &mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
840
841
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
  	    sizeof(Mpi2SasIOUnitPage0_t));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
842
843
844
  	if (!r) {
  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  		    MPI2_IOCSTATUS_MASK;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
845
  		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
846
  			*num_phys = config_page.NumPhys;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
847
  	}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
848
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  	return r;
  }
  
  /**
   * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @sz: size of buffer passed in config_page
   * Context: sleep.
   *
   * Calling function should call config_get_number_hba_phys prior to
   * this function, so enough memory is allocated for config_page.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
871

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
872
873
874
875
876
877
878
879
880
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
881
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
882
883
884
885
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
886
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
887
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
888
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
889
890
891
892
  	return r;
  }
  
  /**
50d5c6063   Kashyap, Desai   [SCSI] mpt2sas: A...
893
   * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @sz: size of buffer passed in config_page
   * Context: sleep.
   *
   * Calling function should call config_get_number_hba_phys prior to
   * this function, so enough memory is allocated for config_page.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
911

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
912
913
914
915
916
917
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  	mpi_request.Header.PageNumber = 1;
50d5c6063   Kashyap, Desai   [SCSI] mpt2sas: A...
918
  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
919
920
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
921
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
922
923
924
925
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
926
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
927
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
928
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
929
930
931
932
  	return r;
  }
  
  /**
50d5c6063   Kashyap, Desai   [SCSI] mpt2sas: A...
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
   * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @sz: size of buffer passed in config_page
   * Context: sleep.
   *
   * Calling function should call config_get_number_hba_phys prior to
   * this function, so enough memory is allocated for config_page.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
  
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  	if (r)
  		goto out;
  
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  	_config_request(ioc, &mpi_request, mpi_reply,
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  	r = _config_request(ioc, &mpi_request, mpi_reply,
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
   out:
  	return r;
  }
  
  /**
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
   * mpt2sas_config_get_expander_pg0 - obtain expander page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: expander handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
992

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
993
994
995
996
997
998
999
1000
1001
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1002
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1003
1004
1005
1006
1007
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1008
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1009
1010
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1011
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
  	return r;
  }
  
  /**
   * mpt2sas_config_get_expander_pg1 - obtain expander page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @phy_number: phy number
   * @handle: expander handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
      u16 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1033

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1034
1035
1036
1037
1038
1039
1040
1041
1042
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1043
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1044
1045
1046
1047
1048
1049
1050
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress =
  	    cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
  	    (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1051
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1052
1053
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1054
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
  	return r;
  }
  
  /**
   * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: expander handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1075

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1076
1077
1078
1079
1080
1081
1082
1083
1084
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1085
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1086
1087
1088
1089
1090
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1091
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1092
1093
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1094
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
  	return r;
  }
  
  /**
   * mpt2sas_config_get_phy_pg0 - obtain phy page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @phy_number: phy number
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1114

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1115
1116
1117
1118
1119
1120
1121
1122
1123
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1124
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1125
1126
1127
1128
1129
1130
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress =
  	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1131
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1132
1133
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1134
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
  	return r;
  }
  
  /**
   * mpt2sas_config_get_phy_pg1 - obtain phy page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @phy_number: phy number
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1154

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1155
1156
1157
1158
1159
1160
1161
1162
1163
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1164
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1165
1166
1167
1168
1169
1170
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress =
  	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1171
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1172
1173
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1174
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  	return r;
  }
  
  /**
   * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: volume handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
      u32 handle)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1196

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1197
1198
1199
1200
1201
1202
1203
1204
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  	mpi_request.Header.PageNumber = 1;
  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1205
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1206
1207
1208
1209
1210
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1211
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1212
1213
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1214
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
  	return r;
  }
  
  /**
   * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
   * @ioc: per adapter object
   * @handle: volume handle
   * @num_pds: returns pds count
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
      u8 *num_pds)
  {
  	Mpi2ConfigRequest_t mpi_request;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1232
  	Mpi2RaidVolPage0_t config_page;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1233
1234
  	Mpi2ConfigReply_t mpi_reply;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1235
  	u16 ioc_status;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1236
1237
1238
1239
1240
1241
1242
1243
1244
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	*num_pds = 0;
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, &mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1245
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1246
1247
1248
1249
1250
1251
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress =
  	    cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1252
  	r = _config_request(ioc, &mpi_request, &mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1253
1254
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
  	    sizeof(Mpi2RaidVolPage0_t));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1255
1256
1257
  	if (!r) {
  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  		    MPI2_IOCSTATUS_MASK;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1258
1259
  		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
  			*num_pds = config_page.NumPhysDisks;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1260
  	}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1261
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
  	return r;
  }
  
  /**
   * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_HANDLE or HANDLE
   * @handle: volume handle
   * @sz: size of buffer passed in config_page
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
      Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
      u32 handle, u16 sz)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1284

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1285
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1286
1287
1288
1289
1290
1291
1292
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1293
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1294
1295
1296
1297
1298
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | handle);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1299
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1300
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1301
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
  	return r;
  }
  
  /**
   * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
   * @ioc: per adapter object
   * @mpi_reply: reply mf payload returned from firmware
   * @config_page: contents of the config page
   * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
   * @form_specific: specific to the form
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
      *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
      u32 form_specific)
  {
  	Mpi2ConfigRequest_t mpi_request;
  	int r;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1323

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1324
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1325
1326
1327
1328
1329
1330
1331
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
  	mpi_request.Header.PageNumber = 0;
  	mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1332
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1333
1334
1335
1336
1337
  	if (r)
  		goto out;
  
  	mpi_request.PageAddress = cpu_to_le32(form | form_specific);
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1338
  	r = _config_request(ioc, &mpi_request, mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1339
1340
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  	    sizeof(*config_page));
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1341
   out:
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
  	return r;
  }
  
  /**
   * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
   * @ioc: per adapter object
   * @pd_handle: phys disk handle
   * @volume_handle: volume handle
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
      u16 *volume_handle)
  {
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1358
  	Mpi2RaidConfigurationPage0_t *config_page = NULL;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1359
1360
  	Mpi2ConfigRequest_t mpi_request;
  	Mpi2ConfigReply_t mpi_reply;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1361
  	int r, i, config_page_sz;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1362
  	u16 ioc_status;
35116db95   nagalakshmi.nandigama@lsi.com   [SCSI] mpt2sas: F...
1363
1364
1365
  	int config_num;
  	u16 element_type;
  	u16 phys_disk_dev_handle;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1366

635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
  	*volume_handle = 0;
  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
  	mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
  	mpi_request.Header.PageNumber = 0;
  	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
  	r = _config_request(ioc, &mpi_request, &mpi_reply,
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1377
  	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1378
1379
  	if (r)
  		goto out;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1380
  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1381
1382
  	config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
  	config_page = kmalloc(config_page_sz, GFP_KERNEL);
35116db95   nagalakshmi.nandigama@lsi.com   [SCSI] mpt2sas: F...
1383
1384
  	if (!config_page) {
  		r = -1;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1385
  		goto out;
35116db95   nagalakshmi.nandigama@lsi.com   [SCSI] mpt2sas: F...
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
  	}
  	config_num = 0xff;
  	while (1) {
  		mpi_request.PageAddress = cpu_to_le32(config_num +
  		    MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
  		r = _config_request(ioc, &mpi_request, &mpi_reply,
  		    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  		    config_page_sz);
  		if (r)
  			goto out;
  		r = -1;
  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  		    MPI2_IOCSTATUS_MASK;
  		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1400
  			goto out;
35116db95   nagalakshmi.nandigama@lsi.com   [SCSI] mpt2sas: F...
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
  		for (i = 0; i < config_page->NumElements; i++) {
  			element_type = le16_to_cpu(config_page->
  			    ConfigElement[i].ElementFlags) &
  			    MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
  			if (element_type ==
  			    MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
  			    element_type ==
  			    MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
  				phys_disk_dev_handle =
  				    le16_to_cpu(config_page->ConfigElement[i].
  				    PhysDiskDevHandle);
  				if (phys_disk_dev_handle == pd_handle) {
  					*volume_handle =
  					    le16_to_cpu(config_page->
  					    ConfigElement[i].VolDevHandle);
  					r = 0;
  					goto out;
  				}
  			} else if (element_type ==
  			    MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
  				*volume_handle = 0;
  				r = 0;
  				goto out;
  			}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1425
  		}
35116db95   nagalakshmi.nandigama@lsi.com   [SCSI] mpt2sas: F...
1426
  		config_num = config_page->ConfigNum;
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1427
  	}
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1428
   out:
5b768581e   Kashyap, Desai   [SCSI] mpt2sas: c...
1429
  	kfree(config_page);
635374e7e   Eric Moore   [SCSI] mpt2sas v0...
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
  	return r;
  }
  
  /**
   * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
   * @ioc: per adapter object
   * @volume_handle: volume handle
   * @wwid: volume wwid
   * Context: sleep.
   *
   * Returns 0 for success, non-zero for failure.
   */
  int
  mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
      u64 *wwid)
  {
  	Mpi2ConfigReply_t mpi_reply;
  	Mpi2RaidVolPage1_t raid_vol_pg1;
  
  	*wwid = 0;
  	if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
  	    &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
  	    volume_handle))) {
  		*wwid = le64_to_cpu(raid_vol_pg1.WWID);
  		return 0;
  	} else
  		return -1;
  }