pci_ops.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BRIEF MODULE DESCRIPTION
  3.  * PB1000 specific pci support.
  4.  *
  5.  * Copyright 2001 MontaVista Software Inc.
  6.  * Author: MontaVista Software, Inc.
  7.  *          ppopov@mvista.com or source@mvista.com
  8.  *
  9.  *  This program is free software; you can redistribute  it and/or modify it
  10.  *  under  the terms of  the GNU General  Public License as published by the
  11.  *  Free Software Foundation;  either version 2 of the  License, or (at your
  12.  *  option) any later version.
  13.  *
  14.  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  15.  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  16.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  17.  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  18.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19.  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  20.  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21.  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  22.  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23.  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24.  *
  25.  *  You should have received a copy of the  GNU General Public License along
  26.  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  27.  *  675 Mass Ave, Cambridge, MA 02139, USA.
  28.  */
  29. #include <linux/config.h>
  30. #ifdef CONFIG_PCI
  31. #include <linux/types.h>
  32. #include <linux/pci.h>
  33. #include <linux/kernel.h>
  34. #include <linux/init.h>
  35. #include <asm/au1000.h>
  36. #include <asm/pb1000.h>
  37. #include <asm/pci_channel.h>
  38. #define PCI_ACCESS_READ  0
  39. #define PCI_ACCESS_WRITE 1
  40. #undef DEBUG
  41. #ifdef  DEBUG
  42. #define DBG(x...) printk(x)
  43. #else
  44. #define DBG(x...)
  45. #endif
  46. static struct resource pci_io_resource = {
  47. "pci IO space",
  48. PCI_IO_START,
  49. PCI_IO_END,
  50. IORESOURCE_IO
  51. };
  52. static struct resource pci_mem_resource = {
  53. "pci memory space",
  54. PCI_MEM_START,
  55. PCI_MEM_END,
  56. IORESOURCE_MEM
  57. };
  58. extern struct pci_ops pb1000_pci_ops;
  59. struct pci_channel mips_pci_channels[] = {
  60. {&pb1000_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 1},
  61. {(struct pci_ops *) NULL, (struct resource *) NULL,
  62.  (struct resource *) NULL, (int) NULL, (int) NULL}
  63. };
  64. /*
  65.  * "Bus 2" is really the first and only external slot on the pb1000.
  66.  * We'll call that bus 0, and limit the accesses to that single
  67.  * external slot only. The SDRAM is already initialized in setup.c.
  68.  */
  69. static int config_access(unsigned char access_type, struct pci_dev *dev,
  70.  unsigned char where, u32 * data)
  71. {
  72. unsigned char bus = dev->bus->number;
  73. unsigned char dev_fn = dev->devfn;
  74. unsigned long config;
  75. if (((dev_fn >> 3) != 0) || (bus != 0)) {
  76. *data = 0xffffffff;
  77. return -1;
  78. }
  79. config = PCI_CONFIG_BASE | (where & ~0x3);
  80. if (access_type == PCI_ACCESS_WRITE) {
  81. au_writel(*data, config);
  82. } else {
  83. *data = au_readl(config);
  84. }
  85. au_sync_udelay(1);
  86. DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %xn",
  87. access_type, bus, dev_fn, where, *data, config);
  88. DBG("bridge config reg: %x (%x)n", au_readl(PCI_BRIDGE_CONFIG), *data);
  89. if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
  90. *data = 0xffffffff;
  91. return -1;
  92. } else {
  93. return PCIBIOS_SUCCESSFUL;
  94. }
  95. }
  96. static int read_config_byte(struct pci_dev *dev, int where, u8 * val)
  97. {
  98. u32 data;
  99. int ret;
  100. ret = config_access(PCI_ACCESS_READ, dev, where, &data);
  101. *val = data & 0xff;
  102. return ret;
  103. }
  104. static int read_config_word(struct pci_dev *dev, int where, u16 * val)
  105. {
  106. u32 data;
  107. int ret;
  108. ret = config_access(PCI_ACCESS_READ, dev, where, &data);
  109. *val = data & 0xffff;
  110. return ret;
  111. }
  112. static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
  113. {
  114. int ret;
  115. ret = config_access(PCI_ACCESS_READ, dev, where, val);
  116. return ret;
  117. }
  118. static int write_config_byte(struct pci_dev *dev, int where, u8 val)
  119. {
  120. u32 data = 0;
  121. if (config_access(PCI_ACCESS_READ, dev, where, &data))
  122. return -1;
  123. data = (data & ~(0xff << ((where & 3) << 3))) |
  124.        (val << ((where & 3) << 3));
  125. if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
  126. return -1;
  127. return PCIBIOS_SUCCESSFUL;
  128. }
  129. static int write_config_word(struct pci_dev *dev, int where, u16 val)
  130. {
  131.         u32 data = 0;
  132. if (where & 1)
  133. return PCIBIOS_BAD_REGISTER_NUMBER;
  134.         if (config_access(PCI_ACCESS_READ, dev, where, &data))
  135.        return -1;
  136. data = (data & ~(0xffff << ((where & 3) << 3))) |
  137.        (val << ((where & 3) << 3));
  138. if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
  139.        return -1;
  140. return PCIBIOS_SUCCESSFUL;
  141. }
  142. static int write_config_dword(struct pci_dev *dev, int where, u32 val)
  143. {
  144. if (where & 3)
  145. return PCIBIOS_BAD_REGISTER_NUMBER;
  146. if (config_access(PCI_ACCESS_WRITE, dev, where, &val))
  147.        return -1;
  148. return PCIBIOS_SUCCESSFUL;
  149. }
  150. struct pci_ops pb1000_pci_ops = {
  151. read_config_byte,
  152.         read_config_word,
  153. read_config_dword,
  154. write_config_byte,
  155. write_config_word,
  156. write_config_dword
  157. };
  158. #endif /* CONFIG_PCI */