1 /* $Id: pci_impl.h,v 1.9 2001/06/13 06:34:30 davem Exp $
2  * pci_impl.h: Helper definitions for PCI controller support.
3  *
4  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5  */
6 
7 #ifndef PCI_IMPL_H
8 #define PCI_IMPL_H
9 
10 #include <linux/types.h>
11 #include <linux/spinlock.h>
12 #include <asm/io.h>
13 
14 extern spinlock_t pci_controller_lock;
15 extern struct pci_controller_info *pci_controller_root;
16 
17 extern struct pci_pbm_info *pci_bus2pbm[256];
18 extern unsigned char pci_highest_busnum;
19 extern int pci_num_controllers;
20 
21 /* PCI bus scanning and fixup support. */
22 extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
23 extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
24 				    struct pci_pbm_info *pbm,
25 				    int prom_node);
26 extern void pci_record_assignments(struct pci_pbm_info *pbm,
27 				   struct pci_bus *pbus);
28 extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
29 				  struct pci_bus *pbus);
30 extern void pci_fixup_irq(struct pci_pbm_info *pbm,
31 			  struct pci_bus *pbus);
32 extern void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm,
33 					    struct pci_bus *pbus);
34 extern void pci_setup_busmastering(struct pci_pbm_info *pbm,
35 				   struct pci_bus *pbus);
36 extern void pci_register_legacy_regions(struct resource *io_res,
37 					struct resource *mem_res);
38 
39 /* Error reporting support. */
40 extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
41 extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
42 extern void pci_scan_for_parity_error(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *);
43 
44 /* Configuration space access. */
45 extern spinlock_t pci_poke_lock;
46 extern volatile int pci_poke_in_progress;
47 extern volatile int pci_poke_cpu;
48 extern volatile int pci_poke_faulted;
49 
pci_config_read8(u8 * addr,u8 * ret)50 static __inline__ void pci_config_read8(u8 *addr, u8 *ret)
51 {
52 	unsigned long flags;
53 	u8 byte;
54 
55 	spin_lock_irqsave(&pci_poke_lock, flags);
56 	pci_poke_cpu = smp_processor_id();
57 	pci_poke_in_progress = 1;
58 	pci_poke_faulted = 0;
59 	__asm__ __volatile__("membar #Sync\n\t"
60 			     "lduba [%1] %2, %0\n\t"
61 			     "membar #Sync"
62 			     : "=r" (byte)
63 			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
64 			     : "memory");
65 	pci_poke_in_progress = 0;
66 	pci_poke_cpu = -1;
67 	if (!pci_poke_faulted)
68 		*ret = byte;
69 	spin_unlock_irqrestore(&pci_poke_lock, flags);
70 }
71 
pci_config_read16(u16 * addr,u16 * ret)72 static __inline__ void pci_config_read16(u16 *addr, u16 *ret)
73 {
74 	unsigned long flags;
75 	u16 word;
76 
77 	spin_lock_irqsave(&pci_poke_lock, flags);
78 	pci_poke_cpu = smp_processor_id();
79 	pci_poke_in_progress = 1;
80 	pci_poke_faulted = 0;
81 	__asm__ __volatile__("membar #Sync\n\t"
82 			     "lduha [%1] %2, %0\n\t"
83 			     "membar #Sync"
84 			     : "=r" (word)
85 			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
86 			     : "memory");
87 	pci_poke_in_progress = 0;
88 	pci_poke_cpu = -1;
89 	if (!pci_poke_faulted)
90 		*ret = word;
91 	spin_unlock_irqrestore(&pci_poke_lock, flags);
92 }
93 
pci_config_read32(u32 * addr,u32 * ret)94 static __inline__ void pci_config_read32(u32 *addr, u32 *ret)
95 {
96 	unsigned long flags;
97 	u32 dword;
98 
99 	spin_lock_irqsave(&pci_poke_lock, flags);
100 	pci_poke_cpu = smp_processor_id();
101 	pci_poke_in_progress = 1;
102 	pci_poke_faulted = 0;
103 	__asm__ __volatile__("membar #Sync\n\t"
104 			     "lduwa [%1] %2, %0\n\t"
105 			     "membar #Sync"
106 			     : "=r" (dword)
107 			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
108 			     : "memory");
109 	pci_poke_in_progress = 0;
110 	pci_poke_cpu = -1;
111 	if (!pci_poke_faulted)
112 		*ret = dword;
113 	spin_unlock_irqrestore(&pci_poke_lock, flags);
114 }
115 
pci_config_write8(u8 * addr,u8 val)116 static __inline__ void pci_config_write8(u8 *addr, u8 val)
117 {
118 	unsigned long flags;
119 
120 	spin_lock_irqsave(&pci_poke_lock, flags);
121 	pci_poke_cpu = smp_processor_id();
122 	pci_poke_in_progress = 1;
123 	pci_poke_faulted = 0;
124 	__asm__ __volatile__("membar #Sync\n\t"
125 			     "stba %0, [%1] %2\n\t"
126 			     "membar #Sync"
127 			     : /* no outputs */
128 			     : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
129 			     : "memory");
130 	pci_poke_in_progress = 0;
131 	pci_poke_cpu = -1;
132 	spin_unlock_irqrestore(&pci_poke_lock, flags);
133 }
134 
pci_config_write16(u16 * addr,u16 val)135 static __inline__ void pci_config_write16(u16 *addr, u16 val)
136 {
137 	unsigned long flags;
138 
139 	spin_lock_irqsave(&pci_poke_lock, flags);
140 	pci_poke_cpu = smp_processor_id();
141 	pci_poke_in_progress = 1;
142 	pci_poke_faulted = 0;
143 	__asm__ __volatile__("membar #Sync\n\t"
144 			     "stha %0, [%1] %2\n\t"
145 			     "membar #Sync"
146 			     : /* no outputs */
147 			     : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
148 			     : "memory");
149 	pci_poke_in_progress = 0;
150 	pci_poke_cpu = -1;
151 	spin_unlock_irqrestore(&pci_poke_lock, flags);
152 }
153 
pci_config_write32(u32 * addr,u32 val)154 static __inline__ void pci_config_write32(u32 *addr, u32 val)
155 {
156 	unsigned long flags;
157 
158 	spin_lock_irqsave(&pci_poke_lock, flags);
159 	pci_poke_cpu = smp_processor_id();
160 	pci_poke_in_progress = 1;
161 	pci_poke_faulted = 0;
162 	__asm__ __volatile__("membar #Sync\n\t"
163 			     "stwa %0, [%1] %2\n\t"
164 			     "membar #Sync"
165 			     : /* no outputs */
166 			     : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
167 			     : "memory");
168 	pci_poke_in_progress = 0;
169 	pci_poke_cpu = -1;
170 	spin_unlock_irqrestore(&pci_poke_lock, flags);
171 }
172 
173 #endif /* !(PCI_IMPL_H) */
174