1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2000, 2001 Keith M Wesolowski 7 */ 8#include <linux/kernel.h> 9#include <linux/init.h> 10#include <linux/pci.h> 11#include <linux/types.h> 12#include <asm/pci.h> 13#include <asm/ip32/mace.h> 14 15# define DPRINTK(args...) 16 17/* 18 * O2 has up to 5 PCI devices connected into the MACE bridge. The device 19 * map looks like this: 20 * 21 * 0 aic7xxx 0 22 * 1 aic7xxx 1 23 * 2 expansion slot 24 * 3 N/C 25 * 4 N/C 26 */ 27 28#define chkslot(_bus,_devfn) \ 29do { \ 30 if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1 \ 31 || PCI_SLOT (_devfn) > 3) \ 32 return PCIBIOS_DEVICE_NOT_FOUND; \ 33} while (0) 34 35#define mkaddr(_devfn, _reg) \ 36((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL)) 37 38static int 39mace_pci_read_config(struct pci_bus *bus, unsigned int devfn, 40 int reg, int size, u32 *val) 41{ 42 chkslot(bus, devfn); 43 mace->pci.config_addr = mkaddr(devfn, reg); 44 switch (size) { 45 case 1: 46 *val = mace->pci.config_data.b[(reg & 3) ^ 3]; 47 break; 48 case 2: 49 *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1]; 50 break; 51 case 4: 52 *val = mace->pci.config_data.l; 53 break; 54 } 55 56 DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val); 57 58 return PCIBIOS_SUCCESSFUL; 59} 60 61static int 62mace_pci_write_config(struct pci_bus *bus, unsigned int devfn, 63 int reg, int size, u32 val) 64{ 65 chkslot(bus, devfn); 66 mace->pci.config_addr = mkaddr(devfn, reg); 67 switch (size) { 68 case 1: 69 mace->pci.config_data.b[(reg & 3) ^ 3] = val; 70 break; 71 case 2: 72 mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val; 73 break; 74 case 4: 75 mace->pci.config_data.l = val; 76 break; 77 } 78 79 DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val); 80 81 return PCIBIOS_SUCCESSFUL; 82} 83 84struct pci_ops mace_pci_ops = { 85 .read = mace_pci_read_config, 86 .write = mace_pci_write_config, 87}; 88