- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / pci / iomulti.h
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
15  *
16  * Copyright (c) 2009 Isaku Yamahata
17  *                    VA Linux Systems Japan K.K.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/list.h>
22 #include <linux/pci.h>
23
24 #define PCI_NUM_BARS            6
25 #define PCI_NUM_FUNC            8
26
27 struct pci_iomul_func {
28         int             segment;
29         uint8_t         bus;
30         uint8_t         devfn;
31
32         /* only start and end are used */
33         unsigned long   io_size;
34         uint8_t         io_bar;
35         struct resource resource[PCI_NUM_BARS];
36         struct resource dummy_parent;
37 };
38
39 struct pci_iomul_switch {
40         struct list_head        list;   /* bus_list_lock protects */
41
42         /*
43          * This lock the following entry and following
44          * pci_iomul_slot/pci_iomul_func.
45          */
46         struct mutex            lock;
47         struct kref             kref;
48
49         struct resource         io_resource;
50         struct resource         *io_region;
51         unsigned int            count;
52         struct pci_dev          *current_pdev;
53
54         int                     segment;
55         uint8_t                 bus;
56
57         uint32_t                io_base;
58         uint32_t                io_limit;
59
60         /* func which has the largeset io size*/
61         struct pci_iomul_func   *func;
62
63         struct list_head        slots;
64 };
65
66 static inline void pci_iomul_switch_get(struct pci_iomul_switch *sw)
67 {
68         kref_get(&sw->kref);
69 }
70
71 static inline void pci_iomul_switch_release(struct kref *kref)
72 {
73         struct pci_iomul_switch *sw = container_of(kref,
74                                                    struct pci_iomul_switch,
75                                                    kref);
76         kfree(sw);
77 }
78
79 static inline void pci_iomul_switch_put(struct pci_iomul_switch *sw)
80 {
81         kref_put(&sw->kref, &pci_iomul_switch_release);
82 }
83
84 struct pci_iomul_slot {
85         struct list_head        sibling;
86         struct kref             kref;
87         /*
88          * busnr
89          * when pcie, the primary busnr of the PCI-PCI bridge on which
90          * this devices sits.
91          */
92         uint8_t                 switch_busnr;
93         struct resource         dummy_parent[PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES];
94
95         /* device */
96         int                     segment;
97         uint8_t                 bus;
98         uint8_t                 dev;
99
100         struct pci_iomul_func   *func[PCI_NUM_FUNC];
101 };
102
103 static inline void pci_iomul_slot_get(struct pci_iomul_slot *slot)
104 {
105         kref_get(&slot->kref);
106 }
107
108 static inline void pci_iomul_slot_release(struct kref *kref)
109 {
110         struct pci_iomul_slot *slot = container_of(kref, struct pci_iomul_slot,
111                                                    kref);
112         kfree(slot);
113 }
114
115 static inline void pci_iomul_slot_put(struct pci_iomul_slot *slot)
116 {
117         kref_put(&slot->kref, &pci_iomul_slot_release);
118 }
119
120 int pci_iomul_switch_io_allocated(const struct pci_iomul_switch *);
121 void pci_iomul_get_lock_switch(struct pci_dev *, struct pci_iomul_switch **,
122                                struct pci_iomul_slot **);