diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-09 05:35:27 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-09 05:35:27 -0400 |
commit | ca3dd88e411648c76e1911a729440e3763ba5049 (patch) | |
tree | e874ed0c1e91269aa514a443358d4f3738bcb244 /arch/sparc64/kernel/pci_sabre.c | |
parent | de372ecd80a42c4fb485c7232475301a18d05184 (diff) |
[SPARC64] PCI: Consolidate PCI access code into pci_common.c
All the sun4u controllers do the same thing to compute the physical
I/O address to poke, and we can move the sun4v code into this common
location too.
This one needs a bit of testing, in particular the Sabre code had some
funny stuff that would break up u16 and/or u32 accesses into pieces
and I didn't think that was needed any more. If it is we need to find
out why and add back code to do it again.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_sabre.c')
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 288 |
1 files changed, 2 insertions, 286 deletions
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 4cefe6e83b24..e2377796de89 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -205,294 +205,9 @@ | |||
205 | #define SABRE_MEMSPACE 0x100000000UL | 205 | #define SABRE_MEMSPACE 0x100000000UL |
206 | #define SABRE_MEMSPACE_SIZE 0x07fffffffUL | 206 | #define SABRE_MEMSPACE_SIZE 0x07fffffffUL |
207 | 207 | ||
208 | /* UltraSparc-IIi Programmer's Manual, page 325, PCI | ||
209 | * configuration space address format: | ||
210 | * | ||
211 | * 32 24 23 16 15 11 10 8 7 2 1 0 | ||
212 | * --------------------------------------------------------- | ||
213 | * |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 | | ||
214 | * --------------------------------------------------------- | ||
215 | */ | ||
216 | #define SABRE_CONFIG_BASE(PBM) \ | ||
217 | ((PBM)->config_space | (1UL << 24)) | ||
218 | #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ | ||
219 | (((unsigned long)(BUS) << 16) | \ | ||
220 | ((unsigned long)(DEVFN) << 8) | \ | ||
221 | ((unsigned long)(REG))) | ||
222 | |||
223 | static int hummingbird_p; | 208 | static int hummingbird_p; |
224 | static struct pci_bus *sabre_root_bus; | 209 | static struct pci_bus *sabre_root_bus; |
225 | 210 | ||
226 | static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm, | ||
227 | unsigned char bus, | ||
228 | unsigned int devfn, | ||
229 | int where) | ||
230 | { | ||
231 | if (!pbm) | ||
232 | return NULL; | ||
233 | return (void *) | ||
234 | (SABRE_CONFIG_BASE(pbm) | | ||
235 | SABRE_CONFIG_ENCODE(bus, devfn, where)); | ||
236 | } | ||
237 | |||
238 | static int sabre_out_of_range(unsigned char devfn) | ||
239 | { | ||
240 | if (hummingbird_p) | ||
241 | return 0; | ||
242 | |||
243 | return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) || | ||
244 | ((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) || | ||
245 | (PCI_SLOT(devfn) > 1)); | ||
246 | } | ||
247 | |||
248 | static int __sabre_out_of_range(struct pci_pbm_info *pbm, | ||
249 | unsigned char bus, | ||
250 | unsigned char devfn) | ||
251 | { | ||
252 | if (hummingbird_p) | ||
253 | return 0; | ||
254 | |||
255 | return ((pbm->parent == 0) || | ||
256 | ((pbm == &pbm->parent->pbm_A) && | ||
257 | (bus == pbm->pci_first_busno) && | ||
258 | PCI_SLOT(devfn) > 8)); | ||
259 | } | ||
260 | |||
261 | static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
262 | int where, int size, u32 *value) | ||
263 | { | ||
264 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
265 | unsigned char bus = bus_dev->number; | ||
266 | u32 *addr; | ||
267 | u16 tmp16; | ||
268 | u8 tmp8; | ||
269 | |||
270 | switch (size) { | ||
271 | case 1: | ||
272 | *value = 0xff; | ||
273 | break; | ||
274 | case 2: | ||
275 | *value = 0xffff; | ||
276 | break; | ||
277 | case 4: | ||
278 | *value = 0xffffffff; | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); | ||
283 | if (!addr) | ||
284 | return PCIBIOS_SUCCESSFUL; | ||
285 | |||
286 | if (__sabre_out_of_range(pbm, bus, devfn)) | ||
287 | return PCIBIOS_SUCCESSFUL; | ||
288 | |||
289 | switch (size) { | ||
290 | case 1: | ||
291 | pci_config_read8((u8 *) addr, &tmp8); | ||
292 | *value = tmp8; | ||
293 | break; | ||
294 | |||
295 | case 2: | ||
296 | if (where & 0x01) { | ||
297 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
298 | where); | ||
299 | return PCIBIOS_SUCCESSFUL; | ||
300 | } | ||
301 | pci_config_read16((u16 *) addr, &tmp16); | ||
302 | *value = tmp16; | ||
303 | break; | ||
304 | |||
305 | case 4: | ||
306 | if (where & 0x03) { | ||
307 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
308 | where); | ||
309 | return PCIBIOS_SUCCESSFUL; | ||
310 | } | ||
311 | pci_config_read32(addr, value); | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | return PCIBIOS_SUCCESSFUL; | ||
316 | } | ||
317 | |||
318 | static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, | ||
319 | int where, int size, u32 *value) | ||
320 | { | ||
321 | struct pci_pbm_info *pbm = bus->sysdata; | ||
322 | |||
323 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
324 | return pci_host_bridge_read_pci_cfg(bus, devfn, where, | ||
325 | size, value); | ||
326 | |||
327 | if (!bus->number && sabre_out_of_range(devfn)) { | ||
328 | switch (size) { | ||
329 | case 1: | ||
330 | *value = 0xff; | ||
331 | break; | ||
332 | case 2: | ||
333 | *value = 0xffff; | ||
334 | break; | ||
335 | case 4: | ||
336 | *value = 0xffffffff; | ||
337 | break; | ||
338 | } | ||
339 | return PCIBIOS_SUCCESSFUL; | ||
340 | } | ||
341 | |||
342 | if (bus->number || PCI_SLOT(devfn)) | ||
343 | return __sabre_read_pci_cfg(bus, devfn, where, size, value); | ||
344 | |||
345 | /* When accessing PCI config space of the PCI controller itself (bus | ||
346 | * 0, device slot 0, function 0) there are restrictions. Each | ||
347 | * register must be accessed as it's natural size. Thus, for example | ||
348 | * the Vendor ID must be accessed as a 16-bit quantity. | ||
349 | */ | ||
350 | |||
351 | switch (size) { | ||
352 | case 1: | ||
353 | if (where < 8) { | ||
354 | u32 tmp32; | ||
355 | u16 tmp16; | ||
356 | |||
357 | __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32); | ||
358 | tmp16 = (u16) tmp32; | ||
359 | if (where & 1) | ||
360 | *value = tmp16 >> 8; | ||
361 | else | ||
362 | *value = tmp16 & 0xff; | ||
363 | } else | ||
364 | return __sabre_read_pci_cfg(bus, devfn, where, 1, value); | ||
365 | break; | ||
366 | |||
367 | case 2: | ||
368 | if (where < 8) | ||
369 | return __sabre_read_pci_cfg(bus, devfn, where, 2, value); | ||
370 | else { | ||
371 | u32 tmp32; | ||
372 | u8 tmp8; | ||
373 | |||
374 | __sabre_read_pci_cfg(bus, devfn, where, 1, &tmp32); | ||
375 | tmp8 = (u8) tmp32; | ||
376 | *value = tmp8; | ||
377 | __sabre_read_pci_cfg(bus, devfn, where + 1, 1, &tmp32); | ||
378 | tmp8 = (u8) tmp32; | ||
379 | *value |= tmp8 << 8; | ||
380 | } | ||
381 | break; | ||
382 | |||
383 | case 4: { | ||
384 | u32 tmp32; | ||
385 | u16 tmp16; | ||
386 | |||
387 | sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32); | ||
388 | tmp16 = (u16) tmp32; | ||
389 | *value = tmp16; | ||
390 | sabre_read_pci_cfg(bus, devfn, where + 2, 2, &tmp32); | ||
391 | tmp16 = (u16) tmp32; | ||
392 | *value |= tmp16 << 16; | ||
393 | break; | ||
394 | } | ||
395 | } | ||
396 | return PCIBIOS_SUCCESSFUL; | ||
397 | } | ||
398 | |||
399 | static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
400 | int where, int size, u32 value) | ||
401 | { | ||
402 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
403 | unsigned char bus = bus_dev->number; | ||
404 | u32 *addr; | ||
405 | |||
406 | addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); | ||
407 | if (!addr) | ||
408 | return PCIBIOS_SUCCESSFUL; | ||
409 | |||
410 | if (__sabre_out_of_range(pbm, bus, devfn)) | ||
411 | return PCIBIOS_SUCCESSFUL; | ||
412 | |||
413 | switch (size) { | ||
414 | case 1: | ||
415 | pci_config_write8((u8 *) addr, value); | ||
416 | break; | ||
417 | |||
418 | case 2: | ||
419 | if (where & 0x01) { | ||
420 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
421 | where); | ||
422 | return PCIBIOS_SUCCESSFUL; | ||
423 | } | ||
424 | pci_config_write16((u16 *) addr, value); | ||
425 | break; | ||
426 | |||
427 | case 4: | ||
428 | if (where & 0x03) { | ||
429 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
430 | where); | ||
431 | return PCIBIOS_SUCCESSFUL; | ||
432 | } | ||
433 | pci_config_write32(addr, value); | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | return PCIBIOS_SUCCESSFUL; | ||
438 | } | ||
439 | |||
440 | static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, | ||
441 | int where, int size, u32 value) | ||
442 | { | ||
443 | struct pci_pbm_info *pbm = bus->sysdata; | ||
444 | |||
445 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
446 | return pci_host_bridge_write_pci_cfg(bus, devfn, where, | ||
447 | size, value); | ||
448 | |||
449 | if (bus->number) | ||
450 | return __sabre_write_pci_cfg(bus, devfn, where, size, value); | ||
451 | |||
452 | if (sabre_out_of_range(devfn)) | ||
453 | return PCIBIOS_SUCCESSFUL; | ||
454 | |||
455 | switch (size) { | ||
456 | case 1: | ||
457 | if (where < 8) { | ||
458 | u32 tmp32; | ||
459 | u16 tmp16; | ||
460 | |||
461 | __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32); | ||
462 | tmp16 = (u16) tmp32; | ||
463 | if (where & 1) { | ||
464 | value &= 0x00ff; | ||
465 | value |= tmp16 << 8; | ||
466 | } else { | ||
467 | value &= 0xff00; | ||
468 | value |= tmp16; | ||
469 | } | ||
470 | tmp32 = (u32) tmp16; | ||
471 | return __sabre_write_pci_cfg(bus, devfn, where & ~1, 2, tmp32); | ||
472 | } else | ||
473 | return __sabre_write_pci_cfg(bus, devfn, where, 1, value); | ||
474 | break; | ||
475 | case 2: | ||
476 | if (where < 8) | ||
477 | return __sabre_write_pci_cfg(bus, devfn, where, 2, value); | ||
478 | else { | ||
479 | __sabre_write_pci_cfg(bus, devfn, where, 1, value & 0xff); | ||
480 | __sabre_write_pci_cfg(bus, devfn, where + 1, 1, value >> 8); | ||
481 | } | ||
482 | break; | ||
483 | case 4: | ||
484 | sabre_write_pci_cfg(bus, devfn, where, 2, value & 0xffff); | ||
485 | sabre_write_pci_cfg(bus, devfn, where + 2, 2, value >> 16); | ||
486 | break; | ||
487 | } | ||
488 | return PCIBIOS_SUCCESSFUL; | ||
489 | } | ||
490 | |||
491 | static struct pci_ops sabre_ops = { | ||
492 | .read = sabre_read_pci_cfg, | ||
493 | .write = sabre_write_pci_cfg, | ||
494 | }; | ||
495 | |||
496 | /* SABRE error handling support. */ | 211 | /* SABRE error handling support. */ |
497 | static void sabre_check_iommu_error(struct pci_pbm_info *pbm, | 212 | static void sabre_check_iommu_error(struct pci_pbm_info *pbm, |
498 | unsigned long afsr, | 213 | unsigned long afsr, |
@@ -1010,7 +725,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *p | |||
1010 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | 725 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
1011 | 726 | ||
1012 | pbm->scan_bus = sabre_scan_bus; | 727 | pbm->scan_bus = sabre_scan_bus; |
1013 | pbm->pci_ops = &sabre_ops; | 728 | pbm->pci_ops = &sun4u_pci_ops; |
729 | pbm->config_space_reg_bits = 8; | ||
1014 | 730 | ||
1015 | pbm->index = pci_num_pbms++; | 731 | pbm->index = pci_num_pbms++; |
1016 | 732 | ||