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