[a31845f7] | 1 | /* PCI Access Library |
---|
| 2 | * |
---|
[71e8a5c] | 3 | * COPYRIGHT (c) 2010 Cobham Gaisler AB. |
---|
[a31845f7] | 4 | * |
---|
| 5 | * The license and distribution terms for this file may be |
---|
| 6 | * found in the file LICENSE in this distribution or at |
---|
| 7 | * http://www.rtems.com/license/LICENSE. |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | #include <pci.h> |
---|
| 11 | |
---|
| 12 | /* Get PCI I/O or Configuration space access function */ |
---|
| 13 | static int pci_ioc_func(int wr, int size, void **func, void **ops) |
---|
| 14 | { |
---|
| 15 | int ofs; |
---|
| 16 | |
---|
| 17 | ofs = 0; |
---|
| 18 | if (wr) |
---|
| 19 | ofs += 3; |
---|
| 20 | if (size == 4) |
---|
| 21 | size = 3; |
---|
| 22 | ofs += (size & 0x3) - 1; |
---|
| 23 | if (ops[ofs] == NULL) |
---|
| 24 | return -1; |
---|
| 25 | if (func) |
---|
| 26 | *func = ops[ofs]; |
---|
| 27 | return 0; |
---|
| 28 | } |
---|
| 29 | |
---|
| 30 | /* Get Registers-over-Memory Space access function */ |
---|
| 31 | static int pci_memreg_func(int wr, int size, void **func, int endian) |
---|
| 32 | { |
---|
| 33 | void **ops; |
---|
| 34 | int ofs = 0; |
---|
| 35 | |
---|
| 36 | ops = (void **)pci_access_ops.memreg; |
---|
| 37 | if (!ops) |
---|
| 38 | return -1; |
---|
| 39 | |
---|
| 40 | if (size == 2) |
---|
| 41 | ofs += 2; |
---|
| 42 | else if (size == 4) |
---|
| 43 | ofs += 6; |
---|
| 44 | |
---|
| 45 | if (size != 1 && endian == PCI_BIG_ENDIAN) |
---|
| 46 | ofs += 2; |
---|
| 47 | |
---|
| 48 | if (wr) |
---|
| 49 | ofs += 1; |
---|
| 50 | |
---|
| 51 | if (ops[ofs] == NULL) |
---|
| 52 | return -1; |
---|
| 53 | if (func) |
---|
| 54 | *func = ops[ofs]; |
---|
| 55 | return 0; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | /* Get function pointer from Host/BSP driver definitions */ |
---|
| 59 | int pci_access_func(int wr, int size, void **func, int endian, int type) |
---|
| 60 | { |
---|
| 61 | switch (type) { |
---|
| 62 | default: |
---|
| 63 | case 2: /* Memory Space - not implemented */ |
---|
| 64 | return -1; |
---|
| 65 | case 1: /* I/O space */ |
---|
| 66 | return pci_ioc_func(wr, size, func, (void**)&pci_access_ops.cfg); |
---|
| 67 | case 3: /* Registers over Memory space */ |
---|
| 68 | return pci_memreg_func(wr, size, func, endian); |
---|
| 69 | case 4: /* Configuration space */ |
---|
| 70 | return pci_ioc_func(wr, size, func, (void**)&pci_access_ops.io); |
---|
| 71 | } |
---|
| 72 | } |
---|