2 * PCI I/O adapter configuration related functions.
4 * Copyright IBM Corp. 2016
6 #define KMSG_COMPONENT "sclp_cmd"
7 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
9 #include <linux/completion.h>
10 #include <linux/export.h>
11 #include <linux/mutex.h>
12 #include <linux/errno.h>
13 #include <linux/slab.h>
14 #include <linux/init.h>
15 #include <linux/err.h>
21 #define SCLP_CMDW_CONFIGURE_PCI 0x001a0001
22 #define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001
24 #define SCLP_ATYPE_PCI 2
26 #define SCLP_ERRNOTIFY_AQ_REPAIR 1
27 #define SCLP_ERRNOTIFY_AQ_INFO_LOG 2
29 static DEFINE_MUTEX(sclp_pci_mutex
);
30 static struct sclp_register sclp_pci_event
= {
31 .send_mask
= EVTYP_ERRNOTIFY_MASK
,
34 struct err_notify_evbuf
{
35 struct evbuf_header header
;
43 struct err_notify_sccb
{
44 struct sccb_header header
;
45 struct err_notify_evbuf evbuf
;
49 struct sccb_header header
;
50 u8 atype
; /* adapter type */
53 u32 aid
; /* adapter identifier */
56 static int do_pci_configure(sclp_cmdw_t cmd
, u32 fid
)
58 struct pci_cfg_sccb
*sccb
;
61 if (!SCLP_HAS_PCI_RECONFIG
)
64 sccb
= (struct pci_cfg_sccb
*) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
68 sccb
->header
.length
= PAGE_SIZE
;
69 sccb
->atype
= SCLP_ATYPE_PCI
;
71 rc
= sclp_sync_request(cmd
, sccb
);
74 switch (sccb
->header
.response_code
) {
79 pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n",
80 cmd
, sccb
->header
.response_code
);
85 free_page((unsigned long) sccb
);
89 int sclp_pci_configure(u32 fid
)
91 return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI
, fid
);
93 EXPORT_SYMBOL(sclp_pci_configure
);
95 int sclp_pci_deconfigure(u32 fid
)
97 return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI
, fid
);
99 EXPORT_SYMBOL(sclp_pci_deconfigure
);
101 static void sclp_pci_callback(struct sclp_req
*req
, void *data
)
103 struct completion
*completion
= data
;
105 complete(completion
);
108 static int sclp_pci_check_report(struct zpci_report_error_header
*report
)
110 if (report
->version
!= 1)
113 if (report
->action
!= SCLP_ERRNOTIFY_AQ_REPAIR
&&
114 report
->action
!= SCLP_ERRNOTIFY_AQ_INFO_LOG
)
117 if (report
->length
> (PAGE_SIZE
- sizeof(struct err_notify_sccb
)))
123 int sclp_pci_report(struct zpci_report_error_header
*report
, u32 fh
, u32 fid
)
125 DECLARE_COMPLETION_ONSTACK(completion
);
126 struct err_notify_sccb
*sccb
;
130 ret
= sclp_pci_check_report(report
);
134 mutex_lock(&sclp_pci_mutex
);
135 ret
= sclp_register(&sclp_pci_event
);
139 if (!(sclp_pci_event
.sclp_receive_mask
& EVTYP_ERRNOTIFY_MASK
)) {
144 sccb
= (void *) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
150 memset(&req
, 0, sizeof(req
));
151 req
.callback_data
= &completion
;
152 req
.callback
= sclp_pci_callback
;
153 req
.command
= SCLP_CMDW_WRITE_EVENT_DATA
;
154 req
.status
= SCLP_REQ_FILLED
;
157 sccb
->evbuf
.header
.length
= sizeof(sccb
->evbuf
) + report
->length
;
158 sccb
->evbuf
.header
.type
= EVTYP_ERRNOTIFY
;
159 sccb
->header
.length
= sizeof(sccb
->header
) + sccb
->evbuf
.header
.length
;
161 sccb
->evbuf
.action
= report
->action
;
162 sccb
->evbuf
.atype
= SCLP_ATYPE_PCI
;
164 sccb
->evbuf
.fid
= fid
;
166 memcpy(sccb
->evbuf
.data
, report
->data
, report
->length
);
168 ret
= sclp_add_request(&req
);
172 wait_for_completion(&completion
);
173 if (req
.status
!= SCLP_REQ_DONE
) {
174 pr_warn("request failed (status=0x%02x)\n",
180 if (sccb
->header
.response_code
!= 0x0020) {
181 pr_warn("request failed with response code 0x%x\n",
182 sccb
->header
.response_code
);
187 free_page((unsigned long) sccb
);
189 sclp_unregister(&sclp_pci_event
);
191 mutex_unlock(&sclp_pci_mutex
);