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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BRIEF MODULE DESCRIPTION
  3.  * Pb1500 specific pci support.
  4.  *
  5.  * Copyright 2001,2002 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/pb1500.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. /* TBD */
  47. static struct resource pci_io_resource = {
  48. "pci IO space",
  49. Au1500_PCI_IO_START,
  50. Au1500_PCI_IO_END,
  51. IORESOURCE_IO
  52. };
  53. static struct resource pci_mem_resource = {
  54. "pci memory space",
  55. Au1500_PCI_MEM_START,
  56. Au1500_PCI_MEM_END,
  57. IORESOURCE_MEM
  58. };
  59. extern struct pci_ops pb1500_pci_ops;
  60. struct pci_channel mips_pci_channels[] = {
  61. {&pb1500_pci_ops, &pci_io_resource, &pci_mem_resource, (10<<3),(16<<3)},
  62. {(struct pci_ops *) NULL, (struct resource *) NULL,
  63.  (struct resource *) NULL, (int) NULL, (int) NULL}
  64. };
  65. static unsigned long cfg_addr;
  66. static int config_access(unsigned char access_type, struct pci_dev *dev,
  67.  unsigned char where, u32 * data)
  68. {
  69. unsigned char bus = dev->bus->number;
  70. unsigned int dev_fn = dev->devfn;
  71. unsigned int device, function;
  72. unsigned long config, status;
  73. static int first = 1;
  74. /*
  75.    * 7:3 = slot
  76.    * 2:0 = function
  77.  */
  78. if (bus != 0) {
  79. *data = 0xffffffff;
  80. return -1;
  81. }
  82. if (first) {
  83. first = 0;
  84. cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000);
  85. if (!cfg_addr)
  86. printk (KERN_ERR "PCI unable to ioremap cfg spacen");
  87. }
  88. device = (dev_fn >> 3) & 0x1f;
  89. function = dev_fn & 0x7;
  90. #if 1
  91. //if (!cfg_addr || (device < 10) || (device > 16)) {
  92. if (!cfg_addr || (device > 16)) {
  93. *data = 0xffffffff;
  94. return -1;
  95. }
  96. #endif
  97. au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
  98. Au1500_PCI_STATCMD);
  99. //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
  100. au_sync_udelay(1);
  101. /* setup the lower 31 bits of the 36 bit address */
  102. config = cfg_addr |
  103. ((1<<device)<<11) | (function << 8) | (where & ~0x3);
  104. #if 0
  105. printk("cfg access: config %x, dev_fn %x, device %x function %xn",
  106. config, dev_fn, device, function);
  107. #endif
  108. if (access_type == PCI_ACCESS_WRITE) {
  109. au_writel(*data, config);
  110. } else {
  111. *data = au_readl(config);
  112. }
  113. au_sync_udelay(1);
  114. DBG("config_access: %d bus %d device %d at %x *data %x, conf %xn",
  115. access_type, bus, device, where, *data, config);
  116. /* check master abort */
  117. status = au_readl(Au1500_PCI_STATCMD);
  118. if (status & (1<<29)) {
  119. *data = 0xffffffff;
  120. return -1;
  121. } else if ((status >> 28) & 0xf) {
  122. DBG("PCI ERR detected: status %xn", status);
  123. *data = 0xffffffff;
  124. return -1;
  125. }
  126. else {
  127. return PCIBIOS_SUCCESSFUL;
  128. }
  129. }
  130. static int read_config_byte(struct pci_dev *dev, int where, u8 * val)
  131. {
  132. u32 data;
  133. int ret;
  134. ret = config_access(PCI_ACCESS_READ, dev, where, &data);
  135.         if (where & 1) data >>= 8;
  136.         if (where & 2) data >>= 16;
  137.         *val = data & 0xff;
  138. return ret;
  139. }
  140. static int read_config_word(struct pci_dev *dev, int where, u16 * val)
  141. {
  142. u32 data;
  143. int ret;
  144. ret = config_access(PCI_ACCESS_READ, dev, where, &data);
  145.         if (where & 2) data >>= 16;
  146.         *val = data & 0xffff;
  147. return ret;
  148. }
  149. static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
  150. {
  151. int ret;
  152. ret = config_access(PCI_ACCESS_READ, dev, where, val);
  153. return ret;
  154. }
  155. static int write_config_byte(struct pci_dev *dev, int where, u8 val)
  156. {
  157. u32 data = 0;
  158. if (config_access(PCI_ACCESS_READ, dev, where, &data))
  159. return -1;
  160. data = (data & ~(0xff << ((where & 3) << 3))) |
  161.        (val << ((where & 3) << 3));
  162. if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
  163. return -1;
  164. return PCIBIOS_SUCCESSFUL;
  165. }
  166. static int write_config_word(struct pci_dev *dev, int where, u16 val)
  167. {
  168.         u32 data = 0;
  169. if (where & 1)
  170. return PCIBIOS_BAD_REGISTER_NUMBER;
  171.         if (config_access(PCI_ACCESS_READ, dev, where, &data))
  172.        return -1;
  173. data = (data & ~(0xffff << ((where & 3) << 3))) |
  174.        (val << ((where & 3) << 3));
  175. if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
  176.        return -1;
  177. return PCIBIOS_SUCCESSFUL;
  178. }
  179. static int write_config_dword(struct pci_dev *dev, int where, u32 val)
  180. {
  181. if (where & 3)
  182. return PCIBIOS_BAD_REGISTER_NUMBER;
  183. if (config_access(PCI_ACCESS_WRITE, dev, where, &val))
  184.        return -1;
  185. return PCIBIOS_SUCCESSFUL;
  186. }
  187. struct pci_ops pb1500_pci_ops = {
  188. read_config_byte,
  189.         read_config_word,
  190. read_config_dword,
  191. write_config_byte,
  192. write_config_word,
  193. write_config_dword
  194. };
  195. #endif /* CONFIG_PCI */