Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2000, 2001 Keith M Wesolowski
0007  */
0008 #include <linux/kernel.h>
0009 #include <linux/pci.h>
0010 #include <linux/types.h>
0011 #include <asm/ip32/mace.h>
0012 
0013 #if 0
0014 # define DPRINTK(args...) printk(args);
0015 #else
0016 # define DPRINTK(args...)
0017 #endif
0018 
0019 /*
0020  * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
0021  * map looks like this:
0022  *
0023  * 0  aic7xxx 0
0024  * 1  aic7xxx 1
0025  * 2  expansion slot
0026  * 3  N/C
0027  * 4  N/C
0028  */
0029 
0030 static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
0031     unsigned int reg)
0032 {
0033     return ((bus->number & 0xff) << 16) |
0034         ((devfn & 0xff) << 8) |
0035         (reg & 0xfc);
0036 }
0037 
0038 
0039 static int
0040 mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
0041              int reg, int size, u32 *val)
0042 {
0043     u32 control = mace->pci.control;
0044 
0045     /* disable master aborts interrupts during config read */
0046     mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
0047     mace->pci.config_addr = mkaddr(bus, devfn, reg);
0048     switch (size) {
0049     case 1:
0050         *val = mace->pci.config_data.b[(reg & 3) ^ 3];
0051         break;
0052     case 2:
0053         *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
0054         break;
0055     case 4:
0056         *val = mace->pci.config_data.l;
0057         break;
0058     }
0059     /* ack possible master abort */
0060     mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
0061     mace->pci.control = control;
0062     /*
0063      * someone forgot to set the ultra bit for the onboard
0064      * scsi chips; we fake it here
0065      */
0066     if (bus->number == 0 && reg == 0x40 && size == 4 &&
0067         (devfn == (1 << 3) || devfn == (2 << 3)))
0068         *val |= 0x1000;
0069 
0070     DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
0071 
0072     return PCIBIOS_SUCCESSFUL;
0073 }
0074 
0075 static int
0076 mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
0077               int reg, int size, u32 val)
0078 {
0079     mace->pci.config_addr = mkaddr(bus, devfn, reg);
0080     switch (size) {
0081     case 1:
0082         mace->pci.config_data.b[(reg & 3) ^ 3] = val;
0083         break;
0084     case 2:
0085         mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
0086         break;
0087     case 4:
0088         mace->pci.config_data.l = val;
0089         break;
0090     }
0091 
0092     DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
0093 
0094     return PCIBIOS_SUCCESSFUL;
0095 }
0096 
0097 struct pci_ops mace_pci_ops = {
0098     .read = mace_pci_read_config,
0099     .write = mace_pci_write_config,
0100 };