2 * PCI Backend - Handles the virtual fields in the configuration space headers.
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
7 #include <linux/kernel.h>
10 #include "conf_space.h"
18 #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
19 #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
21 static int command_read(struct pci_dev
*dev
, int offset
, u16
*value
, void *data
)
26 ret
= xen_pcibk_read_config_word(dev
, offset
, value
, data
);
27 if (!pci_is_enabled(dev
))
30 for (i
= 0; i
< PCI_ROM_RESOURCE
; i
++) {
31 if (dev
->resource
[i
].flags
& IORESOURCE_IO
)
32 *value
|= PCI_COMMAND_IO
;
33 if (dev
->resource
[i
].flags
& IORESOURCE_MEM
)
34 *value
|= PCI_COMMAND_MEMORY
;
40 static int command_write(struct pci_dev
*dev
, int offset
, u16 value
, void *data
)
42 struct xen_pcibk_dev_data
*dev_data
;
45 dev_data
= pci_get_drvdata(dev
);
46 if (!pci_is_enabled(dev
) && is_enable_cmd(value
)) {
47 if (unlikely(verbose_request
))
48 printk(KERN_DEBUG DRV_NAME
": %s: enable\n",
50 err
= pci_enable_device(dev
);
54 dev_data
->enable_intx
= 1;
55 } else if (pci_is_enabled(dev
) && !is_enable_cmd(value
)) {
56 if (unlikely(verbose_request
))
57 printk(KERN_DEBUG DRV_NAME
": %s: disable\n",
59 pci_disable_device(dev
);
61 dev_data
->enable_intx
= 0;
64 if (!dev
->is_busmaster
&& is_master_cmd(value
)) {
65 if (unlikely(verbose_request
))
66 printk(KERN_DEBUG DRV_NAME
": %s: set bus master\n",
71 if (value
& PCI_COMMAND_INVALIDATE
) {
72 if (unlikely(verbose_request
))
74 DRV_NAME
": %s: enable memory-write-invalidate\n",
76 err
= pci_set_mwi(dev
);
79 DRV_NAME
": %s: cannot enable "
80 "memory-write-invalidate (%d)\n",
82 value
&= ~PCI_COMMAND_INVALIDATE
;
86 return pci_write_config_word(dev
, offset
, value
);
89 static int rom_write(struct pci_dev
*dev
, int offset
, u32 value
, void *data
)
91 struct pci_bar_info
*bar
= data
;
94 printk(KERN_WARNING DRV_NAME
": driver data not found for %s\n",
96 return XEN_PCI_ERR_op_failed
;
99 /* A write to obtain the length must happen as a 32-bit write.
100 * This does not (yet) support writing individual bytes
102 if (value
== ~PCI_ROM_ADDRESS_ENABLE
)
106 pci_read_config_dword(dev
, offset
, &tmpval
);
107 if (tmpval
!= bar
->val
&& value
== bar
->val
) {
108 /* Allow restoration of bar value. */
109 pci_write_config_dword(dev
, offset
, bar
->val
);
114 /* Do we need to support enabling/disabling the rom address here? */
119 /* For the BARs, only allow writes which write ~0 or
120 * the correct resource information
121 * (Needed for when the driver probes the resource usage)
123 static int bar_write(struct pci_dev
*dev
, int offset
, u32 value
, void *data
)
125 struct pci_bar_info
*bar
= data
;
127 if (unlikely(!bar
)) {
128 printk(KERN_WARNING DRV_NAME
": driver data not found for %s\n",
130 return XEN_PCI_ERR_op_failed
;
133 /* A write to obtain the length must happen as a 32-bit write.
134 * This does not (yet) support writing individual bytes
140 pci_read_config_dword(dev
, offset
, &tmpval
);
141 if (tmpval
!= bar
->val
&& value
== bar
->val
) {
142 /* Allow restoration of bar value. */
143 pci_write_config_dword(dev
, offset
, bar
->val
);
151 static int bar_read(struct pci_dev
*dev
, int offset
, u32
* value
, void *data
)
153 struct pci_bar_info
*bar
= data
;
155 if (unlikely(!bar
)) {
156 printk(KERN_WARNING DRV_NAME
": driver data not found for %s\n",
158 return XEN_PCI_ERR_op_failed
;
161 *value
= bar
->which
? bar
->len_val
: bar
->val
;
166 static inline void read_dev_bar(struct pci_dev
*dev
,
167 struct pci_bar_info
*bar_info
, int offset
,
171 struct resource
*res
= dev
->resource
;
173 if (offset
== PCI_ROM_ADDRESS
|| offset
== PCI_ROM_ADDRESS1
)
174 pos
= PCI_ROM_RESOURCE
;
176 pos
= (offset
- PCI_BASE_ADDRESS_0
) / 4;
177 if (pos
&& ((res
[pos
- 1].flags
& (PCI_BASE_ADDRESS_SPACE
|
178 PCI_BASE_ADDRESS_MEM_TYPE_MASK
)) ==
179 (PCI_BASE_ADDRESS_SPACE_MEMORY
|
180 PCI_BASE_ADDRESS_MEM_TYPE_64
))) {
181 bar_info
->val
= res
[pos
- 1].start
>> 32;
182 bar_info
->len_val
= res
[pos
- 1].end
>> 32;
187 bar_info
->val
= res
[pos
].start
|
188 (res
[pos
].flags
& PCI_REGION_FLAG_MASK
);
189 bar_info
->len_val
= resource_size(&res
[pos
]);
192 static void *bar_init(struct pci_dev
*dev
, int offset
)
194 struct pci_bar_info
*bar
= kmalloc(sizeof(*bar
), GFP_KERNEL
);
197 return ERR_PTR(-ENOMEM
);
199 read_dev_bar(dev
, bar
, offset
, ~0);
205 static void *rom_init(struct pci_dev
*dev
, int offset
)
207 struct pci_bar_info
*bar
= kmalloc(sizeof(*bar
), GFP_KERNEL
);
210 return ERR_PTR(-ENOMEM
);
212 read_dev_bar(dev
, bar
, offset
, ~PCI_ROM_ADDRESS_ENABLE
);
218 static void bar_reset(struct pci_dev
*dev
, int offset
, void *data
)
220 struct pci_bar_info
*bar
= data
;
225 static void bar_release(struct pci_dev
*dev
, int offset
, void *data
)
230 static int xen_pcibk_read_vendor(struct pci_dev
*dev
, int offset
,
231 u16
*value
, void *data
)
233 *value
= dev
->vendor
;
238 static int xen_pcibk_read_device(struct pci_dev
*dev
, int offset
,
239 u16
*value
, void *data
)
241 *value
= dev
->device
;
246 static int interrupt_read(struct pci_dev
*dev
, int offset
, u8
* value
,
249 *value
= (u8
) dev
->irq
;
254 static int bist_write(struct pci_dev
*dev
, int offset
, u8 value
, void *data
)
259 err
= pci_read_config_byte(dev
, offset
, &cur_value
);
263 if ((cur_value
& ~PCI_BIST_START
) == (value
& ~PCI_BIST_START
)
264 || value
== PCI_BIST_START
)
265 err
= pci_write_config_byte(dev
, offset
, value
);
271 static const struct config_field header_common
[] = {
273 .offset
= PCI_VENDOR_ID
,
275 .u
.w
.read
= xen_pcibk_read_vendor
,
278 .offset
= PCI_DEVICE_ID
,
280 .u
.w
.read
= xen_pcibk_read_device
,
283 .offset
= PCI_COMMAND
,
285 .u
.w
.read
= command_read
,
286 .u
.w
.write
= command_write
,
289 .offset
= PCI_INTERRUPT_LINE
,
291 .u
.b
.read
= interrupt_read
,
294 .offset
= PCI_INTERRUPT_PIN
,
296 .u
.b
.read
= xen_pcibk_read_config_byte
,
299 /* Any side effects of letting driver domain control cache line? */
300 .offset
= PCI_CACHE_LINE_SIZE
,
302 .u
.b
.read
= xen_pcibk_read_config_byte
,
303 .u
.b
.write
= xen_pcibk_write_config_byte
,
306 .offset
= PCI_LATENCY_TIMER
,
308 .u
.b
.read
= xen_pcibk_read_config_byte
,
313 .u
.b
.read
= xen_pcibk_read_config_byte
,
314 .u
.b
.write
= bist_write
,
319 #define CFG_FIELD_BAR(reg_offset) \
321 .offset = reg_offset, \
324 .reset = bar_reset, \
325 .release = bar_release, \
326 .u.dw.read = bar_read, \
327 .u.dw.write = bar_write, \
330 #define CFG_FIELD_ROM(reg_offset) \
332 .offset = reg_offset, \
335 .reset = bar_reset, \
336 .release = bar_release, \
337 .u.dw.read = bar_read, \
338 .u.dw.write = rom_write, \
341 static const struct config_field header_0
[] = {
342 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0
),
343 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1
),
344 CFG_FIELD_BAR(PCI_BASE_ADDRESS_2
),
345 CFG_FIELD_BAR(PCI_BASE_ADDRESS_3
),
346 CFG_FIELD_BAR(PCI_BASE_ADDRESS_4
),
347 CFG_FIELD_BAR(PCI_BASE_ADDRESS_5
),
348 CFG_FIELD_ROM(PCI_ROM_ADDRESS
),
352 static const struct config_field header_1
[] = {
353 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0
),
354 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1
),
355 CFG_FIELD_ROM(PCI_ROM_ADDRESS1
),
359 int xen_pcibk_config_header_add_fields(struct pci_dev
*dev
)
363 err
= xen_pcibk_config_add_fields(dev
, header_common
);
367 switch (dev
->hdr_type
) {
368 case PCI_HEADER_TYPE_NORMAL
:
369 err
= xen_pcibk_config_add_fields(dev
, header_0
);
372 case PCI_HEADER_TYPE_BRIDGE
:
373 err
= xen_pcibk_config_add_fields(dev
, header_1
);
378 printk(KERN_ERR DRV_NAME
": %s: Unsupported header type %d!\n",
379 pci_name(dev
), dev
->hdr_type
);