Staging: comedi: drivers: fix coding style issues in pcl812.c
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / icp_multi.h
CommitLineData
96341f71
AS
1/*
2 comedi/drivers/icp_multi.h
3
4 Stuff for ICP Multi
5
6 Author: Anne Smorthit <anne.smorthit@sfwte.ch>
7
8*/
9
10#ifndef _ICP_MULTI_H_
11#define _ICP_MULTI_H_
12
13#include "../comedidev.h"
14#include "comedi_pci.h"
15
16/****************************************************************************/
17
18struct pcilst_struct {
19 struct pcilst_struct *next;
20 int used;
21 struct pci_dev *pcidev;
22 unsigned short vendor;
23 unsigned short device;
24 unsigned char pci_bus;
25 unsigned char pci_slot;
26 unsigned char pci_func;
27 resource_size_t io_addr[5];
28 unsigned int irq;
29};
30
b6c77757
BP
31struct pcilst_struct *inova_devices;
32/* ptr to root list of all Inova devices */
96341f71
AS
33
34/****************************************************************************/
35
36static void pci_card_list_init(unsigned short pci_vendor, char display);
37static void pci_card_list_cleanup(unsigned short pci_vendor);
38static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
0a85b6f0
MT
39 vendor_id,
40 unsigned short
41 device_id);
96341f71 42static int find_free_pci_card_by_position(unsigned short vendor_id,
0a85b6f0
MT
43 unsigned short device_id,
44 unsigned short pci_bus,
45 unsigned short pci_slot,
46 struct pcilst_struct **card);
96341f71 47static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
0a85b6f0
MT
48 unsigned short device_id,
49 unsigned short pci_bus,
50 unsigned short pci_slot);
96341f71
AS
51
52static int pci_card_alloc(struct pcilst_struct *amcc);
53static int pci_card_free(struct pcilst_struct *amcc);
54static void pci_card_list_display(void);
55static int pci_card_data(struct pcilst_struct *amcc,
0a85b6f0
MT
56 unsigned char *pci_bus, unsigned char *pci_slot,
57 unsigned char *pci_func, resource_size_t * io_addr,
58 unsigned int *irq);
96341f71
AS
59
60/****************************************************************************/
61
62/* build list of Inova cards in this system */
63static void pci_card_list_init(unsigned short pci_vendor, char display)
64{
65 struct pci_dev *pcidev;
66 struct pcilst_struct *inova, *last;
67 int i;
68
69 inova_devices = NULL;
70 last = NULL;
71
72 for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
0a85b6f0
MT
73 pcidev != NULL;
74 pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
96341f71 75 if (pcidev->vendor == pci_vendor) {
7a6cb0d5 76 inova = kzalloc(sizeof(*inova), GFP_KERNEL);
96341f71 77 if (!inova) {
0a85b6f0
MT
78 printk
79 ("icp_multi: pci_card_list_init: allocation failed\n");
96341f71
AS
80 pci_dev_put(pcidev);
81 break;
82 }
96341f71
AS
83
84 inova->pcidev = pci_dev_get(pcidev);
85 if (last) {
86 last->next = inova;
87 } else {
88 inova_devices = inova;
89 }
90 last = inova;
91
92 inova->vendor = pcidev->vendor;
93 inova->device = pcidev->device;
94 inova->pci_bus = pcidev->bus->number;
95 inova->pci_slot = PCI_SLOT(pcidev->devfn);
96 inova->pci_func = PCI_FUNC(pcidev->devfn);
97 /* Note: resources may be invalid if PCI device
98 * not enabled, but they are corrected in
99 * pci_card_alloc. */
100 for (i = 0; i < 5; i++)
101 inova->io_addr[i] =
0a85b6f0 102 pci_resource_start(pcidev, i);
96341f71
AS
103 inova->irq = pcidev->irq;
104 }
105 }
106
107 if (display)
108 pci_card_list_display();
109}
110
111/****************************************************************************/
112/* free up list of amcc cards in this system */
113static void pci_card_list_cleanup(unsigned short pci_vendor)
114{
115 struct pcilst_struct *inova, *next;
116
117 for (inova = inova_devices; inova; inova = next) {
118 next = inova->next;
119 pci_dev_put(inova->pcidev);
120 kfree(inova);
121 }
122
123 inova_devices = NULL;
124}
125
126/****************************************************************************/
127/* find first unused card with this device_id */
128static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
0a85b6f0
MT
129 vendor_id,
130 unsigned short
131 device_id)
96341f71
AS
132{
133 struct pcilst_struct *inova, *next;
134
135 for (inova = inova_devices; inova; inova = next) {
136 next = inova->next;
137 if ((!inova->used) && (inova->device == device_id)
0a85b6f0 138 && (inova->vendor == vendor_id))
96341f71
AS
139 return inova;
140
141 }
142
143 return NULL;
144}
145
146/****************************************************************************/
147/* find card on requested position */
148static int find_free_pci_card_by_position(unsigned short vendor_id,
0a85b6f0
MT
149 unsigned short device_id,
150 unsigned short pci_bus,
151 unsigned short pci_slot,
152 struct pcilst_struct **card)
96341f71
AS
153{
154 struct pcilst_struct *inova, *next;
155
156 *card = NULL;
157 for (inova = inova_devices; inova; inova = next) {
158 next = inova->next;
159 if ((inova->vendor == vendor_id) && (inova->device == device_id)
0a85b6f0
MT
160 && (inova->pci_bus == pci_bus)
161 && (inova->pci_slot == pci_slot)) {
96341f71
AS
162 if (!(inova->used)) {
163 *card = inova;
b6c77757 164 return 0; /* ok, card is found */
96341f71 165 } else {
b6c77757 166 return 2; /* card exist but is used */
96341f71
AS
167 }
168 }
169 }
170
b6c77757 171 return 1; /* no card found */
96341f71
AS
172}
173
174/****************************************************************************/
175/* mark card as used */
176static int pci_card_alloc(struct pcilst_struct *inova)
177{
178 int i;
179
180 if (!inova) {
5f74ea14 181 printk(" - BUG!! inova is NULL!\n");
96341f71
AS
182 return -1;
183 }
184
185 if (inova->used)
186 return 1;
187 if (comedi_pci_enable(inova->pcidev, "icp_multi")) {
5f74ea14 188 printk(" - Can't enable PCI device and request regions!\n");
96341f71
AS
189 return -1;
190 }
191 /* Resources will be accurate now. */
192 for (i = 0; i < 5; i++)
193 inova->io_addr[i] = pci_resource_start(inova->pcidev, i);
194 inova->irq = inova->pcidev->irq;
195 inova->used = 1;
196 return 0;
197}
198
199/****************************************************************************/
200/* mark card as free */
201static int pci_card_free(struct pcilst_struct *inova)
202{
203 if (!inova)
204 return -1;
205
206 if (!inova->used)
207 return 1;
208 inova->used = 0;
209 comedi_pci_disable(inova->pcidev);
210 return 0;
211}
212
213/****************************************************************************/
214/* display list of found cards */
215static void pci_card_list_display(void)
216{
217 struct pcilst_struct *inova, *next;
218
219 printk("Anne's List of pci cards\n");
220 printk("bus:slot:func vendor device io_inova io_daq irq used\n");
221
222 for (inova = inova_devices; inova; inova = next) {
223 next = inova->next;
0a85b6f0
MT
224 printk
225 ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
226 inova->pci_bus, inova->pci_slot, inova->pci_func,
227 inova->vendor, inova->device,
228 (unsigned long long)inova->io_addr[0],
229 (unsigned long long)inova->io_addr[2], inova->irq,
230 inova->used);
96341f71
AS
231
232 }
233}
234
235/****************************************************************************/
236/* return all card information for driver */
237static int pci_card_data(struct pcilst_struct *inova,
0a85b6f0
MT
238 unsigned char *pci_bus, unsigned char *pci_slot,
239 unsigned char *pci_func, resource_size_t * io_addr,
240 unsigned int *irq)
96341f71
AS
241{
242 int i;
243
244 if (!inova)
245 return -1;
246 *pci_bus = inova->pci_bus;
247 *pci_slot = inova->pci_slot;
248 *pci_func = inova->pci_func;
249 for (i = 0; i < 5; i++)
250 io_addr[i] = inova->io_addr[i];
251 *irq = inova->irq;
252 return 0;
253}
254
255/****************************************************************************/
256/* select and alloc card */
257static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
0a85b6f0
MT
258 unsigned short device_id,
259 unsigned short pci_bus,
260 unsigned short pci_slot)
96341f71
AS
261{
262 struct pcilst_struct *card;
263 int err;
264
b6c77757 265 if ((pci_bus < 1) & (pci_slot < 1)) { /* use autodetection */
197c82bf 266
51b713a6 267 card = find_free_pci_card_by_device(vendor_id, device_id);
197c82bf 268 if (card == NULL) {
5f74ea14 269 printk(" - Unused card not found in system!\n");
96341f71
AS
270 return NULL;
271 }
272 } else {
273 switch (find_free_pci_card_by_position(vendor_id, device_id,
0a85b6f0
MT
274 pci_bus, pci_slot,
275 &card)) {
96341f71 276 case 1:
5f74ea14 277 printk
0a85b6f0
MT
278 (" - Card not found on requested position b:s %d:%d!\n",
279 pci_bus, pci_slot);
96341f71
AS
280 return NULL;
281 case 2:
5f74ea14 282 printk
0a85b6f0
MT
283 (" - Card on requested position is used b:s %d:%d!\n",
284 pci_bus, pci_slot);
96341f71
AS
285 return NULL;
286 }
287 }
288
197c82bf 289 err = pci_card_alloc(card);
51b713a6 290 if (err != 0) {
96341f71 291 if (err > 0)
5f74ea14 292 printk(" - Can't allocate card!\n");
96341f71
AS
293 /* else: error already printed. */
294 return NULL;
295 }
296
297 return card;
298}
299
300#endif