1 /*-
2 * Copyright (c) 2011-2015 LSI Corp.
3 * Copyright (c) 2013-2016 Avago Technologies
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
28 *
29 * $FreeBSD: head/sys/dev/mpr/mpr_config.c 322364 2017-08-10 14:59:17Z ken $
30 */
31
32 /* TODO Move headers to mprvar */
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/lock.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/kthread.h>
40 #include <sys/taskqueue.h>
41 #include <sys/bus.h>
42 #include <sys/endian.h>
43 #include <sys/sysctl.h>
44 #include <sys/eventhandler.h>
45 #include <sys/uio.h>
46 #include <dev/raid/mpr/mpi/mpi2_type.h>
47 #include <dev/raid/mpr/mpi/mpi2.h>
48 #include <dev/raid/mpr/mpi/mpi2_ioc.h>
49 #include <dev/raid/mpr/mpi/mpi2_sas.h>
50 #include <dev/raid/mpr/mpi/mpi2_pci.h>
51 #include <dev/raid/mpr/mpi/mpi2_cnfg.h>
52 #include <dev/raid/mpr/mpi/mpi2_init.h>
53 #include <dev/raid/mpr/mpi/mpi2_tool.h>
54 #include <dev/raid/mpr/mpr_ioctl.h>
55 #include <dev/raid/mpr/mprvar.h>
56
57 /**
58 * mpr_config_get_ioc_pg8 - obtain ioc page 8
59 * @sc: per adapter object
60 * @mpi_reply: reply mf payload returned from firmware
61 * @config_page: contents of the config page
62 * Context: sleep.
63 *
64 * Returns 0 for success, non-zero for failure.
65 */
66 int
mpr_config_get_ioc_pg8(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage8_t * config_page)67 mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
68 Mpi2IOCPage8_t *config_page)
69 {
70 MPI2_CONFIG_REQUEST *request;
71 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
72 struct mpr_command *cm;
73 MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
74 int error = 0;
75 u16 ioc_status;
76
77 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
78
79 if ((cm = mpr_alloc_command(sc)) == NULL) {
80 kprintf("%s: command alloc failed @ line %d\n", __func__,
81 __LINE__);
82 error = EBUSY;
83 goto out;
84 }
85 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
86 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
87 request->Function = MPI2_FUNCTION_CONFIG;
88 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
89 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
90 request->Header.PageNumber = 8;
91 request->Header.PageLength = request->Header.PageVersion = 0;
92 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
93 cm->cm_data = NULL;
94 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
95 if (cm != NULL)
96 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
97 if (error || (reply == NULL)) {
98 /* FIXME */
99 /*
100 * If the request returns an error then we need to do a diag
101 * reset
102 */
103 kprintf("%s: request for header completed with error %d",
104 __func__, error);
105 error = ENXIO;
106 goto out;
107 }
108 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
109 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
110 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
111 /* FIXME */
112 /*
113 * If the request returns an error then we need to do a diag
114 * reset
115 */
116 kprintf("%s: header read with error; iocstatus = 0x%x\n",
117 __func__, ioc_status);
118 error = ENXIO;
119 goto out;
120 }
121 /* We have to do free and alloc for the reply-free and reply-post
122 * counters to match - Need to review the reply FIFO handling.
123 */
124 mpr_free_command(sc, cm);
125
126 if ((cm = mpr_alloc_command(sc)) == NULL) {
127 kprintf("%s: command alloc failed @ line %d\n", __func__,
128 __LINE__);
129 error = EBUSY;
130 goto out;
131 }
132 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
133 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
134 request->Function = MPI2_FUNCTION_CONFIG;
135 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
136 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
137 request->Header.PageNumber = 8;
138 request->Header.PageVersion = mpi_reply->Header.PageVersion;
139 request->Header.PageLength = mpi_reply->Header.PageLength;
140 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
141 cm->cm_sge = &request->PageBufferSGE;
142 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
143 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
144 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
145 page = kmalloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
146 if (!page) {
147 kprintf("%s: page alloc failed\n", __func__);
148 error = ENOMEM;
149 goto out;
150 }
151 cm->cm_data = page;
152
153 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
154 if (cm != NULL)
155 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
156 if (error || (reply == NULL)) {
157 /* FIXME */
158 /*
159 * If the request returns an error then we need to do a diag
160 * reset
161 */
162 kprintf("%s: request for page completed with error %d",
163 __func__, error);
164 error = ENXIO;
165 goto out;
166 }
167 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
168 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
169 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
170 /* FIXME */
171 /*
172 * If the request returns an error then we need to do a diag
173 * reset
174 */
175 kprintf("%s: page read with error; iocstatus = 0x%x\n",
176 __func__, ioc_status);
177 error = ENXIO;
178 goto out;
179 }
180 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
181
182 out:
183 kfree(page, M_MPR);
184 if (cm)
185 mpr_free_command(sc, cm);
186 return (error);
187 }
188
189 /**
190 * mpr_config_get_iounit_pg8 - obtain iounit page 8
191 * @sc: per adapter object
192 * @mpi_reply: reply mf payload returned from firmware
193 * @config_page: contents of the config page
194 * Context: sleep.
195 *
196 * Returns 0 for success, non-zero for failure.
197 */
198 int
mpr_config_get_iounit_pg8(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage8_t * config_page)199 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
200 Mpi2IOUnitPage8_t *config_page)
201 {
202 MPI2_CONFIG_REQUEST *request;
203 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
204 struct mpr_command *cm;
205 MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
206 int error = 0;
207 u16 ioc_status;
208
209 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
210
211 if ((cm = mpr_alloc_command(sc)) == NULL) {
212 kprintf("%s: command alloc failed @ line %d\n", __func__,
213 __LINE__);
214 error = EBUSY;
215 goto out;
216 }
217 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
218 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
219 request->Function = MPI2_FUNCTION_CONFIG;
220 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
221 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
222 request->Header.PageNumber = 8;
223 request->Header.PageLength = request->Header.PageVersion = 0;
224 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
225 cm->cm_data = NULL;
226 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
227 if (cm != NULL)
228 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
229 if (error || (reply == NULL)) {
230 /* FIXME */
231 /*
232 * If the request returns an error then we need to do a diag
233 * reset
234 */
235 kprintf("%s: request for header completed with error %d",
236 __func__, error);
237 error = ENXIO;
238 goto out;
239 }
240 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
241 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
242 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
243 /* FIXME */
244 /*
245 * If the request returns an error then we need to do a diag
246 * reset
247 */
248 kprintf("%s: header read with error; iocstatus = 0x%x\n",
249 __func__, ioc_status);
250 error = ENXIO;
251 goto out;
252 }
253 /* We have to do free and alloc for the reply-free and reply-post
254 * counters to match - Need to review the reply FIFO handling.
255 */
256 mpr_free_command(sc, cm);
257
258 if ((cm = mpr_alloc_command(sc)) == NULL) {
259 kprintf("%s: command alloc failed @ line %d\n", __func__,
260 __LINE__);
261 error = EBUSY;
262 goto out;
263 }
264 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
265 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
266 request->Function = MPI2_FUNCTION_CONFIG;
267 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
268 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
269 request->Header.PageNumber = 8;
270 request->Header.PageVersion = mpi_reply->Header.PageVersion;
271 request->Header.PageLength = mpi_reply->Header.PageLength;
272 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
273 cm->cm_sge = &request->PageBufferSGE;
274 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
275 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
276 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
277 page = kmalloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
278 if (!page) {
279 kprintf("%s: page alloc failed\n", __func__);
280 error = ENOMEM;
281 goto out;
282 }
283 cm->cm_data = page;
284
285 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
286 if (cm != NULL)
287 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
288 if (error || (reply == NULL)) {
289 /* FIXME */
290 /*
291 * If the request returns an error then we need to do a diag
292 * reset
293 */
294 kprintf("%s: request for page completed with error %d",
295 __func__, error);
296 error = ENXIO;
297 goto out;
298 }
299 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
300 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
301 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
302 /* FIXME */
303 /*
304 * If the request returns an error then we need to do a diag
305 * reset
306 */
307 kprintf("%s: page read with error; iocstatus = 0x%x\n",
308 __func__, ioc_status);
309 error = ENXIO;
310 goto out;
311 }
312 bcopy(page, config_page, MIN(cm->cm_length,
313 (sizeof(Mpi2IOUnitPage8_t))));
314
315 out:
316 kfree(page, M_MPR);
317 if (cm)
318 mpr_free_command(sc, cm);
319 return (error);
320 }
321
322 /**
323 * mpr_base_static_config_pages - static start of day config pages.
324 * @sc: per adapter object
325 *
326 * Return nothing.
327 */
328 void
mpr_base_static_config_pages(struct mpr_softc * sc)329 mpr_base_static_config_pages(struct mpr_softc *sc)
330 {
331 Mpi2ConfigReply_t mpi_reply;
332 int retry;
333
334 retry = 0;
335 while (mpr_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) {
336 retry++;
337 if (retry > 5) {
338 /* We need to Handle this situation */
339 /*FIXME*/
340 break;
341 }
342 }
343 retry = 0;
344 while (mpr_config_get_iounit_pg8(sc, &mpi_reply, &sc->iounit_pg8)) {
345 retry++;
346 if (retry > 5) {
347 /* We need to Handle this situation */
348 /*FIXME*/
349 break;
350 }
351 }
352 }
353
354 /**
355 * mpr_config_get_dpm_pg0 - obtain driver persistent mapping page0
356 * @sc: per adapter object
357 * @mpi_reply: reply mf payload returned from firmware
358 * @config_page: contents of the config page
359 * @sz: size of buffer passed in config_page
360 * Context: sleep.
361 *
362 * Returns 0 for success, non-zero for failure.
363 */
364 int
mpr_config_get_dpm_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2DriverMappingPage0_t * config_page,u16 sz)365 mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
366 Mpi2DriverMappingPage0_t *config_page, u16 sz)
367 {
368 MPI2_CONFIG_REQUEST *request;
369 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
370 struct mpr_command *cm;
371 Mpi2DriverMappingPage0_t *page = NULL;
372 int error = 0;
373 u16 ioc_status;
374
375 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
376
377 memset(config_page, 0, sz);
378 if ((cm = mpr_alloc_command(sc)) == NULL) {
379 kprintf("%s: command alloc failed @ line %d\n", __func__,
380 __LINE__);
381 error = EBUSY;
382 goto out;
383 }
384 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
385 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
386 request->Function = MPI2_FUNCTION_CONFIG;
387 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
388 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
389 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
390 request->Header.PageNumber = 0;
391 request->ExtPageLength = request->Header.PageVersion = 0;
392 request->PageAddress = sc->max_dpm_entries <<
393 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
394 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
395 cm->cm_data = NULL;
396 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
397 if (cm != NULL)
398 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
399 if (error || (reply == NULL)) {
400 /* FIXME */
401 /*
402 * If the request returns an error then we need to do a diag
403 * reset
404 */
405 kprintf("%s: request for header completed with error %d",
406 __func__, error);
407 error = ENXIO;
408 goto out;
409 }
410 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
411 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
412 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
413 /* FIXME */
414 /*
415 * If the request returns an error then we need to do a diag
416 * reset
417 */
418 kprintf("%s: header read with error; iocstatus = 0x%x\n",
419 __func__, ioc_status);
420 error = ENXIO;
421 goto out;
422 }
423 /* We have to do free and alloc for the reply-free and reply-post
424 * counters to match - Need to review the reply FIFO handling.
425 */
426 mpr_free_command(sc, cm);
427
428 if ((cm = mpr_alloc_command(sc)) == NULL) {
429 kprintf("%s: command alloc failed @ line %d\n", __func__,
430 __LINE__);
431 error = EBUSY;
432 goto out;
433 }
434 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
435 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
436 request->Function = MPI2_FUNCTION_CONFIG;
437 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
438 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
439 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
440 request->Header.PageNumber = 0;
441 request->Header.PageVersion = mpi_reply->Header.PageVersion;
442 request->PageAddress = sc->max_dpm_entries <<
443 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
444 request->ExtPageLength = mpi_reply->ExtPageLength;
445 cm->cm_length = le16toh(request->ExtPageLength) * 4;
446 cm->cm_sge = &request->PageBufferSGE;
447 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
448 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
449 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
450 page = kmalloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
451 if (!page) {
452 kprintf("%s: page alloc failed\n", __func__);
453 error = ENOMEM;
454 goto out;
455 }
456 cm->cm_data = page;
457 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
458 if (cm != NULL)
459 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
460 if (error || (reply == NULL)) {
461 /* FIXME */
462 /*
463 * If the request returns an error then we need to do a diag
464 * reset
465 */
466 kprintf("%s: request for page completed with error %d",
467 __func__, error);
468 error = ENXIO;
469 goto out;
470 }
471 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
472 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
473 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
474 /* FIXME */
475 /*
476 * If the request returns an error then we need to do a diag
477 * reset
478 */
479 kprintf("%s: page read with error; iocstatus = 0x%x\n",
480 __func__, ioc_status);
481 error = ENXIO;
482 goto out;
483 }
484 bcopy(page, config_page, MIN(cm->cm_length, sz));
485 out:
486 kfree(page, M_MPR);
487 if (cm)
488 mpr_free_command(sc, cm);
489 return (error);
490 }
491
492 /**
493 * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
494 * @sc: per adapter object
495 * @mpi_reply: reply mf payload returned from firmware
496 * @config_page: contents of the config page
497 * @entry_idx: entry index in DPM Page0 to be modified
498 * Context: sleep.
499 *
500 * Returns 0 for success, non-zero for failure.
501 */
502
mpr_config_set_dpm_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2DriverMappingPage0_t * config_page,u16 entry_idx)503 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
504 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
505 {
506 MPI2_CONFIG_REQUEST *request;
507 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
508 struct mpr_command *cm;
509 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
510 int error = 0;
511 u16 ioc_status;
512
513 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
514
515 if ((cm = mpr_alloc_command(sc)) == NULL) {
516 kprintf("%s: command alloc failed @ line %d\n", __func__,
517 __LINE__);
518 error = EBUSY;
519 goto out;
520 }
521 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
522 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
523 request->Function = MPI2_FUNCTION_CONFIG;
524 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
525 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
526 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
527 request->Header.PageNumber = 0;
528 request->ExtPageLength = request->Header.PageVersion = 0;
529 /* We can remove below two lines ????*/
530 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
531 request->PageAddress |= htole16(entry_idx);
532 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
533 cm->cm_data = NULL;
534 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
535 if (cm != NULL)
536 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
537 if (error || (reply == NULL)) {
538 /* FIXME */
539 /*
540 * If the request returns an error then we need to do a diag
541 * reset
542 */
543 kprintf("%s: request for header completed with error %d",
544 __func__, error);
545 error = ENXIO;
546 goto out;
547 }
548 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
549 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
550 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
551 /* FIXME */
552 /*
553 * If the request returns an error then we need to do a diag
554 * reset
555 */
556 kprintf("%s: header read with error; iocstatus = 0x%x\n",
557 __func__, ioc_status);
558 error = ENXIO;
559 goto out;
560 }
561 /* We have to do free and alloc for the reply-free and reply-post
562 * counters to match - Need to review the reply FIFO handling.
563 */
564 mpr_free_command(sc, cm);
565
566 if ((cm = mpr_alloc_command(sc)) == NULL) {
567 kprintf("%s: command alloc failed @ line %d\n", __func__,
568 __LINE__);
569 error = EBUSY;
570 goto out;
571 }
572 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
573 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
574 request->Function = MPI2_FUNCTION_CONFIG;
575 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
576 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
577 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
578 request->Header.PageNumber = 0;
579 request->Header.PageVersion = mpi_reply->Header.PageVersion;
580 request->ExtPageLength = mpi_reply->ExtPageLength;
581 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
582 request->PageAddress |= htole16(entry_idx);
583 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
584 cm->cm_sge = &request->PageBufferSGE;
585 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
586 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
587 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
588 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
589 if (!page) {
590 kprintf("%s: page alloc failed\n", __func__);
591 error = ENOMEM;
592 goto out;
593 }
594 bcopy(config_page, page, MIN(cm->cm_length,
595 (sizeof(Mpi2DriverMappingPage0_t))));
596 cm->cm_data = page;
597 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
598 if (cm != NULL)
599 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
600 if (error || (reply == NULL)) {
601 /* FIXME */
602 /*
603 * If the request returns an error then we need to do a diag
604 * reset
605 */
606 kprintf("%s: request to write page completed with error %d",
607 __func__, error);
608 error = ENXIO;
609 goto out;
610 }
611 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
612 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
613 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
614 /* FIXME */
615 /*
616 * If the request returns an error then we need to do a diag
617 * reset
618 */
619 kprintf("%s: page written with error; iocstatus = 0x%x\n",
620 __func__, ioc_status);
621 error = ENXIO;
622 goto out;
623 }
624 out:
625 kfree(page, M_MPR);
626 if (cm)
627 mpr_free_command(sc, cm);
628 return (error);
629 }
630
631 /**
632 * mpr_config_get_sas_device_pg0 - obtain sas device page 0
633 * @sc: per adapter object
634 * @mpi_reply: reply mf payload returned from firmware
635 * @config_page: contents of the config page
636 * @form: GET_NEXT_HANDLE or HANDLE
637 * @handle: device handle
638 * Context: sleep.
639 *
640 * Returns 0 for success, non-zero for failure.
641 */
642 int
mpr_config_get_sas_device_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasDevicePage0_t * config_page,u32 form,u16 handle)643 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
644 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
645 {
646 MPI2_CONFIG_REQUEST *request;
647 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
648 struct mpr_command *cm;
649 Mpi2SasDevicePage0_t *page = NULL;
650 int error = 0;
651 u16 ioc_status;
652
653 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
654
655 if ((cm = mpr_alloc_command(sc)) == NULL) {
656 kprintf("%s: command alloc failed @ line %d\n", __func__,
657 __LINE__);
658 error = EBUSY;
659 goto out;
660 }
661 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
662 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
663 request->Function = MPI2_FUNCTION_CONFIG;
664 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
665 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
666 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
667 request->Header.PageNumber = 0;
668 request->ExtPageLength = request->Header.PageVersion = 0;
669 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
670 cm->cm_data = NULL;
671 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
672 if (cm != NULL)
673 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
674 if (error || (reply == NULL)) {
675 /* FIXME */
676 /*
677 * If the request returns an error then we need to do a diag
678 * reset
679 */
680 kprintf("%s: request for header completed with error %d",
681 __func__, error);
682 error = ENXIO;
683 goto out;
684 }
685 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
686 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
687 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
688 /* FIXME */
689 /*
690 * If the request returns an error then we need to do a diag
691 * reset
692 */
693 kprintf("%s: header read with error; iocstatus = 0x%x\n",
694 __func__, ioc_status);
695 error = ENXIO;
696 goto out;
697 }
698 /* We have to do free and alloc for the reply-free and reply-post
699 * counters to match - Need to review the reply FIFO handling.
700 */
701 mpr_free_command(sc, cm);
702
703 if ((cm = mpr_alloc_command(sc)) == NULL) {
704 kprintf("%s: command alloc failed @ line %d\n", __func__,
705 __LINE__);
706 error = EBUSY;
707 goto out;
708 }
709 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
710 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
711 request->Function = MPI2_FUNCTION_CONFIG;
712 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
713 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
714 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
715 request->Header.PageNumber = 0;
716 request->Header.PageVersion = mpi_reply->Header.PageVersion;
717 request->ExtPageLength = mpi_reply->ExtPageLength;
718 request->PageAddress = htole32(form | handle);
719 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
720 cm->cm_sge = &request->PageBufferSGE;
721 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
722 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
723 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
724 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
725 if (!page) {
726 kprintf("%s: page alloc failed\n", __func__);
727 error = ENOMEM;
728 goto out;
729 }
730 cm->cm_data = page;
731
732 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
733 if (cm != NULL)
734 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
735 if (error || (reply == NULL)) {
736 /* FIXME */
737 /*
738 * If the request returns an error then we need to do a diag
739 * reset
740 */
741 kprintf("%s: request for page completed with error %d",
742 __func__, error);
743 error = ENXIO;
744 goto out;
745 }
746 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
747 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
748 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
749 /* FIXME */
750 /*
751 * If the request returns an error then we need to do a diag
752 * reset
753 */
754 kprintf("%s: page read with error; iocstatus = 0x%x\n",
755 __func__, ioc_status);
756 error = ENXIO;
757 goto out;
758 }
759 bcopy(page, config_page, MIN(cm->cm_length,
760 sizeof(Mpi2SasDevicePage0_t)));
761 out:
762 kfree(page, M_MPR);
763 if (cm)
764 mpr_free_command(sc, cm);
765 return (error);
766 }
767
768 /**
769 * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
770 * @sc: per adapter object
771 * @mpi_reply: reply mf payload returned from firmware
772 * @config_page: contents of the config page
773 * @form: GET_NEXT_HANDLE or HANDLE
774 * @handle: device handle
775 * Context: sleep.
776 *
777 * Returns 0 for success, non-zero for failure.
778 */
779 int
mpr_config_get_pcie_device_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage0_t * config_page,u32 form,u16 handle)780 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
781 *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
782 {
783 MPI2_CONFIG_REQUEST *request;
784 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
785 struct mpr_command *cm;
786 Mpi26PCIeDevicePage0_t *page = NULL;
787 int error = 0;
788 u16 ioc_status;
789
790 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
791
792 if ((cm = mpr_alloc_command(sc)) == NULL) {
793 kprintf("%s: command alloc failed @ line %d\n", __func__,
794 __LINE__);
795 error = EBUSY;
796 goto out;
797 }
798 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
799 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
800 request->Function = MPI2_FUNCTION_CONFIG;
801 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
802 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
803 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
804 request->Header.PageNumber = 0;
805 request->ExtPageLength = request->Header.PageVersion = 0;
806 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
807 cm->cm_data = NULL;
808 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
809 if (cm != NULL)
810 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
811 if (error || (reply == NULL)) {
812 /* FIXME */
813 /*
814 * If the request returns an error then we need to do a diag
815 * reset
816 */
817 kprintf("%s: request for header completed with error %d",
818 __func__, error);
819 error = ENXIO;
820 goto out;
821 }
822 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
823 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
824 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
825 /* FIXME */
826 /*
827 * If the request returns an error then we need to do a diag
828 * reset
829 */
830 kprintf("%s: header read with error; iocstatus = 0x%x\n",
831 __func__, ioc_status);
832 error = ENXIO;
833 goto out;
834 }
835 /* We have to do free and alloc for the reply-free and reply-post
836 * counters to match - Need to review the reply FIFO handling.
837 */
838 mpr_free_command(sc, cm);
839
840 if ((cm = mpr_alloc_command(sc)) == NULL) {
841 kprintf("%s: command alloc failed @ line %d\n", __func__,
842 __LINE__);
843 error = EBUSY;
844 goto out;
845 }
846 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
847 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
848 request->Function = MPI2_FUNCTION_CONFIG;
849 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
850 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
851 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
852 request->Header.PageNumber = 0;
853 request->Header.PageVersion = mpi_reply->Header.PageVersion;
854 request->ExtPageLength = mpi_reply->ExtPageLength;
855 request->PageAddress = htole32(form | handle);
856 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
857 cm->cm_sge = &request->PageBufferSGE;
858 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
859 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
860 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
861 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
862 if (!page) {
863 kprintf("%s: page alloc failed\n", __func__);
864 error = ENOMEM;
865 goto out;
866 }
867 cm->cm_data = page;
868
869 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
870 if (cm != NULL)
871 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
872 if (error || (reply == NULL)) {
873 /* FIXME */
874 /*
875 * If the request returns an error then we need to do a diag
876 * reset
877 */
878 kprintf("%s: request for page completed with error %d",
879 __func__, error);
880 error = ENXIO;
881 goto out;
882 }
883 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
884 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
885 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
886 /* FIXME */
887 /*
888 * If the request returns an error then we need to do a diag
889 * reset
890 */
891 kprintf("%s: page read with error; iocstatus = 0x%x\n",
892 __func__, ioc_status);
893 error = ENXIO;
894 goto out;
895 }
896 bcopy(page, config_page, MIN(cm->cm_length,
897 sizeof(Mpi26PCIeDevicePage0_t)));
898 out:
899 kfree(page, M_MPR);
900 if (cm)
901 mpr_free_command(sc, cm);
902 return (error);
903 }
904
905 /**
906 * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
907 * @sc: per adapter object
908 * @mpi_reply: reply mf payload returned from firmware
909 * @config_page: contents of the config page
910 * @form: GET_NEXT_HANDLE or HANDLE
911 * @handle: device handle
912 * Context: sleep.
913 *
914 * Returns 0 for success, non-zero for failure.
915 */
916 int
mpr_config_get_pcie_device_pg2(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage2_t * config_page,u32 form,u16 handle)917 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
918 *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
919 {
920 MPI2_CONFIG_REQUEST *request;
921 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
922 struct mpr_command *cm;
923 Mpi26PCIeDevicePage2_t *page = NULL;
924 int error = 0;
925 u16 ioc_status;
926
927 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
928
929 if ((cm = mpr_alloc_command(sc)) == NULL) {
930 kprintf("%s: command alloc failed @ line %d\n", __func__,
931 __LINE__);
932 error = EBUSY;
933 goto out;
934 }
935 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
936 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
937 request->Function = MPI2_FUNCTION_CONFIG;
938 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
939 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
940 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
941 request->Header.PageNumber = 2;
942 request->ExtPageLength = request->Header.PageVersion = 0;
943 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
944 cm->cm_data = NULL;
945 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
946 if (cm != NULL)
947 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
948 if (error || (reply == NULL)) {
949 /* FIXME */
950 /*
951 * If the request returns an error then we need to do a diag
952 * reset
953 */
954 kprintf("%s: request for header completed with error %d",
955 __func__, error);
956 error = ENXIO;
957 goto out;
958 }
959 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
960 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
961 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
962 /* FIXME */
963 /*
964 * If the request returns an error then we need to do a diag
965 * reset
966 */
967 kprintf("%s: header read with error; iocstatus = 0x%x\n",
968 __func__, ioc_status);
969 error = ENXIO;
970 goto out;
971 }
972 /* We have to do free and alloc for the reply-free and reply-post
973 * counters to match - Need to review the reply FIFO handling.
974 */
975 mpr_free_command(sc, cm);
976
977 if ((cm = mpr_alloc_command(sc)) == NULL) {
978 kprintf("%s: command alloc failed @ line %d\n", __func__,
979 __LINE__);
980 error = EBUSY;
981 goto out;
982 }
983 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
984 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
985 request->Function = MPI2_FUNCTION_CONFIG;
986 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
987 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
988 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
989 request->Header.PageNumber = 2;
990 request->Header.PageVersion = mpi_reply->Header.PageVersion;
991 request->ExtPageLength = mpi_reply->ExtPageLength;
992 request->PageAddress = htole32(form | handle);
993 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
994 cm->cm_sge = &request->PageBufferSGE;
995 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
996 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
997 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
998 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
999 if (!page) {
1000 kprintf("%s: page alloc failed\n", __func__);
1001 error = ENOMEM;
1002 goto out;
1003 }
1004 cm->cm_data = page;
1005
1006 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1007 if (cm != NULL)
1008 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1009 if (error || (reply == NULL)) {
1010 /* FIXME */
1011 /*
1012 * If the request returns an error then we need to do a diag
1013 * reset
1014 */
1015 kprintf("%s: request for page completed with error %d",
1016 __func__, error);
1017 error = ENXIO;
1018 goto out;
1019 }
1020 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1021 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1022 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1023 /* FIXME */
1024 /*
1025 * If the request returns an error then we need to do a diag
1026 * reset
1027 */
1028 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1029 __func__, ioc_status);
1030 error = ENXIO;
1031 goto out;
1032 }
1033 bcopy(page, config_page, MIN(cm->cm_length,
1034 sizeof(Mpi26PCIeDevicePage2_t)));
1035 out:
1036 kfree(page, M_MPR);
1037 if (cm)
1038 mpr_free_command(sc, cm);
1039 return (error);
1040 }
1041
1042 /**
1043 * mpr_config_get_bios_pg3 - obtain BIOS page 3
1044 * @sc: per adapter object
1045 * @mpi_reply: reply mf payload returned from firmware
1046 * @config_page: contents of the config page
1047 * Context: sleep.
1048 *
1049 * Returns 0 for success, non-zero for failure.
1050 */
1051 int
mpr_config_get_bios_pg3(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage3_t * config_page)1052 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1053 Mpi2BiosPage3_t *config_page)
1054 {
1055 MPI2_CONFIG_REQUEST *request;
1056 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
1057 struct mpr_command *cm;
1058 Mpi2BiosPage3_t *page = NULL;
1059 int error = 0;
1060 u16 ioc_status;
1061
1062 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1063
1064 if ((cm = mpr_alloc_command(sc)) == NULL) {
1065 kprintf("%s: command alloc failed @ line %d\n", __func__,
1066 __LINE__);
1067 error = EBUSY;
1068 goto out;
1069 }
1070 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1071 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1072 request->Function = MPI2_FUNCTION_CONFIG;
1073 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1074 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1075 request->Header.PageNumber = 3;
1076 request->Header.PageLength = request->Header.PageVersion = 0;
1077 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1078 cm->cm_data = NULL;
1079 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1080 if (cm != NULL)
1081 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1082 if (error || (reply == NULL)) {
1083 /* FIXME */
1084 /*
1085 * If the request returns an error then we need to do a diag
1086 * reset
1087 */
1088 kprintf("%s: request for header completed with error %d",
1089 __func__, error);
1090 error = ENXIO;
1091 goto out;
1092 }
1093 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1094 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1095 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1096 /* FIXME */
1097 /*
1098 * If the request returns an error then we need to do a diag
1099 * reset
1100 */
1101 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1102 __func__, ioc_status);
1103 error = ENXIO;
1104 goto out;
1105 }
1106 /* We have to do free and alloc for the reply-free and reply-post
1107 * counters to match - Need to review the reply FIFO handling.
1108 */
1109 mpr_free_command(sc, cm);
1110
1111 if ((cm = mpr_alloc_command(sc)) == NULL) {
1112 kprintf("%s: command alloc failed @ line %d\n", __func__,
1113 __LINE__);
1114 error = EBUSY;
1115 goto out;
1116 }
1117 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1118 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1119 request->Function = MPI2_FUNCTION_CONFIG;
1120 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1121 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1122 request->Header.PageNumber = 3;
1123 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1124 request->Header.PageLength = mpi_reply->Header.PageLength;
1125 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1126 cm->cm_sge = &request->PageBufferSGE;
1127 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1128 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1129 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1130 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1131 if (!page) {
1132 kprintf("%s: page alloc failed\n", __func__);
1133 error = ENOMEM;
1134 goto out;
1135 }
1136 cm->cm_data = page;
1137
1138 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1139 if (cm != NULL)
1140 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1141 if (error || (reply == NULL)) {
1142 /* FIXME */
1143 /*
1144 * If the request returns an error then we need to do a diag
1145 * reset
1146 */
1147 kprintf("%s: request for page completed with error %d",
1148 __func__, error);
1149 error = ENXIO;
1150 goto out;
1151 }
1152 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1153 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1154 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1155 /* FIXME */
1156 /*
1157 * If the request returns an error then we need to do a diag
1158 * reset
1159 */
1160 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1161 __func__, ioc_status);
1162 error = ENXIO;
1163 goto out;
1164 }
1165 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
1166 out:
1167 kfree(page, M_MPR);
1168 if (cm)
1169 mpr_free_command(sc, cm);
1170 return (error);
1171 }
1172
1173 /**
1174 * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
1175 * @sc: per adapter object
1176 * @mpi_reply: reply mf payload returned from firmware
1177 * @config_page: contents of the config page
1178 * @page_address: form and handle value used to get page
1179 * Context: sleep.
1180 *
1181 * Returns 0 for success, non-zero for failure.
1182 */
1183 int
mpr_config_get_raid_volume_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage0_t * config_page,u32 page_address)1184 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
1185 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
1186 {
1187 MPI2_CONFIG_REQUEST *request;
1188 MPI2_CONFIG_REPLY *reply = NULL;
1189 struct mpr_command *cm;
1190 Mpi2RaidVolPage0_t *page = NULL;
1191 int error = 0;
1192 u16 ioc_status;
1193
1194 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1195
1196 if ((cm = mpr_alloc_command(sc)) == NULL) {
1197 kprintf("%s: command alloc failed @ line %d\n", __func__,
1198 __LINE__);
1199 error = EBUSY;
1200 goto out;
1201 }
1202 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1203 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1204 request->Function = MPI2_FUNCTION_CONFIG;
1205 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1206 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1207 request->Header.PageNumber = 0;
1208 request->Header.PageLength = request->Header.PageVersion = 0;
1209 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1210 cm->cm_data = NULL;
1211
1212 /*
1213 * This page must be polled because the IOC isn't ready yet when this
1214 * page is needed.
1215 */
1216 error = mpr_request_polled(sc, &cm);
1217 if (cm != NULL)
1218 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1219 if (error || (reply == NULL)) {
1220 /* FIXME */
1221 /* If the poll returns error then we need to do diag reset */
1222 kprintf("%s: poll for header completed with error %d",
1223 __func__, error);
1224 error = ENXIO;
1225 goto out;
1226 }
1227 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1228 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1229 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1230 /* FIXME */
1231 /* If the poll returns error then we need to do diag reset */
1232 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1233 __func__, ioc_status);
1234 error = ENXIO;
1235 goto out;
1236 }
1237 /* We have to do free and alloc for the reply-free and reply-post
1238 * counters to match - Need to review the reply FIFO handling.
1239 */
1240 mpr_free_command(sc, cm);
1241
1242 if ((cm = mpr_alloc_command(sc)) == NULL) {
1243 kprintf("%s: command alloc failed @ line %d\n", __func__,
1244 __LINE__);
1245 error = EBUSY;
1246 goto out;
1247 }
1248 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1249 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1250 request->Function = MPI2_FUNCTION_CONFIG;
1251 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1252 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1253 request->Header.PageNumber = 0;
1254 request->Header.PageLength = mpi_reply->Header.PageLength;
1255 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1256 request->PageAddress = page_address;
1257 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1258 cm->cm_sge = &request->PageBufferSGE;
1259 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1260 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1261 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1262 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1263 if (!page) {
1264 kprintf("%s: page alloc failed\n", __func__);
1265 error = ENOMEM;
1266 goto out;
1267 }
1268 cm->cm_data = page;
1269
1270 /*
1271 * This page must be polled because the IOC isn't ready yet when this
1272 * page is needed.
1273 */
1274 error = mpr_request_polled(sc, &cm);
1275 if (cm != NULL)
1276 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1277 if (error || (reply == NULL)) {
1278 /* FIXME */
1279 /* If the poll returns error then we need to do diag reset */
1280 kprintf("%s: poll for page completed with error %d",
1281 __func__, error);
1282 error = ENXIO;
1283 goto out;
1284 }
1285 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1286 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1287 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1288 /* FIXME */
1289 /* If the poll returns error then we need to do diag reset */
1290 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1291 __func__, ioc_status);
1292 error = ENXIO;
1293 goto out;
1294 }
1295 bcopy(page, config_page, cm->cm_length);
1296 out:
1297 kfree(page, M_MPR);
1298 if (cm)
1299 mpr_free_command(sc, cm);
1300 return (error);
1301 }
1302
1303 /**
1304 * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
1305 * @sc: per adapter object
1306 * @mpi_reply: reply mf payload returned from firmware
1307 * @config_page: contents of the config page
1308 * @form: GET_NEXT_HANDLE or HANDLE
1309 * @handle: volume handle
1310 * Context: sleep.
1311 *
1312 * Returns 0 for success, non-zero for failure.
1313 */
1314 int
mpr_config_get_raid_volume_pg1(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage1_t * config_page,u32 form,u16 handle)1315 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
1316 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
1317 {
1318 MPI2_CONFIG_REQUEST *request;
1319 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
1320 struct mpr_command *cm;
1321 Mpi2RaidVolPage1_t *page = NULL;
1322 int error = 0;
1323 u16 ioc_status;
1324
1325 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1326
1327 if ((cm = mpr_alloc_command(sc)) == NULL) {
1328 kprintf("%s: command alloc failed @ line %d\n", __func__,
1329 __LINE__);
1330 error = EBUSY;
1331 goto out;
1332 }
1333 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1334 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1335 request->Function = MPI2_FUNCTION_CONFIG;
1336 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1337 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1338 request->Header.PageNumber = 1;
1339 request->Header.PageLength = request->Header.PageVersion = 0;
1340 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1341 cm->cm_data = NULL;
1342 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1343 if (cm != NULL)
1344 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1345 if (error || (reply == NULL)) {
1346 /* FIXME */
1347 /*
1348 * If the request returns an error then we need to do a diag
1349 * reset
1350 */
1351 kprintf("%s: request for header completed with error %d",
1352 __func__, error);
1353 error = ENXIO;
1354 goto out;
1355 }
1356 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1357 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1358 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1359 /* FIXME */
1360 /*
1361 * If the request returns an error then we need to do a diag
1362 * reset
1363 */
1364 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1365 __func__, ioc_status);
1366 error = ENXIO;
1367 goto out;
1368 }
1369 /* We have to do free and alloc for the reply-free and reply-post
1370 * counters to match - Need to review the reply FIFO handling.
1371 */
1372 mpr_free_command(sc, cm);
1373
1374 if ((cm = mpr_alloc_command(sc)) == NULL) {
1375 kprintf("%s: command alloc failed @ line %d\n", __func__,
1376 __LINE__);
1377 error = EBUSY;
1378 goto out;
1379 }
1380 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1381 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1382 request->Function = MPI2_FUNCTION_CONFIG;
1383 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1384 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1385 request->Header.PageNumber = 1;
1386 request->Header.PageLength = mpi_reply->Header.PageLength;
1387 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1388 request->PageAddress = htole32(form | handle);
1389 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1390 cm->cm_sge = &request->PageBufferSGE;
1391 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1392 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1393 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1394 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1395 if (!page) {
1396 kprintf("%s: page alloc failed\n", __func__);
1397 error = ENOMEM;
1398 goto out;
1399 }
1400 cm->cm_data = page;
1401
1402 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1403 if (cm != NULL)
1404 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1405 if (error || (reply == NULL)) {
1406 /* FIXME */
1407 /*
1408 * If the request returns an error then we need to do a diag
1409 * reset
1410 */
1411 kprintf("%s: request for page completed with error %d",
1412 __func__, error);
1413 error = ENXIO;
1414 goto out;
1415 }
1416 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1417 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1418 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1419 /* FIXME */
1420 /*
1421 * If the request returns an error then we need to do a diag
1422 * reset
1423 */
1424 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1425 __func__, ioc_status);
1426 error = ENXIO;
1427 goto out;
1428 }
1429 bcopy(page, config_page, MIN(cm->cm_length,
1430 sizeof(Mpi2RaidVolPage1_t)));
1431 out:
1432 kfree(page, M_MPR);
1433 if (cm)
1434 mpr_free_command(sc, cm);
1435 return (error);
1436 }
1437
1438 /**
1439 * mpr_config_get_volume_wwid - returns wwid given the volume handle
1440 * @sc: per adapter object
1441 * @volume_handle: volume handle
1442 * @wwid: volume wwid
1443 * Context: sleep.
1444 *
1445 * Returns 0 for success, non-zero for failure.
1446 */
1447 int
mpr_config_get_volume_wwid(struct mpr_softc * sc,u16 volume_handle,u64 * wwid)1448 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
1449 {
1450 Mpi2ConfigReply_t mpi_reply;
1451 Mpi2RaidVolPage1_t raid_vol_pg1;
1452
1453 *wwid = 0;
1454 if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
1455 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
1456 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
1457 raid_vol_pg1.WWID.Low);
1458 return 0;
1459 } else
1460 return -1;
1461 }
1462
1463 /**
1464 * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
1465 * @sc: per adapter object
1466 * @mpi_reply: reply mf payload returned from firmware
1467 * @config_page: contents of the config page
1468 * @page_address: form and handle value used to get page
1469 * Context: sleep.
1470 *
1471 * Returns 0 for success, non-zero for failure.
1472 */
1473 int
mpr_config_get_raid_pd_pg0(struct mpr_softc * sc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidPhysDiskPage0_t * config_page,u32 page_address)1474 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1475 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
1476 {
1477 MPI2_CONFIG_REQUEST *request;
1478 MPI2_CONFIG_REPLY *reply = NULL;
1479 struct mpr_command *cm;
1480 Mpi2RaidPhysDiskPage0_t *page = NULL;
1481 int error = 0;
1482 u16 ioc_status;
1483
1484 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1485
1486 if ((cm = mpr_alloc_command(sc)) == NULL) {
1487 kprintf("%s: command alloc failed @ line %d\n", __func__,
1488 __LINE__);
1489 error = EBUSY;
1490 goto out;
1491 }
1492 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1493 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1494 request->Function = MPI2_FUNCTION_CONFIG;
1495 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1496 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1497 request->Header.PageNumber = 0;
1498 request->Header.PageLength = request->Header.PageVersion = 0;
1499 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1500 cm->cm_data = NULL;
1501
1502 /*
1503 * This page must be polled because the IOC isn't ready yet when this
1504 * page is needed.
1505 */
1506 error = mpr_request_polled(sc, &cm);
1507 if (cm != NULL)
1508 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1509 if (error || (reply == NULL)) {
1510 /* FIXME */
1511 /* If the poll returns error then we need to do diag reset */
1512 kprintf("%s: poll for header completed with error %d",
1513 __func__, error);
1514 error = ENXIO;
1515 goto out;
1516 }
1517 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1518 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1519 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1520 /* FIXME */
1521 /* If the poll returns error then we need to do diag reset */
1522 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1523 __func__, ioc_status);
1524 error = ENXIO;
1525 goto out;
1526 }
1527 /* We have to do free and alloc for the reply-free and reply-post
1528 * counters to match - Need to review the reply FIFO handling.
1529 */
1530 mpr_free_command(sc, cm);
1531
1532 if ((cm = mpr_alloc_command(sc)) == NULL) {
1533 kprintf("%s: command alloc failed @ line %d\n", __func__,
1534 __LINE__);
1535 error = EBUSY;
1536 goto out;
1537 }
1538 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1539 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1540 request->Function = MPI2_FUNCTION_CONFIG;
1541 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1542 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1543 request->Header.PageNumber = 0;
1544 request->Header.PageLength = mpi_reply->Header.PageLength;
1545 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1546 request->PageAddress = page_address;
1547 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1548 cm->cm_sge = &request->PageBufferSGE;
1549 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1550 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1551 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1552 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1553 if (!page) {
1554 kprintf("%s: page alloc failed\n", __func__);
1555 error = ENOMEM;
1556 goto out;
1557 }
1558 cm->cm_data = page;
1559
1560 /*
1561 * This page must be polled because the IOC isn't ready yet when this
1562 * page is needed.
1563 */
1564 error = mpr_request_polled(sc, &cm);
1565 if (cm != NULL)
1566 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1567 if (error || (reply == NULL)) {
1568 /* FIXME */
1569 /* If the poll returns error then we need to do diag reset */
1570 kprintf("%s: poll for page completed with error %d",
1571 __func__, error);
1572 error = ENXIO;
1573 goto out;
1574 }
1575 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1576 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1577 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1578 /* FIXME */
1579 /* If the poll returns error then we need to do diag reset */
1580 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1581 __func__, ioc_status);
1582 error = ENXIO;
1583 goto out;
1584 }
1585 bcopy(page, config_page, MIN(cm->cm_length,
1586 sizeof(Mpi2RaidPhysDiskPage0_t)));
1587 out:
1588 kfree(page, M_MPR);
1589 if (cm)
1590 mpr_free_command(sc, cm);
1591 return (error);
1592 }
1593