xref: /openbmc/linux/drivers/pci/access.c (revision d5cb9783536a41df9f9cba5b0a1d78047ed787f7)
1 #include <linux/pci.h>
2 #include <linux/module.h>
3 #include <linux/ioport.h>
4 
5 /*
6  * This interrupt-safe spinlock protects all accesses to PCI
7  * configuration space.
8  */
9 
10 static DEFINE_SPINLOCK(pci_lock);
11 
12 /*
13  *  Wrappers for all PCI configuration access functions.  They just check
14  *  alignment, do locking and call the low-level functions pointed to
15  *  by pci_dev->ops.
16  */
17 
18 #define PCI_byte_BAD 0
19 #define PCI_word_BAD (pos & 1)
20 #define PCI_dword_BAD (pos & 3)
21 
22 #define PCI_OP_READ(size,type,len) \
23 int pci_bus_read_config_##size \
24 	(struct pci_bus *bus, unsigned int devfn, int pos, type *value)	\
25 {									\
26 	int res;							\
27 	unsigned long flags;						\
28 	u32 data = 0;							\
29 	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
30 	spin_lock_irqsave(&pci_lock, flags);				\
31 	res = bus->ops->read(bus, devfn, pos, len, &data);		\
32 	*value = (type)data;						\
33 	spin_unlock_irqrestore(&pci_lock, flags);			\
34 	return res;							\
35 }
36 
37 #define PCI_OP_WRITE(size,type,len) \
38 int pci_bus_write_config_##size \
39 	(struct pci_bus *bus, unsigned int devfn, int pos, type value)	\
40 {									\
41 	int res;							\
42 	unsigned long flags;						\
43 	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
44 	spin_lock_irqsave(&pci_lock, flags);				\
45 	res = bus->ops->write(bus, devfn, pos, len, value);		\
46 	spin_unlock_irqrestore(&pci_lock, flags);			\
47 	return res;							\
48 }
49 
50 PCI_OP_READ(byte, u8, 1)
51 PCI_OP_READ(word, u16, 2)
52 PCI_OP_READ(dword, u32, 4)
53 PCI_OP_WRITE(byte, u8, 1)
54 PCI_OP_WRITE(word, u16, 2)
55 PCI_OP_WRITE(dword, u32, 4)
56 
57 EXPORT_SYMBOL(pci_bus_read_config_byte);
58 EXPORT_SYMBOL(pci_bus_read_config_word);
59 EXPORT_SYMBOL(pci_bus_read_config_dword);
60 EXPORT_SYMBOL(pci_bus_write_config_byte);
61 EXPORT_SYMBOL(pci_bus_write_config_word);
62 EXPORT_SYMBOL(pci_bus_write_config_dword);
63 
64 static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
65 {
66 	u32 data;
67 
68 	data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
69 	data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
70 	return data;
71 }
72 
73 #define PCI_USER_READ_CONFIG(size,type)					\
74 int pci_user_read_config_##size						\
75 	(struct pci_dev *dev, int pos, type *val)			\
76 {									\
77 	unsigned long flags;						\
78 	int ret = 0;							\
79 	u32 data = -1;							\
80 	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
81 	spin_lock_irqsave(&pci_lock, flags);				\
82 	if (likely(!dev->block_ucfg_access))				\
83 		ret = dev->bus->ops->read(dev->bus, dev->devfn,		\
84 					pos, sizeof(type), &data);	\
85 	else if (pos < sizeof(dev->saved_config_space))			\
86 		data = pci_user_cached_config(dev, pos); 		\
87 	spin_unlock_irqrestore(&pci_lock, flags);			\
88 	*val = (type)data;						\
89 	return ret;							\
90 }
91 
92 #define PCI_USER_WRITE_CONFIG(size,type)				\
93 int pci_user_write_config_##size					\
94 	(struct pci_dev *dev, int pos, type val)			\
95 {									\
96 	unsigned long flags;						\
97 	int ret = -EIO;							\
98 	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
99 	spin_lock_irqsave(&pci_lock, flags);				\
100 	if (likely(!dev->block_ucfg_access))				\
101 		ret = dev->bus->ops->write(dev->bus, dev->devfn,	\
102 					pos, sizeof(type), val);	\
103 	spin_unlock_irqrestore(&pci_lock, flags);			\
104 	return ret;							\
105 }
106 
107 PCI_USER_READ_CONFIG(byte, u8)
108 PCI_USER_READ_CONFIG(word, u16)
109 PCI_USER_READ_CONFIG(dword, u32)
110 PCI_USER_WRITE_CONFIG(byte, u8)
111 PCI_USER_WRITE_CONFIG(word, u16)
112 PCI_USER_WRITE_CONFIG(dword, u32)
113 
114 /**
115  * pci_block_user_cfg_access - Block userspace PCI config reads/writes
116  * @dev:	pci device struct
117  *
118  * This function blocks any userspace PCI config accesses from occurring.
119  * When blocked, any writes will be bit bucketed and reads will return the
120  * data saved using pci_save_state for the first 64 bytes of config
121  * space and return 0xff for all other config reads.
122  **/
123 void pci_block_user_cfg_access(struct pci_dev *dev)
124 {
125 	unsigned long flags;
126 
127 	pci_save_state(dev);
128 
129 	/* spinlock to synchronize with anyone reading config space now */
130 	spin_lock_irqsave(&pci_lock, flags);
131 	dev->block_ucfg_access = 1;
132 	spin_unlock_irqrestore(&pci_lock, flags);
133 }
134 EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
135 
136 /**
137  * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
138  * @dev:	pci device struct
139  *
140  * This function allows userspace PCI config accesses to resume.
141  **/
142 void pci_unblock_user_cfg_access(struct pci_dev *dev)
143 {
144 	unsigned long flags;
145 
146 	/* spinlock to synchronize with anyone reading saved config space */
147 	spin_lock_irqsave(&pci_lock, flags);
148 	dev->block_ucfg_access = 0;
149 	spin_unlock_irqrestore(&pci_lock, flags);
150 }
151 EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
152