0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/pci.h>
0012 #include <linux/types.h>
0013 #include <asm/sni.h>
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
0025 {
0026 if ((devfn > 255) || (reg > 255))
0027 return PCIBIOS_BAD_REGISTER_NUMBER;
0028
0029 if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
0030 return PCIBIOS_DEVICE_NOT_FOUND;
0031
0032 *(volatile u32 *)PCIMT_CONFIG_ADDRESS =
0033 ((busno & 0xff) << 16) |
0034 ((devfn & 0xff) << 8) |
0035 (reg & 0xfc);
0036
0037 return PCIBIOS_SUCCESSFUL;
0038 }
0039
0040 static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg,
0041 int size, u32 * val)
0042 {
0043 int res;
0044
0045 if ((res = set_config_address(bus->number, devfn, reg)))
0046 return res;
0047
0048 switch (size) {
0049 case 1:
0050 *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
0051 break;
0052 case 2:
0053 *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
0054 break;
0055 case 4:
0056 *val = inl(PCIMT_CONFIG_DATA);
0057 break;
0058 }
0059
0060 return 0;
0061 }
0062
0063 static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
0064 int size, u32 val)
0065 {
0066 int res;
0067
0068 if ((res = set_config_address(bus->number, devfn, reg)))
0069 return res;
0070
0071 switch (size) {
0072 case 1:
0073 outb(val, PCIMT_CONFIG_DATA + (reg & 3));
0074 break;
0075 case 2:
0076 outw(val, PCIMT_CONFIG_DATA + (reg & 2));
0077 break;
0078 case 4:
0079 outl(val, PCIMT_CONFIG_DATA);
0080 break;
0081 }
0082
0083 return 0;
0084 }
0085
0086 struct pci_ops sni_pcimt_ops = {
0087 .read = pcimt_read,
0088 .write = pcimt_write,
0089 };
0090
0091 static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg)
0092 {
0093 if ((devfn > 255) || (reg > 255) || (busno > 255))
0094 return PCIBIOS_BAD_REGISTER_NUMBER;
0095
0096 outl((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8);
0097 return PCIBIOS_SUCCESSFUL;
0098 }
0099
0100 static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg,
0101 int size, u32 * val)
0102 {
0103 int res;
0104
0105
0106
0107
0108
0109
0110 if (bus->number == 0) {
0111 pcit_set_config_address(0, 0, 0x68);
0112 outl(inl(0xcfc) | 0xc0000000, 0xcfc);
0113 if ((res = pcit_set_config_address(0, devfn, 0)))
0114 return res;
0115 outl(0xffffffff, 0xcfc);
0116 pcit_set_config_address(0, 0, 0x68);
0117 if (inl(0xcfc) & 0x100000)
0118 return PCIBIOS_DEVICE_NOT_FOUND;
0119 }
0120 if ((res = pcit_set_config_address(bus->number, devfn, reg)))
0121 return res;
0122
0123 switch (size) {
0124 case 1:
0125 *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
0126 break;
0127 case 2:
0128 *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
0129 break;
0130 case 4:
0131 *val = inl(PCIMT_CONFIG_DATA);
0132 break;
0133 }
0134 return 0;
0135 }
0136
0137 static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg,
0138 int size, u32 val)
0139 {
0140 int res;
0141
0142 if ((res = pcit_set_config_address(bus->number, devfn, reg)))
0143 return res;
0144
0145 switch (size) {
0146 case 1:
0147 outb(val, PCIMT_CONFIG_DATA + (reg & 3));
0148 break;
0149 case 2:
0150 outw(val, PCIMT_CONFIG_DATA + (reg & 2));
0151 break;
0152 case 4:
0153 outl(val, PCIMT_CONFIG_DATA);
0154 break;
0155 }
0156
0157 return 0;
0158 }
0159
0160
0161 struct pci_ops sni_pcit_ops = {
0162 .read = pcit_read,
0163 .write = pcit_write,
0164 };