void __exit sclp_sdias_exit(void) { debug_unregister(sdias_dbf); sclp_unregister(&sclp_sdias_register); }
int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid) { DECLARE_COMPLETION_ONSTACK(completion); struct err_notify_sccb *sccb; struct sclp_req req; int ret; ret = sclp_pci_check_report(report); if (ret) return ret; mutex_lock(&sclp_pci_mutex); ret = sclp_register(&sclp_pci_event); if (ret) goto out_unlock; if (!(sclp_pci_event.sclp_receive_mask & EVTYP_ERRNOTIFY_MASK)) { ret = -EOPNOTSUPP; goto out_unregister; } sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!sccb) { ret = -ENOMEM; goto out_unregister; } memset(&req, 0, sizeof(req)); req.callback_data = &completion; req.callback = sclp_pci_callback; req.command = SCLP_CMDW_WRITE_EVENT_DATA; req.status = SCLP_REQ_FILLED; req.sccb = sccb; sccb->evbuf.header.length = sizeof(sccb->evbuf) + report->length; sccb->evbuf.header.type = EVTYP_ERRNOTIFY; sccb->header.length = sizeof(sccb->header) + sccb->evbuf.header.length; sccb->evbuf.action = report->action; sccb->evbuf.atype = SCLP_ATYPE_PCI; sccb->evbuf.fh = fh; sccb->evbuf.fid = fid; memcpy(sccb->evbuf.data, report->data, report->length); ret = sclp_add_request(&req); if (ret) goto out_free_req; wait_for_completion(&completion); if (req.status != SCLP_REQ_DONE) { pr_warn("request failed (status=0x%02x)\n", req.status); ret = -EIO; goto out_free_req; } if (sccb->header.response_code != 0x0020) { pr_warn("request failed with response code 0x%x\n", sccb->header.response_code); ret = -EIO; } out_free_req: free_page((unsigned long) sccb); out_unregister: sclp_unregister(&sclp_pci_event); out_unlock: mutex_unlock(&sclp_pci_mutex); return ret; }