This commit was generated by cvs2svn to compensate for changes in r925,
[linux-2.6.git] / arch / xen / i386 / pci / direct.c
1 /*
2  * direct.c - Low-level direct PCI config space access
3  */
4
5 #include <linux/pci.h>
6 #include <linux/init.h>
7 #include "pci.h"
8
9 #include <asm-xen/xen-public/xen.h>
10 #include <asm-xen/xen-public/physdev.h>
11
12 /*
13  * Functions for accessing PCI configuration space with type xen accesses
14  */
15
16 static int pci_conf_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
17 {
18         unsigned long flags;
19         physdev_op_t op;
20         int ret;
21
22         if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
23                 return -EINVAL;
24
25         spin_lock_irqsave(&pci_config_lock, flags);
26
27         op.cmd = PHYSDEVOP_PCI_CFGREG_READ;
28         op.u.pci_cfgreg_read.bus  = bus;
29         op.u.pci_cfgreg_read.dev  = (devfn & ~0x7) >> 3;
30         op.u.pci_cfgreg_read.func = devfn & 0x7;
31         op.u.pci_cfgreg_read.reg  = reg;
32         op.u.pci_cfgreg_read.len  = len;
33
34         ret = HYPERVISOR_physdev_op(&op);
35         if (ret == 0)
36                 *value = op.u.pci_cfgreg_read.value;
37
38         spin_unlock_irqrestore(&pci_config_lock, flags);
39
40         return ret;
41 }
42
43 static int pci_conf_write (int seg, int bus, int devfn, int reg, int len, u32 value)
44 {
45         unsigned long flags;
46         physdev_op_t op;
47         int ret;
48
49         if ((bus > 255) || (devfn > 255) || (reg > 255)) 
50                 return -EINVAL;
51
52         spin_lock_irqsave(&pci_config_lock, flags);
53
54         op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE;
55         op.u.pci_cfgreg_write.bus   = bus;
56         op.u.pci_cfgreg_write.dev   = (devfn & ~0x7) >> 3;
57         op.u.pci_cfgreg_write.func  = devfn & 0x7;
58         op.u.pci_cfgreg_write.reg   = reg;
59         op.u.pci_cfgreg_write.len   = len;
60         op.u.pci_cfgreg_write.value = value;
61
62         ret = HYPERVISOR_physdev_op(&op);
63
64         spin_unlock_irqrestore(&pci_config_lock, flags);
65
66         return ret;
67 }
68
69 struct pci_raw_ops pci_direct_xen = {
70         .read =         pci_conf_read,
71         .write =        pci_conf_write,
72 };
73
74 static int __init pci_direct_init(void)
75 {
76         printk(KERN_INFO "PCI: Using configuration type Xen\n");
77         raw_pci_ops = &pci_direct_xen;
78         return 0;
79 }
80
81 arch_initcall(pci_direct_init);