aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
authorBrian King <brking@us.ibm.com>2005-09-27 04:21:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 18:36:58 -0400
commite04b0ea2e0f9c1bb0d874db4493fc7f7a623116b (patch)
tree75937e50de883f69e906a4c8bc9f119d86c14411 /drivers/pci/pci-sysfs.c
parent2cea752f683af1be58ee8f25717c0a8118e0ac5b (diff)
[PATCH] PCI: Block config access during BIST
Some PCI adapters (eg. ipr scsi adapters) have an exposure today in that they issue BIST to the adapter to reset the card. If, during the time it takes to complete BIST, userspace attempts to access PCI config space, the host bus bridge will master abort the access since the ipr adapter does not respond on the PCI bus for a brief period of time when running BIST. On PPC64 hardware, this master abort results in the host PCI bridge isolating that PCI device from the rest of the system, making the device unusable until Linux is rebooted. This patch is an attempt to close that exposure by introducing some blocking code in the PCI code. When blocked, writes will be humored and reads will return the cached value. Ben Herrenschmidt has also mentioned that he plans to use this in PPC power management. Signed-off-by: Brian King <brking@us.ibm.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/pci/access.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 20 +++++----- drivers/pci/pci.h | 7 +++ drivers/pci/proc.c | 28 +++++++-------- drivers/pci/syscall.c | 14 +++---- include/linux/pci.h | 7 +++ 6 files changed, 134 insertions(+), 31 deletions(-)
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r--drivers/pci/pci-sysfs.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 2898830c496f..965a5934623a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -130,7 +130,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
130 130
131 if ((off & 1) && size) { 131 if ((off & 1) && size) {
132 u8 val; 132 u8 val;
133 pci_read_config_byte(dev, off, &val); 133 pci_user_read_config_byte(dev, off, &val);
134 data[off - init_off] = val; 134 data[off - init_off] = val;
135 off++; 135 off++;
136 size--; 136 size--;
@@ -138,7 +138,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
138 138
139 if ((off & 3) && size > 2) { 139 if ((off & 3) && size > 2) {
140 u16 val; 140 u16 val;
141 pci_read_config_word(dev, off, &val); 141 pci_user_read_config_word(dev, off, &val);
142 data[off - init_off] = val & 0xff; 142 data[off - init_off] = val & 0xff;
143 data[off - init_off + 1] = (val >> 8) & 0xff; 143 data[off - init_off + 1] = (val >> 8) & 0xff;
144 off += 2; 144 off += 2;
@@ -147,7 +147,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
147 147
148 while (size > 3) { 148 while (size > 3) {
149 u32 val; 149 u32 val;
150 pci_read_config_dword(dev, off, &val); 150 pci_user_read_config_dword(dev, off, &val);
151 data[off - init_off] = val & 0xff; 151 data[off - init_off] = val & 0xff;
152 data[off - init_off + 1] = (val >> 8) & 0xff; 152 data[off - init_off + 1] = (val >> 8) & 0xff;
153 data[off - init_off + 2] = (val >> 16) & 0xff; 153 data[off - init_off + 2] = (val >> 16) & 0xff;
@@ -158,7 +158,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
158 158
159 if (size >= 2) { 159 if (size >= 2) {
160 u16 val; 160 u16 val;
161 pci_read_config_word(dev, off, &val); 161 pci_user_read_config_word(dev, off, &val);
162 data[off - init_off] = val & 0xff; 162 data[off - init_off] = val & 0xff;
163 data[off - init_off + 1] = (val >> 8) & 0xff; 163 data[off - init_off + 1] = (val >> 8) & 0xff;
164 off += 2; 164 off += 2;
@@ -167,7 +167,7 @@ pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
167 167
168 if (size > 0) { 168 if (size > 0) {
169 u8 val; 169 u8 val;
170 pci_read_config_byte(dev, off, &val); 170 pci_user_read_config_byte(dev, off, &val);
171 data[off - init_off] = val; 171 data[off - init_off] = val;
172 off++; 172 off++;
173 --size; 173 --size;
@@ -192,7 +192,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
192 } 192 }
193 193
194 if ((off & 1) && size) { 194 if ((off & 1) && size) {
195 pci_write_config_byte(dev, off, data[off - init_off]); 195 pci_user_write_config_byte(dev, off, data[off - init_off]);
196 off++; 196 off++;
197 size--; 197 size--;
198 } 198 }
@@ -200,7 +200,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
200 if ((off & 3) && size > 2) { 200 if ((off & 3) && size > 2) {
201 u16 val = data[off - init_off]; 201 u16 val = data[off - init_off];
202 val |= (u16) data[off - init_off + 1] << 8; 202 val |= (u16) data[off - init_off + 1] << 8;
203 pci_write_config_word(dev, off, val); 203 pci_user_write_config_word(dev, off, val);
204 off += 2; 204 off += 2;
205 size -= 2; 205 size -= 2;
206 } 206 }
@@ -210,7 +210,7 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
210 val |= (u32) data[off - init_off + 1] << 8; 210 val |= (u32) data[off - init_off + 1] << 8;
211 val |= (u32) data[off - init_off + 2] << 16; 211 val |= (u32) data[off - init_off + 2] << 16;
212 val |= (u32) data[off - init_off + 3] << 24; 212 val |= (u32) data[off - init_off + 3] << 24;
213 pci_write_config_dword(dev, off, val); 213 pci_user_write_config_dword(dev, off, val);
214 off += 4; 214 off += 4;
215 size -= 4; 215 size -= 4;
216 } 216 }
@@ -218,13 +218,13 @@ pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
218 if (size >= 2) { 218 if (size >= 2) {
219 u16 val = data[off - init_off]; 219 u16 val = data[off - init_off];
220 val |= (u16) data[off - init_off + 1] << 8; 220 val |= (u16) data[off - init_off + 1] << 8;
221 pci_write_config_word(dev, off, val); 221 pci_user_write_config_word(dev, off, val);
222 off += 2; 222 off += 2;
223 size -= 2; 223 size -= 2;
224 } 224 }
225 225
226 if (size) { 226 if (size) {
227 pci_write_config_byte(dev, off, data[off - init_off]); 227 pci_user_write_config_byte(dev, off, data[off - init_off]);
228 off++; 228 off++;
229 --size; 229 --size;
230 } 230 }