- patches.fixes/patch-2.6.11-rc1: 2.6.11-rc1.
[linux-flexiantxendom0-3.2.10.git] / drivers / pci / pcie / portdrv_core.c
1 /*
2  * File:        portdrv_core.c
3  * Purpose:     PCI Express Port Bus Driver's Core Functions
4  *
5  * Copyright (C) 2004 Intel
6  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7  */
8
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/pm.h>
14 #include <linux/pcieport_if.h>
15
16 #include "portdrv.h"
17
18 extern int pcie_mch_quirk;      /* MSI-quirk Indicator */
19
20 extern struct device_driver pcieport_generic_driver;
21
22 static int pcie_port_probe_service(struct device *dev)
23 {
24         struct pcie_device *pciedev;
25         struct pcie_port_service_driver *driver;
26         int status = -ENODEV;
27
28         if (!dev || !dev->driver)
29                 return status;
30
31         driver = to_service_driver(dev->driver);
32         if (!driver || !driver->probe)
33                 return status;
34
35         pciedev = to_pcie_device(dev);
36         status = driver->probe(pciedev, driver->id_table);
37         if (!status) {
38                 printk(KERN_DEBUG "Load service driver %s on pcie device %s\n",
39                         driver->name, dev->bus_id);
40                 get_device(dev);
41         }
42         return status;
43 }
44
45 static int pcie_port_remove_service(struct device *dev)
46 {
47         struct pcie_device *pciedev;
48         struct pcie_port_service_driver *driver;
49
50         if (!dev || !dev->driver)
51                 return 0;
52
53         pciedev = to_pcie_device(dev);
54         driver = to_service_driver(dev->driver);
55         if (driver && driver->remove) { 
56                 printk(KERN_DEBUG "Unload service driver %s on pcie device %s\n",
57                         driver->name, dev->bus_id);
58                 driver->remove(pciedev);
59                 put_device(dev);
60         }
61         return 0;
62 }
63
64 static void pcie_port_shutdown_service(struct device *dev) {}
65
66 static int pcie_port_suspend_service(struct device *dev, u32 state, u32 level)
67 {
68         struct pcie_device *pciedev;
69         struct pcie_port_service_driver *driver;
70
71         if (!dev || !dev->driver)
72                 return 0;
73
74         pciedev = to_pcie_device(dev);
75         driver = to_service_driver(dev->driver);
76         if (driver && driver->suspend)
77                 driver->suspend(pciedev, state);
78         return 0;
79 }
80
81 static int pcie_port_resume_service(struct device *dev, u32 state)
82 {
83         struct pcie_device *pciedev;
84         struct pcie_port_service_driver *driver;
85
86         if (!dev || !dev->driver)
87                 return 0;
88
89         pciedev = to_pcie_device(dev);
90         driver = to_service_driver(dev->driver);
91
92         if (driver && driver->resume)
93                 driver->resume(pciedev);
94         return 0;
95 }
96
97 /*
98  * release_pcie_device
99  *      
100  *      Being invoked automatically when device is being removed 
101  *      in response to device_unregister(dev) call.
102  *      Release all resources being claimed.
103  */
104 static void release_pcie_device(struct device *dev)
105 {
106         kfree(to_pcie_device(dev));                     
107 }
108
109 static int is_msi_quirked(struct pci_dev *dev)
110 {
111         int port_type, quirk = 0;
112         u16 reg16;
113
114         pci_read_config_word(dev, 
115                 pci_find_capability(dev, PCI_CAP_ID_EXP) + 
116                 PCIE_CAPABILITIES_REG, &reg16);
117         port_type = (reg16 >> 4) & PORT_TYPE_MASK;
118         switch(port_type) {
119         case PCIE_RC_PORT:
120                 if (pcie_mch_quirk == 1)
121                         quirk = 1;
122                 break;
123         case PCIE_SW_UPSTREAM_PORT:
124         case PCIE_SW_DOWNSTREAM_PORT:
125         default:
126                 break;  
127         }
128         return quirk;
129 }
130         
131 static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
132 {
133         int i, pos, nvec, status = -EINVAL;
134         int interrupt_mode = PCIE_PORT_INTx_MODE;
135
136         /* Set INTx as default */
137         for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
138                 if (mask & (1 << i)) 
139                         nvec++;
140                 vectors[i] = dev->irq;
141         }
142         
143         /* Check MSI quirk */
144         if (is_msi_quirked(dev))
145                 return interrupt_mode;
146
147         /* Select MSI-X over MSI if supported */                
148         pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
149         if (pos) {
150                 struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 
151                         {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
152                 printk("%s Found MSIX capability\n", __FUNCTION__);
153                 status = pci_enable_msix(dev, msix_entries, nvec);
154                 if (!status) {
155                         int j = 0;
156
157                         interrupt_mode = PCIE_PORT_MSIX_MODE;
158                         for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
159                                 if (mask & (1 << i)) 
160                                         vectors[i] = msix_entries[j++].vector;
161                         }
162                 }
163         } 
164         if (status) {
165                 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
166                 if (pos) {
167                         printk("%s Found MSI capability\n", __FUNCTION__);
168                         status = pci_enable_msi(dev);
169                         if (!status) {
170                                 interrupt_mode = PCIE_PORT_MSI_MODE;
171                                 for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
172                                         vectors[i] = dev->irq;
173                         }
174                 }
175         } 
176         return interrupt_mode;
177 }
178
179 static int get_port_device_capability(struct pci_dev *dev)
180 {
181         int services = 0, pos;
182         u16 reg16;
183         u32 reg32;
184
185         pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
186         pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
187         /* Hot-Plug Capable */
188         if (reg16 & PORT_TO_SLOT_MASK) {
189                 pci_read_config_dword(dev, 
190                         pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
191                 if (reg32 & SLOT_HP_CAPABLE_MASK)
192                         services |= PCIE_PORT_SERVICE_HP;
193         } 
194         /* PME Capable */
195         pos = pci_find_capability(dev, PCI_CAP_ID_PME);
196         if (pos) 
197                 services |= PCIE_PORT_SERVICE_PME;
198         
199         pos = PCI_CFG_SPACE_SIZE;
200         while (pos) {
201                 pci_read_config_dword(dev, pos, &reg32);
202                 switch (reg32 & 0xffff) {
203                 case PCI_EXT_CAP_ID_ERR:
204                         services |= PCIE_PORT_SERVICE_AER;
205                         pos = reg32 >> 20;
206                         break;
207                 case PCI_EXT_CAP_ID_VC:
208                         services |= PCIE_PORT_SERVICE_VC;
209                         pos = reg32 >> 20;
210                         break;
211                 default:
212                         pos = 0;
213                         break;
214                 }
215         }
216
217         return services;
218 }
219
220 static void pcie_device_init(struct pcie_device *parent, 
221                         struct pcie_device *dev, 
222                         int port_type, int service_type)
223 {
224         struct device *device;
225
226         if (parent) {
227                 dev->id.vendor = parent->port->vendor;
228                 dev->id.device = parent->port->device;
229                 dev->id.port_type = port_type;
230                 dev->id.service_type = (1 << service_type);
231         }
232
233         /* Initialize generic device interface */
234         device = &dev->device;
235         memset(device, 0, sizeof(struct device));
236         INIT_LIST_HEAD(&device->node);
237         INIT_LIST_HEAD(&device->children);
238         INIT_LIST_HEAD(&device->bus_list);
239         device->bus = &pcie_port_bus_type;
240         device->driver = NULL;
241         device->driver_data = NULL; 
242         device->release = release_pcie_device;  /* callback to free pcie dev */
243         sprintf(&device->bus_id[0], "%s.%02x", parent->device.bus_id, 
244                         get_descriptor_id(port_type, service_type));
245         device->parent = ((parent == NULL) ? NULL : &parent->device);
246 }
247
248 static struct pcie_device* alloc_pcie_device(
249         struct pcie_device *parent, struct pci_dev *bridge, 
250         int port_type, int service_type, int irq, int irq_mode)
251 {
252         struct pcie_device *device;
253         static int NR_PORTS = 0;
254
255         device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
256         if (!device)
257                 return NULL;
258
259         memset(device, 0, sizeof(struct pcie_device));
260         device->port = bridge;
261         device->interrupt_mode = irq_mode;
262         device->irq = irq;
263         if (!parent) {
264                 pcie_device_init(NULL, device, port_type, service_type);
265                 NR_PORTS++;
266                 device->device.driver = &pcieport_generic_driver;
267                 sprintf(&device->device.bus_id[0], "port%d", NR_PORTS); 
268         } else { 
269                 pcie_device_init(parent, device, port_type, service_type);
270         }
271         printk(KERN_DEBUG "Allocate Port Device[%s]\n", device->device.bus_id);
272         return device;
273 }
274
275 int pcie_port_device_probe(struct pci_dev *dev)
276 {
277         int pos, type;
278         u16 reg;
279
280         if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
281                 return -ENODEV;
282
283         pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
284         type = (reg >> 4) & PORT_TYPE_MASK;
285         if (    type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
286                 type == PCIE_SW_DOWNSTREAM_PORT )  
287                 return 0;
288  
289         return -ENODEV;
290 }
291
292 int pcie_port_device_register(struct pci_dev *dev)
293 {
294         struct pcie_device *parent;
295         int status, type, capabilities, irq_mode, i;
296         int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
297         u16 reg16;
298
299         /* Get port type */
300         pci_read_config_word(dev, 
301                 pci_find_capability(dev, PCI_CAP_ID_EXP) + 
302                 PCIE_CAPABILITIES_REG, &reg16);
303         type = (reg16 >> 4) & PORT_TYPE_MASK;
304
305         /* Now get port services */
306         capabilities = get_port_device_capability(dev);
307         irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
308
309         /* Allocate parent */
310         parent = alloc_pcie_device(NULL, dev, type, 0, dev->irq, irq_mode);
311         if (!parent) 
312                 return -ENOMEM;
313         
314         status = device_register(&parent->device);
315         if (status) {
316                 kfree(parent);
317                 return status;
318         }
319         get_device(&parent->device);
320         pci_set_drvdata(dev, parent);   
321
322         /* Allocate child services if any */
323         for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
324                 struct pcie_device *child;
325
326                 if (capabilities & (1 << i)) {
327                         child = alloc_pcie_device(
328                                 parent,         /* parent */ 
329                                 dev,            /* Root/Upstream/Downstream */
330                                 type,           /* port type */ 
331                                 i,              /* service type */
332                                 vectors[i],     /* irq */
333                                 irq_mode        /* interrupt mode */);
334                         if (child) { 
335                                 status = device_register(&child->device);
336                                 if (status) {
337                                         kfree(child);
338                                         continue;
339                                 }
340                                 get_device(&child->device);
341                         }
342                 }
343         }
344         return 0;
345 }
346
347 #ifdef CONFIG_PM
348 int pcie_port_device_suspend(struct pcie_device *dev, u32 state)
349 {
350         struct list_head                *head;
351         struct device                   *parent, *child;
352         struct device_driver            *driver;
353         struct pcie_port_service_driver *service_driver;
354
355         parent = &dev->device;
356         head = &parent->children;
357         while (!list_empty(head)) {
358                 child = container_of(head->next, struct device, node);
359                 driver = child->driver;
360                 if (!driver)
361                         continue;
362                 service_driver = to_service_driver(driver);
363                 if (service_driver->suspend)  
364                         service_driver->suspend(to_pcie_device(child), state);
365         }
366         return 0; 
367 }
368
369 int pcie_port_device_resume(struct pcie_device *dev) 
370
371         struct list_head                *head;
372         struct device                   *parent, *child;
373         struct device_driver            *driver;
374         struct pcie_port_service_driver *service_driver;
375
376         parent = &dev->device;
377         head = &parent->children;
378         while (!list_empty(head)) {
379                 child = container_of(head->next, struct device, node);
380                 driver = child->driver;
381                 if (!driver)
382                         continue;
383                 service_driver = to_service_driver(driver);
384                 if (service_driver->resume)  
385                         service_driver->resume(to_pcie_device(child));
386         }
387         return 0; 
388
389 }
390 #endif
391
392 void pcie_port_device_remove(struct pcie_device *dev)
393 {
394         struct list_head                *head;
395         struct device                   *parent, *child;
396         struct device_driver            *driver;
397         struct pcie_port_service_driver *service_driver;
398
399         parent = &dev->device;
400         head = &parent->children;
401         while (!list_empty(head)) {
402                 child = container_of(head->next, struct device, node);
403                 driver = child->driver;
404                 if (driver) { 
405                         service_driver = to_service_driver(driver);
406                         if (service_driver->remove)  
407                                 service_driver->remove(to_pcie_device(child));
408                 }
409                 put_device(child);
410                 device_unregister(child);
411         }
412
413         /* Switch to INTx by default if MSI enabled */
414         if (dev->interrupt_mode == PCIE_PORT_MSIX_MODE)
415                 pci_disable_msix(dev->port);
416         else if (dev->interrupt_mode == PCIE_PORT_MSI_MODE)
417                 pci_disable_msi(dev->port);
418         put_device(parent);
419         device_unregister(parent);
420 }
421
422 void pcie_port_bus_register(void)
423 {
424         bus_register(&pcie_port_bus_type);
425         driver_register(&pcieport_generic_driver);
426 }
427
428 void pcie_port_bus_unregister(void)
429 {
430         driver_unregister(&pcieport_generic_driver);
431         bus_unregister(&pcie_port_bus_type);
432 }
433
434 int pcie_port_service_register(struct pcie_port_service_driver *new)
435 {
436         new->driver.name = (char *)new->name;
437         new->driver.bus = &pcie_port_bus_type;
438         new->driver.probe = pcie_port_probe_service;
439         new->driver.remove = pcie_port_remove_service;
440         new->driver.shutdown = pcie_port_shutdown_service;
441         new->driver.suspend = pcie_port_suspend_service;
442         new->driver.resume = pcie_port_resume_service;
443
444         return driver_register(&new->driver);
445
446
447 void pcie_port_service_unregister(struct pcie_port_service_driver *new)
448 {
449         driver_unregister(&new->driver);
450 }
451
452 EXPORT_SYMBOL(pcie_port_service_register);
453 EXPORT_SYMBOL(pcie_port_service_unregister);