vphb.c (3a7651e683701dbb4c7d02e20661c923fa4c6901) vphb.c (0b3f9c757cabad4b8101c5fcddddd029ed5506a6)
1/*
2 * Copyright 2014 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */

--- 124 unchanged lines hidden (view full) ---

133 break;
134 default:
135 *mask = 0xffffffff;
136 break;
137 }
138 return 0;
139}
140
1/*
2 * Copyright 2014 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */

--- 124 unchanged lines hidden (view full) ---

133 break;
134 default:
135 *mask = 0xffffffff;
136 break;
137 }
138 return 0;
139}
140
141
142static inline bool cxl_config_link_ok(struct pci_bus *bus)
143{
144 struct pci_controller *phb;
145 struct cxl_afu *afu;
146
147 /* Config space IO is based on phb->cfg_addr, which is based on
148 * afu_desc_mmio. This isn't safe to read/write when the link
149 * goes down, as EEH tears down MMIO space.
150 *
151 * Check if the link is OK before proceeding.
152 */
153
154 phb = pci_bus_to_host(bus);
155 if (phb == NULL)
156 return false;
157 afu = (struct cxl_afu *)phb->private_data;
158 return cxl_adapter_link_ok(afu->adapter);
159}
160
141static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
142 int offset, int len, u32 *val)
143{
144 volatile void __iomem *ioaddr;
145 int shift, rc;
146 u32 mask;
147
148 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
149 &mask, &shift);
150 if (rc)
151 return rc;
152
161static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
162 int offset, int len, u32 *val)
163{
164 volatile void __iomem *ioaddr;
165 int shift, rc;
166 u32 mask;
167
168 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
169 &mask, &shift);
170 if (rc)
171 return rc;
172
173 if (!cxl_config_link_ok(bus))
174 return PCIBIOS_DEVICE_NOT_FOUND;
175
153 /* Can only read 32 bits */
154 *val = (in_le32(ioaddr) >> shift) & mask;
155 return PCIBIOS_SUCCESSFUL;
156}
157
158static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
159 int offset, int len, u32 val)
160{
161 volatile void __iomem *ioaddr;
162 u32 v, mask;
163 int shift, rc;
164
165 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
166 &mask, &shift);
167 if (rc)
168 return rc;
169
176 /* Can only read 32 bits */
177 *val = (in_le32(ioaddr) >> shift) & mask;
178 return PCIBIOS_SUCCESSFUL;
179}
180
181static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
182 int offset, int len, u32 val)
183{
184 volatile void __iomem *ioaddr;
185 u32 v, mask;
186 int shift, rc;
187
188 rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
189 &mask, &shift);
190 if (rc)
191 return rc;
192
193 if (!cxl_config_link_ok(bus))
194 return PCIBIOS_DEVICE_NOT_FOUND;
195
170 /* Can only write 32 bits so do read-modify-write */
171 mask <<= shift;
172 val <<= shift;
173
174 v = (in_le32(ioaddr) & ~mask) || (val & mask);
175
176 out_le32(ioaddr, v);
177 return PCIBIOS_SUCCESSFUL;

--- 94 unchanged lines hidden ---
196 /* Can only write 32 bits so do read-modify-write */
197 mask <<= shift;
198 val <<= shift;
199
200 v = (in_le32(ioaddr) & ~mask) || (val & mask);
201
202 out_le32(ioaddr, v);
203 return PCIBIOS_SUCCESSFUL;

--- 94 unchanged lines hidden ---