1#include <linux/pci.h>
2#include <linux/module.h>
3#include <linux/sched.h>
4#include <linux/ioport.h>
5#include <linux/wait.h>
6
7#include "pci.h"
8
9/*
10 * This interrupt-safe spinlock protects all accesses to PCI
11 * configuration space.
12 */
13
14static DEFINE_SPINLOCK(pci_lock);
15
16/*
17 *  Wrappers for all PCI configuration access functions.  They just check
18 *  alignment, do locking and call the low-level functions pointed to
19 *  by pci_dev->ops.
20 */
21
22#define PCI_byte_BAD 0
23#define PCI_word_BAD (pos & 1)
24#define PCI_dword_BAD (pos & 3)
25
26#define PCI_OP_READ(size,type,len) \
27int pci_bus_read_config_##size \
28	(struct pci_bus *bus, unsigned int devfn, int pos, type *value)	\
29{									\
30	int res;							\
31	unsigned long flags;						\
32	u32 data = 0;							\
33	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
34	spin_lock_irqsave(&pci_lock, flags);				\
35	res = bus->ops->read(bus, devfn, pos, len, &data);		\
36	*value = (type)data;						\
37	spin_unlock_irqrestore(&pci_lock, flags);			\
38	return res;							\
39}
40
41#define PCI_OP_WRITE(size,type,len) \
42int pci_bus_write_config_##size \
43	(struct pci_bus *bus, unsigned int devfn, int pos, type value)	\
44{									\
45	int res;							\
46	unsigned long flags;						\
47	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
48	spin_lock_irqsave(&pci_lock, flags);				\
49	res = bus->ops->write(bus, devfn, pos, len, value);		\
50	spin_unlock_irqrestore(&pci_lock, flags);			\
51	return res;							\
52}
53
54PCI_OP_READ(byte, u8, 1)
55PCI_OP_READ(word, u16, 2)
56PCI_OP_READ(dword, u32, 4)
57PCI_OP_WRITE(byte, u8, 1)
58PCI_OP_WRITE(word, u16, 2)
59PCI_OP_WRITE(dword, u32, 4)
60
61EXPORT_SYMBOL(pci_bus_read_config_byte);
62EXPORT_SYMBOL(pci_bus_read_config_word);
63EXPORT_SYMBOL(pci_bus_read_config_dword);
64EXPORT_SYMBOL(pci_bus_write_config_byte);
65EXPORT_SYMBOL(pci_bus_write_config_word);
66EXPORT_SYMBOL(pci_bus_write_config_dword);
67
68/*
69 * The following routines are to prevent the user from accessing PCI config
70 * space when it's unsafe to do so.  Some devices require this during BIST and
71 * we're required to prevent it during D-state transitions.
72 *
73 * We have a bit per device to indicate it's blocked and a global wait queue
74 * for callers to sleep on until devices are unblocked.
75 */
76static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait);
77
78static noinline void pci_wait_ucfg(struct pci_dev *dev)
79{
80	DECLARE_WAITQUEUE(wait, current);
81
82	__add_wait_queue(&pci_ucfg_wait, &wait);
83	do {
84		set_current_state(TASK_UNINTERRUPTIBLE);
85		spin_unlock_irq(&pci_lock);
86		schedule();
87		spin_lock_irq(&pci_lock);
88	} while (dev->block_ucfg_access);
89	__remove_wait_queue(&pci_ucfg_wait, &wait);
90}
91
92#define PCI_USER_READ_CONFIG(size,type)					\
93int pci_user_read_config_##size						\
94	(struct pci_dev *dev, int pos, type *val)			\
95{									\
96	int ret = 0;							\
97	u32 data = -1;							\
98	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
99	spin_lock_irq(&pci_lock);					\
100	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\
101	ret = dev->bus->ops->read(dev->bus, dev->devfn,			\
102					pos, sizeof(type), &data);	\
103	spin_unlock_irq(&pci_lock);					\
104	*val = (type)data;						\
105	return ret;							\
106}
107
108#define PCI_USER_WRITE_CONFIG(size,type)				\
109int pci_user_write_config_##size					\
110	(struct pci_dev *dev, int pos, type val)			\
111{									\
112	int ret = -EIO;							\
113	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
114	spin_lock_irq(&pci_lock);					\
115	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\
116	ret = dev->bus->ops->write(dev->bus, dev->devfn,		\
117					pos, sizeof(type), val);	\
118	spin_unlock_irq(&pci_lock);					\
119	return ret;							\
120}
121
122PCI_USER_READ_CONFIG(byte, u8)
123PCI_USER_READ_CONFIG(word, u16)
124PCI_USER_READ_CONFIG(dword, u32)
125PCI_USER_WRITE_CONFIG(byte, u8)
126PCI_USER_WRITE_CONFIG(word, u16)
127PCI_USER_WRITE_CONFIG(dword, u32)
128
129/**
130 * pci_block_user_cfg_access - Block userspace PCI config reads/writes
131 * @dev:	pci device struct
132 *
133 * When user access is blocked, any reads or writes to config space will
134 * sleep until access is unblocked again.  We don't allow nesting of
135 * block/unblock calls.
136 */
137void pci_block_user_cfg_access(struct pci_dev *dev)
138{
139	unsigned long flags;
140	int was_blocked;
141
142	spin_lock_irqsave(&pci_lock, flags);
143	was_blocked = dev->block_ucfg_access;
144	dev->block_ucfg_access = 1;
145	spin_unlock_irqrestore(&pci_lock, flags);
146
147	/* If we BUG() inside the pci_lock, we're guaranteed to hose
148	 * the machine */
149	BUG_ON(was_blocked);
150}
151EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
152
153/**
154 * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
155 * @dev:	pci device struct
156 *
157 * This function allows userspace PCI config accesses to resume.
158 */
159void pci_unblock_user_cfg_access(struct pci_dev *dev)
160{
161	unsigned long flags;
162
163	spin_lock_irqsave(&pci_lock, flags);
164
165	/* This indicates a problem in the caller, but we don't need
166	 * to kill them, unlike a double-block above. */
167	WARN_ON(!dev->block_ucfg_access);
168
169	dev->block_ucfg_access = 0;
170	wake_up_all(&pci_ucfg_wait);
171	spin_unlock_irqrestore(&pci_lock, flags);
172}
173EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
174