18
#include "qemu/osdep.h"
19
#include "hw/pci/pci.h"
20
#include "hw/scsi/scsi.h"
31
#define repl4(x) x x x x
32
#define repl5(x) x x x x x
33
#define repl6(x) x x x x x x
34
#define repl7(x) x x x x x x x
35
#define repl8(x) x x x x x x x x
37
#define repl(n, x) glue(repl, n)(x)
39
typedef union PackValue {
44
static size_t vfill(uint8_t *data, size_t size, const char *fmt, va_list ap)
53
memset(&val, 0, sizeof(val));
61
val.ll = va_arg(ap, int);
64
val.ll = va_arg(ap, int64_t);
67
val.str = va_arg(ap, void *);
73
stb_p(data + ofs, val.ll);
79
stw_le_p(data + ofs, val.ll);
85
stl_le_p(data + ofs, val.ll);
91
stq_le_p(data + ofs, val.ll);
100
strncpy((void *)data + ofs, val.str, cnt);
102
memset((void *)data + ofs, 0, cnt);
114
static size_t vpack(uint8_t **p_data, const char *fmt, va_list ap1)
117
uint8_t *data = NULL;
123
size = vfill(NULL, 0, fmt, ap2);
124
*p_data = data = g_malloc(size);
127
return vfill(data, size, fmt, ap1);
130
static size_t fill(uint8_t *data, size_t size, const char *fmt, ...)
136
ret = vfill(data, size, fmt, ap);
146
#define MPTSAS_CONFIG_PACK(number, type, version, fmt, ...) \
147
mptsas_config_pack(data, "b*bbb" fmt, version, number, type, \
150
static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...)
156
ret = vpack(data, fmt, ap);
160
assert(ret / 4 < 256 && (ret % 4) == 0);
161
stb_p(*data + 1, ret / 4);
166
#define MPTSAS_CONFIG_PACK_EXT(number, type, version, fmt, ...) \
167
mptsas_config_pack_ext(data, "b*bbb*wb*b" fmt, version, number, \
168
MPI_CONFIG_PAGETYPE_EXTENDED, type, ## __VA_ARGS__)
170
static size_t mptsas_config_pack_ext(uint8_t **data, const char *fmt, ...)
176
ret = vpack(data, fmt, ap);
180
assert(ret < 65536 && (ret % 4) == 0);
181
stw_le_p(*data + 4, ret / 4);
189
size_t mptsas_config_manufacturing_0(MPTSASState *s, uint8_t **data, int address)
191
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
201
size_t mptsas_config_manufacturing_1(MPTSASState *s, uint8_t **data, int address)
204
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
209
size_t mptsas_config_manufacturing_2(MPTSASState *s, uint8_t **data, int address)
211
PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s);
212
return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
214
pcic->device_id, pcic->revision);
218
size_t mptsas_config_manufacturing_3(MPTSASState *s, uint8_t **data, int address)
220
PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s);
221
return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
223
pcic->device_id, pcic->revision);
227
size_t mptsas_config_manufacturing_4(MPTSASState *s, uint8_t **data, int address)
230
return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x05,
231
"*l*b*b*b*b*b*b*w*s56*l*l*l*l*l*l"
236
size_t mptsas_config_manufacturing_5(MPTSASState *s, uint8_t **data, int address)
238
return MPTSAS_CONFIG_PACK(5, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x02,
239
"q*b*b*w*l*l", s->sas_addr);
243
size_t mptsas_config_manufacturing_6(MPTSASState *s, uint8_t **data, int address)
245
return MPTSAS_CONFIG_PACK(6, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
250
size_t mptsas_config_manufacturing_7(MPTSASState *s, uint8_t **data, int address)
252
return MPTSAS_CONFIG_PACK(7, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
253
"*l*l*l*s16*b*b*w", MPTSAS_NUM_PORTS);
257
size_t mptsas_config_manufacturing_8(MPTSASState *s, uint8_t **data, int address)
259
return MPTSAS_CONFIG_PACK(8, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
264
size_t mptsas_config_manufacturing_9(MPTSASState *s, uint8_t **data, int address)
266
return MPTSAS_CONFIG_PACK(9, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
271
size_t mptsas_config_manufacturing_10(MPTSASState *s, uint8_t **data, int address)
273
return MPTSAS_CONFIG_PACK(10, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
280
size_t mptsas_config_io_unit_0(MPTSASState *s, uint8_t **data, int address)
282
PCIDevice *pci = PCI_DEVICE(s);
283
uint64_t unique_value = 0x53504D554D4551LL;
285
unique_value |= (uint64_t)pci->devfn << 56;
286
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x00,
291
size_t mptsas_config_io_unit_1(MPTSASState *s, uint8_t **data, int address)
293
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x02, "l",
298
size_t mptsas_config_io_unit_2(MPTSASState *s, uint8_t **data, int address)
300
PCIDevice *pci = PCI_DEVICE(s);
301
uint8_t devfn = pci->devfn;
302
return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x02,
303
"llbbw*b*b*w*b*b*w*b*b*w*l",
304
0, 0x100, 0 , devfn, 0);
308
size_t mptsas_config_io_unit_3(MPTSASState *s, uint8_t **data, int address)
310
return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x01,
315
size_t mptsas_config_io_unit_4(MPTSASState *s, uint8_t **data, int address)
317
return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_IO_UNIT, 0x00, "*l*l*q");
323
size_t mptsas_config_ioc_0(MPTSASState *s, uint8_t **data, int address)
325
PCIDeviceClass *pcic = PCI_DEVICE_GET_CLASS(s);
327
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IOC, 0x01,
329
pcic->vendor_id, pcic->device_id, pcic->revision,
330
pcic->class_id, pcic->subsystem_vendor_id,
335
size_t mptsas_config_ioc_1(MPTSASState *s, uint8_t **data, int address)
337
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_IOC, 0x03,
342
size_t mptsas_config_ioc_2(MPTSASState *s, uint8_t **data, int address)
344
return MPTSAS_CONFIG_PACK(2, MPI_CONFIG_PAGETYPE_IOC, 0x04,
349
size_t mptsas_config_ioc_3(MPTSASState *s, uint8_t **data, int address)
351
return MPTSAS_CONFIG_PACK(3, MPI_CONFIG_PAGETYPE_IOC, 0x00,
356
size_t mptsas_config_ioc_4(MPTSASState *s, uint8_t **data, int address)
358
return MPTSAS_CONFIG_PACK(4, MPI_CONFIG_PAGETYPE_IOC, 0x00,
363
size_t mptsas_config_ioc_5(MPTSASState *s, uint8_t **data, int address)
365
return MPTSAS_CONFIG_PACK(5, MPI_CONFIG_PAGETYPE_IOC, 0x00,
370
size_t mptsas_config_ioc_6(MPTSASState *s, uint8_t **data, int address)
372
return MPTSAS_CONFIG_PACK(6, MPI_CONFIG_PAGETYPE_IOC, 0x01,
373
"*l*b*b*b*b*b*b*b*b*b*b*w*l*l*l*l*b*b*w"
379
#define MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE 16
381
#define MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION 0x02
382
#define MPI_SAS_IOUNIT0_RATE_1_5 0x08
383
#define MPI_SAS_IOUNIT0_RATE_3_0 0x09
385
#define MPI_SAS_DEVICE_INFO_NO_DEVICE 0x00000000
386
#define MPI_SAS_DEVICE_INFO_END_DEVICE 0x00000001
387
#define MPI_SAS_DEVICE_INFO_SSP_TARGET 0x00000400
389
#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS 0x00
391
#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT 0x0001
392
#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED 0x0002
393
#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT 0x0004
397
static SCSIDevice *mptsas_phy_get_device(MPTSASState *s, int i,
398
int *phy_handle, int *dev_handle)
400
SCSIDevice *d = scsi_device_find(&s->bus, 0, i, 0);
406
*dev_handle = d ? i + 1 + MPTSAS_NUM_PORTS : 0;
412
size_t mptsas_config_sas_io_unit_0(MPTSASState *s, uint8_t **data, int address)
414
size_t size = MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x04,
416
repl(MPTSAS_NUM_PORTS, "*s16"),
420
size_t ofs = size - MPTSAS_NUM_PORTS * MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE;
423
for (i = 0; i < MPTSAS_NUM_PORTS; i++) {
424
int phy_handle, dev_handle;
425
SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
427
fill(*data + ofs, MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE,
430
? MPI_SAS_IOUNIT0_RATE_3_0
431
: MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION),
433
? MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET
434
: MPI_SAS_DEVICE_INFO_NO_DEVICE),
438
ofs += MPTSAS_CONFIG_SAS_IO_UNIT_0_SIZE;
445
#define MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE 12
448
size_t mptsas_config_sas_io_unit_1(MPTSASState *s, uint8_t **data, int address)
450
size_t size = MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x07,
452
repl(MPTSAS_NUM_PORTS, "*s12"),
456
size_t ofs = size - MPTSAS_NUM_PORTS * MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE;
459
for (i = 0; i < MPTSAS_NUM_PORTS; i++) {
460
SCSIDevice *dev = mptsas_phy_get_device(s, i, NULL, NULL);
461
fill(*data + ofs, MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE,
463
(MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5,
465
? MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET
466
: MPI_SAS_DEVICE_INFO_NO_DEVICE),
468
ofs += MPTSAS_CONFIG_SAS_IO_UNIT_1_SIZE;
476
size_t mptsas_config_sas_io_unit_2(MPTSASState *s, uint8_t **data, int address)
478
return MPTSAS_CONFIG_PACK_EXT(2, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x06,
483
size_t mptsas_config_sas_io_unit_3(MPTSASState *s, uint8_t **data, int address)
485
return MPTSAS_CONFIG_PACK_EXT(3, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0x06,
486
"*l*l*l*l*l*l*l*l*l");
491
static int mptsas_phy_addr_get(MPTSASState *s, int address)
494
if ((address >> MPI_SAS_PHY_PGAD_FORM_SHIFT) == 0) {
496
} else if ((address >> MPI_SAS_PHY_PGAD_FORM_SHIFT) == 1) {
502
if (i >= MPTSAS_NUM_PORTS) {
510
size_t mptsas_config_phy_0(MPTSASState *s, uint8_t **data, int address)
514
int i = mptsas_phy_addr_get(s, address);
518
trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 0);
522
dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
523
trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 0);
525
return MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, 0x01,
527
dev_handle, s->sas_addr, dev_handle, i,
529
? MPI_SAS_DEVICE_INFO_END_DEVICE
530
: MPI_SAS_DEVICE_INFO_NO_DEVICE),
531
(MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5,
532
(MPI_SAS_IOUNIT0_RATE_3_0 << 4) | MPI_SAS_IOUNIT0_RATE_1_5);
536
size_t mptsas_config_phy_1(MPTSASState *s, uint8_t **data, int address)
540
int i = mptsas_phy_addr_get(s, address);
543
trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 1);
547
(void) mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
548
trace_mptsas_config_sas_phy(s, address, i, phy_handle, dev_handle, 1);
550
return MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_PHY, 0x01,
556
static int mptsas_device_addr_get(MPTSASState *s, int address)
559
uint32_t form = address >> MPI_SAS_PHY_PGAD_FORM_SHIFT;
560
if (form == MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) {
561
handle = address & MPI_SAS_DEVICE_PGAD_GNH_HANDLE_MASK;
563
if (handle == 65535) {
564
handle = MPTSAS_NUM_PORTS + 1;
568
i = handle - 1 - MPTSAS_NUM_PORTS;
569
} while (i < MPTSAS_NUM_PORTS && !scsi_device_find(&s->bus, 0, i, 0));
571
} else if (form == MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID) {
572
if (address & MPI_SAS_DEVICE_PGAD_BT_BUS_MASK) {
575
i = address & MPI_SAS_DEVICE_PGAD_BT_TID_MASK;
577
} else if (form == MPI_SAS_DEVICE_PGAD_FORM_HANDLE) {
578
handle = address & MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK;
579
i = handle - 1 - MPTSAS_NUM_PORTS;
585
if (i >= MPTSAS_NUM_PORTS) {
593
size_t mptsas_config_sas_device_0(MPTSASState *s, uint8_t **data, int address)
597
int i = mptsas_device_addr_get(s, address);
598
SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
600
trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 0);
605
return MPTSAS_CONFIG_PACK_EXT(0, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x05,
607
dev->wwn, phy_handle, i,
608
MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS,
610
MPI_SAS_DEVICE_INFO_END_DEVICE | MPI_SAS_DEVICE_INFO_SSP_TARGET,
611
(MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT |
612
MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED |
613
MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT), i);
617
size_t mptsas_config_sas_device_1(MPTSASState *s, uint8_t **data, int address)
621
int i = mptsas_device_addr_get(s, address);
622
SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
624
trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 1);
629
return MPTSAS_CONFIG_PACK_EXT(1, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x00,
631
dev->wwn, dev_handle, i, 0);
635
size_t mptsas_config_sas_device_2(MPTSASState *s, uint8_t **data, int address)
639
int i = mptsas_device_addr_get(s, address);
640
SCSIDevice *dev = mptsas_phy_get_device(s, i, &phy_handle, &dev_handle);
642
trace_mptsas_config_sas_device(s, address, i, phy_handle, dev_handle, 2);
647
return MPTSAS_CONFIG_PACK_EXT(2, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0x01,
651
typedef struct MPTSASConfigPage {
654
size_t (*mpt_config_build)(MPTSASState *s, uint8_t **data, int address);
657
static const MPTSASConfigPage mptsas_config_pages[] = {
659
0, MPI_CONFIG_PAGETYPE_MANUFACTURING,
660
mptsas_config_manufacturing_0,
662
1, MPI_CONFIG_PAGETYPE_MANUFACTURING,
663
mptsas_config_manufacturing_1,
665
2, MPI_CONFIG_PAGETYPE_MANUFACTURING,
666
mptsas_config_manufacturing_2,
668
3, MPI_CONFIG_PAGETYPE_MANUFACTURING,
669
mptsas_config_manufacturing_3,
671
4, MPI_CONFIG_PAGETYPE_MANUFACTURING,
672
mptsas_config_manufacturing_4,
674
5, MPI_CONFIG_PAGETYPE_MANUFACTURING,
675
mptsas_config_manufacturing_5,
677
6, MPI_CONFIG_PAGETYPE_MANUFACTURING,
678
mptsas_config_manufacturing_6,
680
7, MPI_CONFIG_PAGETYPE_MANUFACTURING,
681
mptsas_config_manufacturing_7,
683
8, MPI_CONFIG_PAGETYPE_MANUFACTURING,
684
mptsas_config_manufacturing_8,
686
9, MPI_CONFIG_PAGETYPE_MANUFACTURING,
687
mptsas_config_manufacturing_9,
689
10, MPI_CONFIG_PAGETYPE_MANUFACTURING,
690
mptsas_config_manufacturing_10,
692
0, MPI_CONFIG_PAGETYPE_IO_UNIT,
693
mptsas_config_io_unit_0,
695
1, MPI_CONFIG_PAGETYPE_IO_UNIT,
696
mptsas_config_io_unit_1,
698
2, MPI_CONFIG_PAGETYPE_IO_UNIT,
699
mptsas_config_io_unit_2,
701
3, MPI_CONFIG_PAGETYPE_IO_UNIT,
702
mptsas_config_io_unit_3,
704
4, MPI_CONFIG_PAGETYPE_IO_UNIT,
705
mptsas_config_io_unit_4,
707
0, MPI_CONFIG_PAGETYPE_IOC,
710
1, MPI_CONFIG_PAGETYPE_IOC,
713
2, MPI_CONFIG_PAGETYPE_IOC,
716
3, MPI_CONFIG_PAGETYPE_IOC,
719
4, MPI_CONFIG_PAGETYPE_IOC,
722
5, MPI_CONFIG_PAGETYPE_IOC,
725
6, MPI_CONFIG_PAGETYPE_IOC,
728
0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
729
mptsas_config_sas_io_unit_0,
731
1, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
732
mptsas_config_sas_io_unit_1,
734
2, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
735
mptsas_config_sas_io_unit_2,
737
3, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
738
mptsas_config_sas_io_unit_3,
740
0, MPI_CONFIG_EXTPAGETYPE_SAS_PHY,
743
1, MPI_CONFIG_EXTPAGETYPE_SAS_PHY,
746
0, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE,
747
mptsas_config_sas_device_0,
749
1, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE,
750
mptsas_config_sas_device_1,
752
2, MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE,
753
mptsas_config_sas_device_2,
757
static const MPTSASConfigPage *mptsas_find_config_page(int type, int number)
759
const MPTSASConfigPage *page;
762
for (i = 0; i < ARRAY_SIZE(mptsas_config_pages); i++) {
763
page = &mptsas_config_pages[i];
764
if (page->type == type && page->number == number) {
772
void mptsas_process_config(MPTSASState *s, MPIMsgConfig *req)
774
PCIDevice *pci = PCI_DEVICE(s);
776
MPIMsgConfigReply reply;
777
const MPTSASConfigPage *page;
780
uint8_t *data = NULL;
781
uint32_t flags_and_length;
785
mptsas_fix_config_endianness(req);
787
QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
788
QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
791
memset(&reply, 0, sizeof(reply));
792
reply.Action = req->Action;
793
reply.Function = req->Function;
794
reply.MsgContext = req->MsgContext;
795
reply.MsgLength = sizeof(reply) / 4;
796
reply.PageType = req->PageType;
797
reply.PageNumber = req->PageNumber;
798
reply.PageLength = req->PageLength;
799
reply.PageVersion = req->PageVersion;
801
type = req->PageType & MPI_CONFIG_PAGETYPE_MASK;
802
if (type == MPI_CONFIG_PAGETYPE_EXTENDED) {
803
type = req->ExtPageType;
804
if (type <= MPI_CONFIG_PAGETYPE_MASK) {
805
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_TYPE;
809
reply.ExtPageType = req->ExtPageType;
812
page = mptsas_find_config_page(type, req->PageNumber);
814
switch(req->Action) {
815
case MPI_CONFIG_ACTION_PAGE_DEFAULT:
816
case MPI_CONFIG_ACTION_PAGE_HEADER:
817
case MPI_CONFIG_ACTION_PAGE_READ_NVRAM:
818
case MPI_CONFIG_ACTION_PAGE_READ_CURRENT:
819
case MPI_CONFIG_ACTION_PAGE_READ_DEFAULT:
820
case MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT:
821
case MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM:
825
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_ACTION;
830
page = mptsas_find_config_page(type, 1);
832
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE;
834
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_TYPE;
839
if (req->Action == MPI_CONFIG_ACTION_PAGE_DEFAULT ||
840
req->Action == MPI_CONFIG_ACTION_PAGE_HEADER) {
841
length = page->mpt_config_build(s, NULL, req->PageAddress);
842
if ((ssize_t)length < 0) {
843
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE;
850
if (req->Action == MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
851
req->Action == MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
852
length = page->mpt_config_build(s, NULL, req->PageAddress);
853
if ((ssize_t)length < 0) {
854
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE;
856
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_CANT_COMMIT;
861
flags_and_length = req->PageBufferSGE.FlagsLength;
862
dmalen = flags_and_length & MPI_SGE_LENGTH_MASK;
864
length = page->mpt_config_build(s, NULL, req->PageAddress);
865
if ((ssize_t)length < 0) {
866
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE;
873
if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
874
pa = req->PageBufferSGE.u.Address64;
876
pa = req->PageBufferSGE.u.Address32;
880
length = page->mpt_config_build(s, &data, req->PageAddress);
881
if ((ssize_t)length < 0) {
882
reply.IOCStatus = MPI_IOCSTATUS_CONFIG_INVALID_PAGE;
885
assert(data[2] == page->number);
886
pci_dma_write(pci, pa, data, MIN(length, dmalen));
893
if (type > MPI_CONFIG_PAGETYPE_MASK) {
894
reply.ExtPageLength = length / 4;
895
reply.ExtPageType = req->ExtPageType;
897
reply.PageLength = length / 4;
901
mptsas_fix_config_reply_endianness(&reply);
902
mptsas_reply(s, (MPIDefaultReply *)&reply);