1/* 2 * Copyright IBM Corp. 2012 3 * 4 * Author(s): 5 * Jan Glauber <jang@linux.vnet.ibm.com> 6 */ 7 8#define KMSG_COMPONENT "zpci" 9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 11#include <linux/kernel.h> 12#include <linux/pci.h> 13#include <asm/pci_debug.h> 14#include <asm/sclp.h> 15 16/* Content Code Description for PCI Function Error */ 17struct zpci_ccdf_err { 18 u32 reserved1; 19 u32 fh; /* function handle */ 20 u32 fid; /* function id */ 21 u32 ett : 4; /* expected table type */ 22 u32 mvn : 12; /* MSI vector number */ 23 u32 dmaas : 8; /* DMA address space */ 24 u32 : 6; 25 u32 q : 1; /* event qualifier */ 26 u32 rw : 1; /* read/write */ 27 u64 faddr; /* failing address */ 28 u32 reserved3; 29 u16 reserved4; 30 u16 pec; /* PCI event code */ 31} __packed; 32 33/* Content Code Description for PCI Function Availability */ 34struct zpci_ccdf_avail { 35 u32 reserved1; 36 u32 fh; /* function handle */ 37 u32 fid; /* function id */ 38 u32 reserved2; 39 u32 reserved3; 40 u32 reserved4; 41 u32 reserved5; 42 u16 reserved6; 43 u16 pec; /* PCI event code */ 44} __packed; 45 46static void __zpci_event_error(struct zpci_ccdf_err *ccdf) 47{ 48 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 49 50 zpci_err("error CCDF:\n"); 51 zpci_err_hex(ccdf, sizeof(*ccdf)); 52 53 if (!zdev) 54 return; 55 56 pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", 57 pci_name(zdev->pdev), ccdf->pec, ccdf->fid); 58} 59 60void zpci_event_error(void *data) 61{ 62 if (zpci_is_enabled()) 63 __zpci_event_error(data); 64} 65 66static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) 67{ 68 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 69 struct pci_dev *pdev = zdev ? zdev->pdev : NULL; 70 int ret; 71 72 pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n", 73 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); 74 zpci_err("avail CCDF:\n"); 75 zpci_err_hex(ccdf, sizeof(*ccdf)); 76 77 switch (ccdf->pec) { 78 case 0x0301: /* Standby -> Configured */ 79 if (!zdev || zdev->state != ZPCI_FN_STATE_STANDBY) 80 break; 81 zdev->state = ZPCI_FN_STATE_CONFIGURED; 82 zdev->fh = ccdf->fh; 83 ret = zpci_enable_device(zdev); 84 if (ret) 85 break; 86 pci_rescan_bus(zdev->bus); 87 break; 88 case 0x0302: /* Reserved -> Standby */ 89 if (!zdev) 90 clp_add_pci_device(ccdf->fid, ccdf->fh, 0); 91 break; 92 case 0x0303: /* Deconfiguration requested */ 93 if (pdev) 94 pci_stop_and_remove_bus_device(pdev); 95 96 ret = zpci_disable_device(zdev); 97 if (ret) 98 break; 99 100 ret = sclp_pci_deconfigure(zdev->fid); 101 zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret); 102 if (!ret) 103 zdev->state = ZPCI_FN_STATE_STANDBY; 104 105 break; 106 case 0x0304: /* Configured -> Standby */ 107 if (pdev) { 108 /* Give the driver a hint that the function is 109 * already unusable. */ 110 pdev->error_state = pci_channel_io_perm_failure; 111 pci_stop_and_remove_bus_device(pdev); 112 } 113 114 zdev->fh = ccdf->fh; 115 zpci_disable_device(zdev); 116 zdev->state = ZPCI_FN_STATE_STANDBY; 117 break; 118 case 0x0306: /* 0x308 or 0x302 for multiple devices */ 119 clp_rescan_pci_devices(); 120 break; 121 case 0x0308: /* Standby -> Reserved */ 122 if (!zdev) 123 break; 124 pci_stop_root_bus(zdev->bus); 125 pci_remove_root_bus(zdev->bus); 126 break; 127 default: 128 break; 129 } 130} 131 132void zpci_event_availability(void *data) 133{ 134 if (zpci_is_enabled()) 135 __zpci_event_availability(data); 136} 137