diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2012-11-29 08:35:47 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-11-30 11:47:25 -0500 |
commit | 7441b0627e2251370902305a204e1330a696ca04 (patch) | |
tree | d3a36466a8517f8b889b6f0037f15280e33302d4 /drivers/s390 | |
parent | cbc0dd1f856b52b59c2c73a477b6cb210c8c66ad (diff) |
s390/pci: PCI hotplug support via SCLP
Add SCLP PCI configure/deconfigure and implement a PCI hotplug
controller (s390_pci_hpc). The hotplug controller creates a slot
for every PCI function in stand-by or configured state. The PCI
functions are named after the PCI function ID (fid). By writing to
the power attribute in /sys/bus/pci/slots/<fid>/power the PCI function
is moved to stand-by or configured state. If moved to the configured
state the device is automatically scanned by the s390 PCI layer.
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/sclp.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 64 |
2 files changed, 65 insertions, 2 deletions
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index d7e97ae9ef6d..25bcd4c0ed82 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright IBM Corp. 1999, 2009 | 2 | * Copyright IBM Corp. 1999,2012 |
3 | * | 3 | * |
4 | * Author(s): Martin Peschke <mpeschke@de.ibm.com> | 4 | * Author(s): Martin Peschke <mpeschke@de.ibm.com> |
5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -103,6 +103,7 @@ extern u64 sclp_facilities; | |||
103 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | 103 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) |
104 | #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) | 104 | #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) |
105 | #define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) | 105 | #define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) |
106 | #define SCLP_HAS_PCI_RECONFIG (sclp_facilities & 0x0000000040000000ULL) | ||
106 | 107 | ||
107 | 108 | ||
108 | struct gds_subvector { | 109 | struct gds_subvector { |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 0dfa88a30118..c44d13f607bc 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright IBM Corp. 2007, 2009 | 2 | * Copyright IBM Corp. 2007,2012 |
3 | * | 3 | * |
4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | 4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, |
5 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 5 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/export.h> | ||
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | #include <linux/string.h> | 17 | #include <linux/string.h> |
17 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
@@ -701,6 +702,67 @@ __initcall(sclp_detect_standby_memory); | |||
701 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 702 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
702 | 703 | ||
703 | /* | 704 | /* |
705 | * PCI I/O adapter configuration related functions. | ||
706 | */ | ||
707 | #define SCLP_CMDW_CONFIGURE_PCI 0x001a0001 | ||
708 | #define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001 | ||
709 | |||
710 | #define SCLP_RECONFIG_PCI_ATPYE 2 | ||
711 | |||
712 | struct pci_cfg_sccb { | ||
713 | struct sccb_header header; | ||
714 | u8 atype; /* adapter type */ | ||
715 | u8 reserved1; | ||
716 | u16 reserved2; | ||
717 | u32 aid; /* adapter identifier */ | ||
718 | } __packed; | ||
719 | |||
720 | static int do_pci_configure(sclp_cmdw_t cmd, u32 fid) | ||
721 | { | ||
722 | struct pci_cfg_sccb *sccb; | ||
723 | int rc; | ||
724 | |||
725 | if (!SCLP_HAS_PCI_RECONFIG) | ||
726 | return -EOPNOTSUPP; | ||
727 | |||
728 | sccb = (struct pci_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
729 | if (!sccb) | ||
730 | return -ENOMEM; | ||
731 | |||
732 | sccb->header.length = PAGE_SIZE; | ||
733 | sccb->atype = SCLP_RECONFIG_PCI_ATPYE; | ||
734 | sccb->aid = fid; | ||
735 | rc = do_sync_request(cmd, sccb); | ||
736 | if (rc) | ||
737 | goto out; | ||
738 | switch (sccb->header.response_code) { | ||
739 | case 0x0020: | ||
740 | case 0x0120: | ||
741 | break; | ||
742 | default: | ||
743 | pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n", | ||
744 | cmd, sccb->header.response_code); | ||
745 | rc = -EIO; | ||
746 | break; | ||
747 | } | ||
748 | out: | ||
749 | free_page((unsigned long) sccb); | ||
750 | return rc; | ||
751 | } | ||
752 | |||
753 | int sclp_pci_configure(u32 fid) | ||
754 | { | ||
755 | return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid); | ||
756 | } | ||
757 | EXPORT_SYMBOL(sclp_pci_configure); | ||
758 | |||
759 | int sclp_pci_deconfigure(u32 fid) | ||
760 | { | ||
761 | return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); | ||
762 | } | ||
763 | EXPORT_SYMBOL(sclp_pci_deconfigure); | ||
764 | |||
765 | /* | ||
704 | * Channel path configuration related functions. | 766 | * Channel path configuration related functions. |
705 | */ | 767 | */ |
706 | 768 | ||