s390/pci: cleanup function information block

Cleanup function information block used as a modify pci function
parameter. Change reserved members to be anonymous. Fix the size
of the struct and add proper alignment information. Also put the
FIB on the stack.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h
index df6eac9..649eb62 100644
--- a/arch/s390/include/asm/pci_insn.h
+++ b/arch/s390/include/asm/pci_insn.h
@@ -54,11 +54,9 @@
 struct zpci_fib {
 	u32 fmt		:  8;	/* format */
 	u32		: 24;
-	u32 reserved1;
+	u32		: 32;
 	u8 fc;			/* function controls */
-	u8 reserved2;
-	u16 reserved3;
-	u32 reserved4;
+	u64		: 56;
 	u64 pba;		/* PCI base address */
 	u64 pal;		/* PCI address limit */
 	u64 iota;		/* I/O Translation Anchor */
@@ -70,14 +68,13 @@
 	u32 sum		:  1;	/* Adapter int summary bit enabled */
 	u32		:  1;
 	u32 aisbo	:  6;	/* Adapter int summary bit offset */
-	u32 reserved5;
+	u32		: 32;
 	u64 aibv;		/* Adapter int bit vector address */
 	u64 aisb;		/* Adapter int summary bit address */
 	u64 fmb_addr;		/* Function measurement block address and key */
-	u64 reserved6;
-	u64 reserved7;
-} __packed;
-
+	u32		: 32;
+	u32 gd;
+} __packed __aligned(8);
 
 int zpci_mod_fc(u64 req, struct zpci_fib *fib);
 int zpci_refresh_trans(u64 fn, u64 addr, u64 range);
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index fd6d6ce..0c9a177 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -120,25 +120,17 @@
 static int zpci_set_airq(struct zpci_dev *zdev)
 {
 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
-	struct zpci_fib *fib;
-	int rc;
+	struct zpci_fib fib = {0};
 
-	fib = (void *) get_zeroed_page(GFP_KERNEL);
-	if (!fib)
-		return -ENOMEM;
+	fib.isc = PCI_ISC;
+	fib.sum = 1;		/* enable summary notifications */
+	fib.noi = airq_iv_end(zdev->aibv);
+	fib.aibv = (unsigned long) zdev->aibv->vector;
+	fib.aibvo = 0;		/* each zdev has its own interrupt vector */
+	fib.aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8;
+	fib.aisbo = zdev->aisb & 63;
 
-	fib->isc = PCI_ISC;
-	fib->sum = 1;		/* enable summary notifications */
-	fib->noi = airq_iv_end(zdev->aibv);
-	fib->aibv = (unsigned long) zdev->aibv->vector;
-	fib->aibvo = 0;		/* each zdev has its own interrupt vector */
-	fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8;
-	fib->aisbo = zdev->aisb & 63;
-
-	rc = zpci_mod_fc(req, fib);
-
-	free_page((unsigned long) fib);
-	return rc;
+	return zpci_mod_fc(req, &fib);
 }
 
 struct mod_pci_args {
@@ -151,22 +143,14 @@
 static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
 {
 	u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn);
-	struct zpci_fib *fib;
-	int rc;
+	struct zpci_fib fib = {0};
 
-	/* The FIB must be available even if it's not used */
-	fib = (void *) get_zeroed_page(GFP_KERNEL);
-	if (!fib)
-		return -ENOMEM;
+	fib.pba = args->base;
+	fib.pal = args->limit;
+	fib.iota = args->iota;
+	fib.fmb_addr = args->fmb_addr;
 
-	fib->pba = args->base;
-	fib->pal = args->limit;
-	fib->iota = args->iota;
-	fib->fmb_addr = args->fmb_addr;
-
-	rc = zpci_mod_fc(req, fib);
-	free_page((unsigned long) fib);
-	return rc;
+	return zpci_mod_fc(req, &fib);
 }
 
 /* Modify PCI: Register I/O address translation parameters */