Guest operating system driven brightness control support.
[xenclient/linux-2.6.27-pq.git] / master / pciback-flr
1 diff --git a/drivers/xen/pciback/controller.c b/drivers/xen/pciback/controller.c
2 --- a/drivers/xen/pciback/controller.c
3 +++ b/drivers/xen/pciback/controller.c
4 @@ -208,7 +208,7 @@
5         }
6  
7         spin_unlock_irqrestore(&dev_data->lock, flags);
8 -       pcistub_put_pci_dev(found_dev);
9 +       pcistub_put_pci_dev(found_dev, 0);
10  }
11  
12  int pciback_init_devices(struct pciback_device *pdev)
13 @@ -396,7 +396,7 @@
14                 list_for_each_entry_safe(dev_entry, d,
15                                          &cntrl_entry->dev_list, list) {
16                         list_del(&dev_entry->list);
17 -                       pcistub_put_pci_dev(dev_entry->dev);
18 +                       pcistub_put_pci_dev(dev_entry->dev, 0);
19                         kfree(dev_entry);
20                 }
21                 list_del(&cntrl_entry->list);
22 diff --git a/drivers/xen/pciback/passthrough.c b/drivers/xen/pciback/passthrough.c
23 --- a/drivers/xen/pciback/passthrough.c
24 +++ b/drivers/xen/pciback/passthrough.c
25 @@ -88,7 +88,7 @@
26         spin_unlock_irqrestore(&dev_data->lock, flags);
27  
28         if (found_dev)
29 -               pcistub_put_pci_dev(found_dev);
30 +               pcistub_put_pci_dev(found_dev, 1);
31  }
32  
33  int pciback_init_devices(struct pciback_device *pdev)
34 @@ -157,7 +157,7 @@
35  
36         list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
37                 list_del(&dev_entry->list);
38 -               pcistub_put_pci_dev(dev_entry->dev);
39 +               pcistub_put_pci_dev(dev_entry->dev, 1);
40                 kfree(dev_entry);
41         }
42  
43 diff --git a/drivers/xen/pciback/pci_stub.c b/drivers/xen/pciback/pci_stub.c
44 --- a/drivers/xen/pciback/pci_stub.c
45 +++ b/drivers/xen/pciback/pci_stub.c
46 @@ -24,10 +24,28 @@
47  * We want to avoid in middle of AER ops, pciback devices is being removed
48  */
49  static DECLARE_RWSEM(pcistub_sem);
50 -module_param_named(hide, pci_devs_to_hide, charp, 0444);
51 +module_param_named(hide, pci_devs_to_hide, charp, S_IRUGO);
52 +
53 +static char *pci_devs_use_sbr = NULL;
54 +module_param_named(sbr, pci_devs_use_sbr, charp, S_IRUGO);
55 +
56 +static char *pci_devs_use_d3r = NULL;
57 +module_param_named(d3r, pci_devs_use_d3r, charp, S_IRUGO);
58 +
59 +static char *pci_devs_no_flr = NULL;
60 +module_param_named(noflr, pci_devs_no_flr, charp, S_IRUGO);
61 +
62 +/* Device id list holding different device type listings
63 + * for hiding devices and reset logic.
64 + */
65 +#define PCIBACK_ID_TYPE_HIDE  1
66 +#define PCIBACK_ID_TYPE_SBR   2
67 +#define PCIBACK_ID_TYPE_D3R   3
68 +#define PCIBACK_ID_TYPE_NOFLR 4
69  
70  struct pcistub_device_id {
71         struct list_head slot_list;
72 +       int type;
73         int domain;
74         unsigned char bus;
75         unsigned int devfn;
76 @@ -56,6 +74,8 @@
77  static int initialize_devices = 0;
78  static LIST_HEAD(seized_devices);
79  
80 +static int disable_all_flr = 0;
81 +
82  static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
83  {
84         struct pcistub_device *psdev;
85 @@ -76,6 +96,23 @@
86         spin_lock_init(&psdev->lock);
87  
88         return psdev;
89 +}
90 +
91 +static struct pciback_dev_data *pcistub_dev_data_alloc(struct pci_dev *dev)
92 +{
93 +       struct pciback_dev_data *dev_data;
94 +
95 +       dev_dbg(&dev->dev, "pcistub_dev_data_alloc\n");
96 +
97 +       dev_data = kzalloc(sizeof(*dev_data) + dev->cfg_size, GFP_ATOMIC);
98 +       if (!dev_data)
99 +               return NULL;
100 +               
101 +       pci_set_drvdata(dev, dev_data);
102 +
103 +       dev_data->cfg_space = (u8*)(dev_data) + sizeof(*dev_data);
104 +
105 +       return dev_data;
106  }
107  
108  /* Don't call this directly as it's called by pcistub_device_put */
109 @@ -200,7 +237,7 @@
110         return found_dev;
111  }
112  
113 -void pcistub_put_pci_dev(struct pci_dev *dev)
114 +void pcistub_put_pci_dev(struct pci_dev *dev, int do_flr)
115  {
116         struct pcistub_device *psdev, *found_psdev = NULL;
117         unsigned long flags;
118 @@ -220,6 +257,13 @@
119         * pcistub and pciback when AER is in processing
120         */
121         down_write(&pcistub_sem);
122 +
123 +       /* For pass-through devices, do an FLR (or approximate) for the device
124 +        * before it is put back and ready for the next domain
125 +        */
126 +       if (!disable_all_flr && do_flr)
127 +               pciback_flr_device(dev);
128 +
129         /* Cleanup our device
130          * (so it's ready for the next domain)
131          */
132 @@ -233,6 +277,43 @@
133  
134         pcistub_device_put(found_psdev);
135         up_write(&pcistub_sem);
136 +}
137 +
138 +struct pci_dev *pcistub_ref_pci_dev(struct pci_dev *dev)
139 +{
140 +       struct pcistub_device *psdev;
141 +       struct pci_dev *found_dev = NULL;
142 +       unsigned long flags;
143 +
144 +       spin_lock_irqsave(&pcistub_devices_lock, flags);
145 +
146 +       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
147 +               if (psdev->dev == dev) {
148 +                       pcistub_device_get(psdev); /* just a ref count */
149 +                       found_dev = psdev->dev;
150 +                       break;
151 +               }
152 +       }
153 +
154 +       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
155 +       return found_dev;
156 +}
157 +
158 +void pcistub_unref_pci_dev(struct pci_dev *dev)
159 +{
160 +       struct pcistub_device *psdev;
161 +       unsigned long flags;
162 +
163 +       spin_lock_irqsave(&pcistub_devices_lock, flags);
164 +
165 +       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
166 +               if (psdev->dev == dev) {
167 +                       pcistub_device_get(psdev); /* just an unref count */
168 +                       break;
169 +               }
170 +       }
171 +
172 +       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
173  }
174  
175  static int __devinit pcistub_match_one(struct pci_dev *dev,
176 @@ -255,7 +336,7 @@
177         return 0;
178  }
179  
180 -static int __devinit pcistub_match(struct pci_dev *dev)
181 +static int __devinit pcistub_match(struct pci_dev *dev, int type)
182  {
183         struct pcistub_device_id *pdev_id;
184         unsigned long flags;
185 @@ -263,6 +344,8 @@
186  
187         spin_lock_irqsave(&device_ids_lock, flags);
188         list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
189 +               if (pdev_id->type != type)
190 +                       continue;
191                 if (pcistub_match_one(dev, pdev_id)) {
192                         found = 1;
193                         break;
194 @@ -285,12 +368,11 @@
195          * would need to be called somewhere to free the memory allocated
196          * here and then to call kfree(pci_get_drvdata(psdev->dev)).
197          */
198 -       dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
199 +       dev_data = pcistub_dev_data_alloc(dev);
200         if (!dev_data) {
201                 err = -ENOMEM;
202                 goto out;
203         }
204 -       pci_set_drvdata(dev, dev_data);
205  
206         dev_dbg(&dev->dev, "initializing config\n");
207  
208 @@ -316,6 +398,22 @@
209          */
210         dev_dbg(&dev->dev, "reset device\n");
211         pciback_reset_device(dev);
212 +
213 +       /* Classify the device so we know if it is PCI/PCIe and if it is
214 +        * a bridge - this information is used for FLR logic. Also store 
215 +        * values if SBR/D3R reset logic was requested.
216 +        */
217 +       pciback_classify_device(dev);
218 +       dev_data->no_flr = pcistub_match(dev, PCIBACK_ID_TYPE_NOFLR);
219 +       if (!dev_data->no_flr) {
220 +               dev_data->use_sbr = pcistub_match(dev, PCIBACK_ID_TYPE_SBR);
221 +               dev_data->use_d3r = pcistub_match(dev, PCIBACK_ID_TYPE_D3R);
222 +       }
223 +
224 +       /* Store the config space here where the device is off and ready to be 
225 +        * exported before any FLRs or other resets are done
226 +        */
227 +       pciback_store_config_space(dev);
228  
229         return 0;
230  
231 @@ -414,7 +512,7 @@
232  
233         dev_dbg(&dev->dev, "probing...\n");
234  
235 -       if (pcistub_match(dev)) {
236 +       if (pcistub_match(dev, PCIBACK_ID_TYPE_HIDE)) {
237  
238                 if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
239                     && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
240 @@ -851,7 +949,7 @@
241         return -EINVAL;
242  }
243  
244 -static int pcistub_device_id_add(int domain, int bus, int slot, int func)
245 +static int pcistub_device_id_add(int domain, int bus, int slot, int func, int type)
246  {
247         struct pcistub_device_id *pci_dev_id;
248         unsigned long flags;
249 @@ -860,12 +958,13 @@
250         if (!pci_dev_id)
251                 return -ENOMEM;
252  
253 +       pci_dev_id->type = type;
254         pci_dev_id->domain = domain;
255         pci_dev_id->bus = bus;
256         pci_dev_id->devfn = PCI_DEVFN(slot, func);
257  
258 -       pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
259 -                domain, bus, slot, func);
260 +       pr_debug("pciback: adding device ID type: %d for %04x:%02x:%02x.%01x\n",
261 +                type, domain, bus, slot, func);
262  
263         spin_lock_irqsave(&device_ids_lock, flags);
264         list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
265 @@ -874,7 +973,7 @@
266         return 0;
267  }
268  
269 -static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
270 +static int pcistub_device_id_remove(int domain, int bus, int slot, int func, int type)
271  {
272         struct pcistub_device_id *pci_dev_id, *t;
273         int devfn = PCI_DEVFN(slot, func);
274 @@ -884,7 +983,7 @@
275         spin_lock_irqsave(&device_ids_lock, flags);
276         list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) {
277  
278 -               if (pci_dev_id->domain == domain
279 +               if (pci_dev_id->type == type && pci_dev_id->domain == domain
280                     && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
281                         /* Don't break; here because it's possible the same
282                          * slot could be in the list more than once
283 @@ -939,6 +1038,32 @@
284         return err;
285  }
286  
287 +static int pcistub_device_do_flr(int domain, int bus, int slot, int func)
288 +{
289 +       int err = 0;
290 +       struct pcistub_device *psdev;
291 +       struct pci_dev *dev;
292 +
293 +       psdev = pcistub_device_find(domain, bus, slot, func);
294 +       if (!psdev || !psdev->dev) {
295 +               err = -ENODEV;
296 +               goto out;
297 +       }
298 +       dev = psdev->dev;
299 +
300 +       /* Do an FLR (or approximate) for the device on demand and 
301 +        * reload config
302 +        */
303 +       if (!disable_all_flr) {
304 +               pciback_flr_device(dev);
305 +       }
306 +       else
307 +               dev_dbg(&dev->dev, "FLR disabled for all devices\n");
308 +
309 +out:
310 +       return err;
311 +}
312 +
313  static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
314                                 size_t count)
315  {
316 @@ -949,7 +1074,7 @@
317         if (err)
318                 goto out;
319  
320 -       err = pcistub_device_id_add(domain, bus, slot, func);
321 +       err = pcistub_device_id_add(domain, bus, slot, func, PCIBACK_ID_TYPE_HIDE);
322  
323        out:
324         if (!err)
325 @@ -969,7 +1094,7 @@
326         if (err)
327                 goto out;
328  
329 -       err = pcistub_device_id_remove(domain, bus, slot, func);
330 +       err = pcistub_device_id_remove(domain, bus, slot, func, PCIBACK_ID_TYPE_HIDE);
331  
332        out:
333         if (!err)
334 @@ -987,6 +1112,10 @@
335  
336         spin_lock_irqsave(&device_ids_lock, flags);
337         list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
338 +               /* only want devices set for hide, not reset entries */
339 +               if (pci_dev_id->type != PCIBACK_ID_TYPE_HIDE)
340 +                       continue;
341 +
342                 if (count >= PAGE_SIZE)
343                         break;
344  
345 @@ -1068,7 +1197,7 @@
346  
347  DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add);
348  
349 -static ssize_t permissive_add(struct device_driver *drv, const char *buf,
350 +static ssize_t pcistub_permissive_add(struct device_driver *drv, const char *buf,
351                               size_t count)
352  {
353         int domain, bus, slot, func;
354 @@ -1109,7 +1238,7 @@
355         return err;
356  }
357  
358 -static ssize_t permissive_show(struct device_driver *drv, char *buf)
359 +static ssize_t pcistub_permissive_show(struct device_driver *drv, char *buf)
360  {
361         struct pcistub_device *psdev;
362         struct pciback_dev_data *dev_data;
363 @@ -1132,7 +1261,68 @@
364         return count;
365  }
366  
367 -DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
368 +DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, pcistub_permissive_show, pcistub_permissive_add);
369 +
370 +static ssize_t pcistub_do_flr(struct device_driver *drv, const char *buf,
371 +                                  size_t count)
372 +{
373 +       int domain, bus, slot, func;
374 +       int err;
375 +
376 +       err = str_to_slot(buf, &domain, &bus, &slot, &func);
377 +       if (err)
378 +               goto out;
379 +
380 +       err = pcistub_device_do_flr(domain, bus, slot, func);
381 +
382 +out:
383 +       if (!err)
384 +               err = count;
385 +       return err;
386 +}
387 +
388 +DRIVER_ATTR(do_flr, S_IWUSR, NULL, pcistub_do_flr);
389 +
390 +static ssize_t pcistub_resets(struct device_driver *drv, const char *buf,
391 +                                  size_t count)
392 +{
393 +       int domain, bus, slot, func;
394 +       int type, err = 0;
395 +
396 +       /* string begins with reset type specifier sbr=|dr3=|noflr= */
397 +       if (!strncmp(buf, "sbr=", 4)) {
398 +               type = PCIBACK_ID_TYPE_SBR;
399 +               buf += 4;
400 +       } else if (!strncmp(buf, "d3r=", 4)) {
401 +               type = PCIBACK_ID_TYPE_D3R;
402 +               buf += 4;
403 +       } else if (!strncmp(buf, "noflr=", 6)) {
404 +               type = PCIBACK_ID_TYPE_NOFLR;
405 +               buf += 6;
406 +       } else {
407 +               err = -EINVAL;
408 +               goto out;
409 +       }
410 +
411 +       /* check special wildcard noflr */
412 +       if (type == PCIBACK_ID_TYPE_NOFLR && !strncmp(buf, "(*)", 3)) {
413 +               disable_all_flr = 1;
414 +               goto out;
415 +       }
416 +
417 +       err = str_to_slot(buf, &domain, &bus, &slot, &func);
418 +       if (err)
419 +               goto out;
420 +
421 +       err = pcistub_device_id_add(domain, bus, slot, func, type);
422 +
423 +out:
424 +       if (!err)
425 +               err = count;
426 +       return err;
427 +}
428 +
429 +DRIVER_ATTR(resets, S_IWUSR, NULL, pcistub_resets);
430  
431  #ifdef CONFIG_PCI_MSI
432  
433 @@ -1158,6 +1348,8 @@
434         driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
435         driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
436         driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
437 +       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_do_flr);
438 +       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_resets);
439  
440         pci_unregister_driver(&pciback_pci_driver);
441         WARN_ON(unregister_msi_get_owner(pciback_get_owner));
442 @@ -1165,35 +1357,27 @@
443  
444  static int __init pcistub_init(void)
445  {
446 -       int pos = 0;
447         int err = 0;
448 -       int domain, bus, slot, func;
449 -       int parsed;
450  
451 -       if (pci_devs_to_hide && *pci_devs_to_hide) {
452 -               do {
453 -                       parsed = 0;
454 +       /* Parse device lists for hide, sbr, and d3r */
455 +       err = pciback_parse_device_params(pci_devs_to_hide, PCIBACK_ID_TYPE_HIDE, pcistub_device_id_add);
456 +       if (err)
457 +               goto out;
458  
459 -                       err = sscanf(pci_devs_to_hide + pos,
460 -                                    " (%x:%x:%x.%x) %n",
461 -                                    &domain, &bus, &slot, &func, &parsed);
462 -                       if (err != 4) {
463 -                               domain = 0;
464 -                               err = sscanf(pci_devs_to_hide + pos,
465 -                                            " (%x:%x.%x) %n",
466 -                                            &bus, &slot, &func, &parsed);
467 -                               if (err != 3)
468 -                                       goto parse_error;
469 -                       }
470 +       err = pciback_parse_device_params(pci_devs_use_sbr, PCIBACK_ID_TYPE_SBR, pcistub_device_id_add);
471 +       if (err)
472 +               goto out;
473  
474 -                       err = pcistub_device_id_add(domain, bus, slot, func);
475 -                       if (err)
476 -                               goto out;
477 +       err = pciback_parse_device_params(pci_devs_use_d3r, PCIBACK_ID_TYPE_D3R, pcistub_device_id_add);
478 +       if (err)
479 +               goto out;
480  
481 -                       /* if parsed<=0, we've reached the end of the string */
482 -                       pos += parsed;
483 -               } while (parsed > 0 && pci_devs_to_hide[pos]);
484 -       }
485 +       if (pci_devs_no_flr && *pci_devs_no_flr && !strncmp(pci_devs_no_flr, "(*)", 3))
486 +               disable_all_flr = 1; /* check special wildcard noflr */
487 +       else
488 +               err = pciback_parse_device_params(pci_devs_no_flr, PCIBACK_ID_TYPE_NOFLR, pcistub_device_id_add);
489 +       if (err)
490 +               goto out;
491  
492         /* If we're the first PCI Device Driver to register, we're the
493          * first one to get offered PCI devices as they become
494 @@ -1217,6 +1401,12 @@
495         if (!err)
496                 err = driver_create_file(&pciback_pci_driver.driver,
497                                          &driver_attr_permissive);
498 +       if (!err)
499 +               err = driver_create_file(&pciback_pci_driver.driver,
500 +                                        &driver_attr_do_flr);
501 +       if (!err)
502 +               err = driver_create_file(&pciback_pci_driver.driver,
503 +                                        &driver_attr_resets);
504  
505         if (!err)
506                 err = register_msi_get_owner(pciback_get_owner);
507 @@ -1225,11 +1415,6 @@
508  
509        out:
510         return err;
511 -
512 -      parse_error:
513 -       printk(KERN_ERR "pciback: Error parsing pci_devs_to_hide at \"%s\"\n",
514 -              pci_devs_to_hide + pos);
515 -       return -EINVAL;
516  }
517  
518  #ifndef MODULE
519 diff --git a/drivers/xen/pciback/pciback.h b/drivers/xen/pciback/pciback.h
520 --- a/drivers/xen/pciback/pciback.h
521 +++ b/drivers/xen/pciback/pciback.h
522 @@ -25,6 +25,14 @@
523  #define _PCIB_op_pending       (1)
524  #define PCIB_op_pending                (1<<(_PCIB_op_pending))
525  
526 +#define PCIBACK_TYPE_UNKNOWN       0
527 +#define PCIBACK_TYPE_PCIe_ENDPOINT 1
528 +#define PCIBACK_TYPE_PCIe_BRIDGE   2
529 +#define PCIBACK_TYPE_PCI_BRIDGE    3
530 +#define PCIBACK_TYPE_PCI           4
531 +
532 +#define DEV_CLASS_PCI_PCI_BRIDGE 0x0604
533 +
534  struct pciback_device {
535         void *pci_dev_data;
536         spinlock_t dev_lock;
537 @@ -48,6 +56,13 @@
538         struct list_head config_fields;
539         int permissive;
540         int warned_on_write;
541 +       u32 dev_type;
542 +       int no_flr;
543 +       int exp_flr_offset;
544 +       int af_flr_offset;
545 +       int use_sbr;
546 +       int use_d3r;
547 +       u8 *cfg_space; /* saved config space for device */
548  };
549  
550  /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
551 @@ -56,10 +71,24 @@
552                                             int slot, int func);
553  struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
554                                     struct pci_dev *dev);
555 -void pcistub_put_pci_dev(struct pci_dev *dev);
556 +void pcistub_put_pci_dev(struct pci_dev *dev, int do_flr);
557 +
558 +/* Reference/unreference PCI Devices and stubs without changing the state */
559 +struct pci_dev *pcistub_ref_pci_dev(struct pci_dev *dev);
560 +void pcistub_unref_pci_dev(struct pci_dev *dev);
561 +
562 +/* Store/reload config space for devices */
563 +void pciback_store_config_space(struct pci_dev *dev);
564 +void pciback_reload_config_space(struct pci_dev *dev);
565  
566  /* Ensure a device is turned off or reset */
567  void pciback_reset_device(struct pci_dev *pdev);
568 +
569 +/* Do a function level reset (or approximage functionality) for device */
570 +void pciback_flr_device(struct pci_dev *dev);
571 +
572 +/* Helper to classify the device type */
573 +void pciback_classify_device(struct pci_dev *dev);
574  
575  /* Access a virtual configuration space for a PCI device */
576  int pciback_config_init(void);
577 @@ -102,6 +131,10 @@
578  irqreturn_t pciback_handle_event(int irq, void *dev_id);
579  void pciback_do_op(struct work_struct *work);
580  
581 +/* Parse and load device specific module parameters */
582 +int pciback_parse_device_params(const char *device_args, int type,
583 +                                       int (*add_func) (int domain, int bus, int slot, int func, int type));
584 +
585  int pciback_xenbus_register(void);
586  void pciback_xenbus_unregister(void);
587  
588 diff --git a/drivers/xen/pciback/pciback_ops.c b/drivers/xen/pciback/pciback_ops.c
589 --- a/drivers/xen/pciback/pciback_ops.c
590 +++ b/drivers/xen/pciback/pciback_ops.c
591 @@ -9,8 +9,176 @@
592  #include <xen/evtchn.h>
593  #include "pciback.h"
594  
595 +#define PCIBACK_VENDOR_INTEL     0x8086
596 +#define PCIBACK_CLASS_ID_USB     0x0c03
597 +#define PCIBACK_CLASS_ID_VGA     0x0300
598 +#define PCIBACK_USB_FLRCTRL      0x4
599 +
600 +#define PCIBACK_IGFX_CAP09_OFFSET    0xa4
601 +#define PCIBACK_IGFX_CAP13_OFFSET    0xa4
602 +
603 +#define PCIBACK_IGFX_MEDIARST        0x0d
604 +#define PCIBACK_IGFX_MEDIARST_OFFSET 0xc0
605 +
606  int verbose_request = 0;
607  module_param(verbose_request, int, 0644);
608 +
609 +struct pcistub_sbr_entry {
610 +       struct list_head dev_list;
611 +       struct pci_dev *dev;
612 +};
613 +
614 +struct pcistub_sbr_list {
615 +       struct list_head dev_list;
616 +       struct pci_dev *bridge;
617 +       struct pci_dev *dev;
618 +       int find_all;
619 +       int err;
620 +};
621 +
622 +/* Used to store the config state so it can be restored after
623 + * resets.
624 + */
625 +void pciback_store_config_space(struct pci_dev *dev)
626 +{
627 +       struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
628 +       u32 *ptr = (u32*)dev_data->cfg_space;
629 +       int i, count = dev->cfg_size/sizeof(u32);
630 +       
631 +       for (i = 0; i < count; i += sizeof(u32), ptr++)
632 +               pci_read_config_dword(dev, i, ptr);
633 +}
634 +
635 +/* Used to reload the config state after resets.
636 + */
637 +void pciback_reload_config_space(struct pci_dev *dev)
638 +{
639 +       struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
640 +       u32 *ptr = (u32*)dev_data->cfg_space;
641 +       int i, val, count = dev->cfg_size/sizeof(u32);
642 +
643 +       for (i = 0; i < count; i += sizeof(u32), ptr++) {
644 +               pci_read_config_dword(dev, i, &val);
645 +               if (val != *ptr)
646 +                       pci_write_config_dword(dev, i, *ptr);
647 +       }
648 +}
649 +
650 +static void pciback_walk_bus_cb(struct pci_dev *dev, void *userdata)
651 +{
652 +       struct pcistub_sbr_list *list = (struct pcistub_sbr_list*)userdata;
653 +       struct pcistub_sbr_entry *entry;
654 +       struct pci_dev *dev_tmp;
655 +       
656 +       if (list->err != 0)
657 +               return;
658 +
659 +       /* For PCIe endpoints we are only looking for co-assigned functions */
660 +       if (!list->find_all &&
661 +               (dev->bus->number != list->dev->bus->number ||
662 +                PCI_SLOT(dev->devfn) != PCI_SLOT(list->dev->devfn)))
663 +               return;
664 +
665 +       dev_tmp = pcistub_ref_pci_dev(dev);
666 +       if (dev_tmp == NULL) {
667 +               /* not controlled by pciback, fail */
668 +               list->err = ENXIO;
669 +               return;
670 +       }
671 +
672 +       entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
673 +       if (entry == NULL) {
674 +               pcistub_unref_pci_dev(dev_tmp);
675 +               list->err = ENOMEM;
676 +               return;
677 +       }
678 +
679 +       entry->dev = dev_tmp;
680 +       list_add_tail(&entry->dev_list, &list->dev_list);
681 +}
682 +
683 +static void pciback_cleanup_sbr_list(struct pcistub_sbr_list *list)
684 +{
685 +       struct pcistub_sbr_entry *entry;
686 +
687 +       list_for_each_entry(entry, &list->dev_list, dev_list) {
688 +               pcistub_unref_pci_dev(entry->dev);
689 +               kfree(entry);
690 +       }
691 +}
692 +
693 +/* Routine to find all devices and bridges that need to be reset
694 + * during a secondary bus reset. For PCIe this is simply all the
695 + * functions on the particular device. For PCI this is all devices
696 + * and bridges below the topmost PCI/PCI-X bridge. Note for PCI, 
697 + * there is at least one something->PCI/PCI-X bridge to find since
698 + * the device is not on the host bus 0 and is on a PCI bus.
699 + */
700 +static int pciback_get_sbr_list(struct pci_dev *dev, 
701 +       struct pcistub_sbr_list *list, int pcie_endpoint)
702 +{
703 +       struct pci_dev *bridge = dev->bus->self;
704 +       struct pci_dev *last = NULL;
705 +       int exp_pos;
706 +       u16 exp_caps = 0;
707 +
708 +       list->err = 0;
709 +       list->dev = dev;
710 +       INIT_LIST_HEAD(&list->dev_list);
711 +
712 +       if (!pcie_endpoint) {
713 +               while (bridge) {
714 +                       /* Looking for the uppermost PCI/PCI-X bridge. If it is not PCIe then 
715 +                        * this is a PCI/PCI-X bridge. If it is PCIe then except the PCIe to 
716 +                        * PCI/PCI-X type 7, the rest of the bridge types are PCIe so the last 
717 +                        * bridge encountered was the topmost PCI/PCI-X bridge.
718 +                        */
719 +                       exp_pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
720 +                       if (exp_pos != 0) {
721 +                               pci_read_config_word(bridge, exp_pos + PCI_EXP_FLAGS, &exp_caps);
722 +                               if (((exp_caps & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_PCI_BRIDGE)
723 +                                       break; /* don't want it in the list if it is a PCIe bridge */
724 +                       }
725 +                       last = bridge;
726 +                       bridge = last->bus->self;
727 +               }
728 +               list->bridge = last;
729 +               list->find_all = 1; /* find all devices/bridges below the topmost */
730 +       }
731 +       else {
732 +               if (bridge) {
733 +                       /* For PCIe, SBR logic is limited to PCIe endpoints behind a root/switch
734 +                        * port.
735 +                        */
736 +                       exp_pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
737 +                       if (likely(exp_pos != 0)) {
738 +                               pci_read_config_word(bridge, exp_pos + PCI_EXP_FLAGS, &exp_caps);
739 +                               exp_caps = ((exp_caps & PCI_EXP_FLAGS_TYPE) >> 4);
740 +                               if (exp_caps == PCI_EXP_TYPE_ROOT_PORT ||
741 +                                       exp_caps == PCI_EXP_TYPE_UPSTREAM ||
742 +                                       exp_caps == PCI_EXP_TYPE_DOWNSTREAM)
743 +                                       last = bridge;
744 +                       }
745 +               }
746 +               list->bridge = last;
747 +               list->find_all = 0; /* find just functions on this slot */
748 +       }
749 +
750 +       /* Sanity check, there may not be any appropriate bridge to reset */
751 +       if (!list->bridge) {
752 +               dev_dbg(&dev->dev, "No appropriate bridge to reset\n");
753 +               return ENXIO;
754 +       }
755 +
756 +       pci_walk_bus(list->bridge->subordinate, pciback_walk_bus_cb, list);
757 +
758 +       if (list->err) {
759 +               pciback_cleanup_sbr_list(list);
760 +               return list->err;
761 +       }
762 +
763 +       return 0;
764 +}
765  
766  /* Ensure a device is "turned off" and ready to be exported.
767   * (Also see pciback_config_reset to ensure virtual configuration space is
768 @@ -18,7 +186,7 @@
769   */
770  void pciback_reset_device(struct pci_dev *dev)
771  {
772 -       u16 cmd;
773 +       u16 cmd = 0;
774  
775         /* Disable devices (but not bridges) */
776         if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
777 @@ -38,6 +206,425 @@
778                 }
779         }
780  }
781 +
782 +/* Do a PCIe type function level reset for a single function on this
783 + * device.
784 + */
785 +static void pciback_do_pcie_flr(struct pci_dev *dev, int exp_pos)
786 +{
787 +       u16 status = 0;
788 +       
789 +       dev_dbg(&dev->dev, "doing PCIe FLR\n"); 
790 +
791 +       pci_block_user_cfg_access(dev);
792 +
793 +       /* Wait for Transaction Pending bit clean */
794 +       msleep(100);
795 +       pci_read_config_word(dev, exp_pos + PCI_EXP_DEVSTA, &status);
796 +       if (status & PCI_EXP_DEVSTA_TRPND) {
797 +               dev_dbg(&dev->dev, "Busy after 100ms while trying to reset; sleeping for 1 second\n");
798 +               ssleep(1);
799 +               pci_read_config_word(dev, exp_pos + PCI_EXP_DEVSTA, &status);
800 +               if (status & PCI_EXP_DEVSTA_TRPND)
801 +                       dev_warn(&dev->dev, "Still busy after 1s; proceeding with reset anyway\n");
802 +       }
803 +
804 +       pci_write_config_word(dev, exp_pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
805 +       mdelay(200);
806 +
807 +       pciback_reload_config_space(dev);
808 +
809 +       pci_unblock_user_cfg_access(dev);
810 +}
811 +
812 +/* Do a PCI type function level reset for a single function on this
813 + * device. This uses the Advanced Features Capability extensions to
814 + * the PCI spec.
815 + */
816 +static void pciback_do_pci_flr(struct pci_dev *dev, int af_pos, int clear_cmd)
817 +{
818 +       u8 status = 0;
819 +
820 +       dev_dbg(&dev->dev, "doing PCI FLR\n");
821 +
822 +       pci_block_user_cfg_access(dev);
823 +
824 +       /* Clear the command register to prevent new transactions */
825 +       if (clear_cmd)
826 +               pci_write_config_word(dev, PCI_COMMAND, 0);
827 +
828 +       /* Wait for Transaction Pending bit clean */
829 +       msleep(100);
830 +       pci_read_config_byte(dev, af_pos + PCI_AF_STA, &status);
831 +       if (status & PCI_AF_STA_TP) {
832 +               dev_dbg(&dev->dev, "Busy after 100ms while trying to reset; sleeping for 1 second\n");
833 +               ssleep(1);
834 +               pci_read_config_byte(dev, af_pos + PCI_AF_STA, &status);
835 +               if (status & PCI_AF_STA_TP)
836 +                       dev_warn(&dev->dev, "Still busy after 1s; proceeding with reset anyway\n");
837 +       }
838 +
839 +       pci_write_config_byte(dev, af_pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
840 +       mdelay(200);
841 +
842 +       pciback_reload_config_space(dev);
843 +
844 +       pci_unblock_user_cfg_access(dev);
845 +}
846 +
847 +/* Vendor specific resets. These can be set in the vendor specific
848 + * capabilities structures. Currently only the Intel USB and iGFX
849 + * reset is supported.
850 + */
851 +static int pciback_do_vendor_specific_reset(struct pci_dev *dev)
852 +{
853 +       struct pci_dev *gmch;
854 +       int vendor_pos, i;
855 +       u32 reg32 = 0;
856 +       u16 device_id, cmd;     
857 +       u8 reg8 = 0;
858 +
859 +       dev_dbg(&dev->dev, "doing vendor specific resets\n");   
860 +
861 +       if (dev->vendor != PCIBACK_VENDOR_INTEL)
862 +               return -ENXIO;
863 +
864 +       if ((dev->class >> 8) == PCIBACK_CLASS_ID_VGA) {
865 +               if (dev->bus->number != 0 || dev->devfn != PCI_DEVFN(2,0))
866 +                       return -ENXIO;
867 +
868 +               /* Locate the GMCH (north bridge) and test for specific Intel devices */
869 +               gmch = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
870 +               if (!gmch)
871 +                       return -ENXIO;
872 +
873 +               device_id = gmch->device;
874 +               pci_dev_put(gmch);
875 +
876 +               if (device_id != PCI_DEVICE_ID_INTEL_GMCHGM45)
877 +                       return -ENXIO;
878 +
879 +               /* Correct device and platform, assume vendor specific offset */
880 +               pci_read_config_dword(dev, PCIBACK_IGFX_CAP09_OFFSET, &reg32);
881 +               if ((reg32 & 0x000000FF) != PCI_CAP_ID_VNDR ||
882 +                       ((reg32 >> 16) & 0x000000FF) != 0x06 ||
883 +                       ((reg32 >> 24) & 0x000000F0) != 0x20)
884 +                       return -ENXIO;
885 +
886 +               vendor_pos = PCIBACK_IGFX_CAP09_OFFSET;
887 +       } else if ((dev->class >> 8) == PCIBACK_CLASS_ID_USB) {
888 +               vendor_pos = pci_find_capability(dev, PCI_CAP_ID_VNDR);
889 +               if (vendor_pos == 0)
890 +                       return -ENXIO;
891 +       }
892 +       else
893 +               return -ENXIO;  
894 +
895 +       if ((dev->class >> 8) == PCIBACK_CLASS_ID_VGA) {
896 +               pci_write_config_byte(dev, PCIBACK_IGFX_MEDIARST_OFFSET, PCIBACK_IGFX_MEDIARST);
897 +               for (i = 0; i <= 10; i++) {
898 +                       msleep(100);
899 +                       pci_read_config_byte(dev, PCIBACK_IGFX_MEDIARST_OFFSET, &reg8);
900 +                       if ((reg8 & 0x01) == 0)
901 +                               break;
902 +                       if (i == 10) {
903 +                               dev_warn(&dev->dev, "media not reset after 1s; skipping FLR\n");
904 +                               goto out;
905 +                       }
906 +               }
907 +        
908 +               /* This specific reset will hang if the command register does not have
909 +                * memory space access enabled */
910 +               pci_read_config_word(dev, PCI_COMMAND, &cmd);
911 +               pci_write_config_word(dev, PCI_COMMAND, (cmd | PCI_COMMAND_MEMORY));
912 +               /* The rest is the same as a PCI AF FLR - use the same routine */
913 +               pciback_do_pci_flr(dev, vendor_pos, 0);
914 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
915 +       } else {
916 +               pci_block_user_cfg_access(dev);
917 +
918 +               pci_write_config_byte(dev, vendor_pos + PCIBACK_USB_FLRCTRL, 1);
919 +               mdelay(200);
920 +
921 +               pciback_reload_config_space(dev);
922 +
923 +               pci_unblock_user_cfg_access(dev);
924 +       }
925 +
926 +out:
927 +       return 0;
928 +}
929 +
930 +/* Use a D0-D3-D0 device state transition to reset the device. This
931 + * is a good enough reset for some devices (like NICs).
932 + */
933 +static int pciback_do_dstate_transition_reset(struct pci_dev *dev)
934 +{
935 +       int pm_pos;
936 +       u32 pm_ctl = 0;
937 +
938 +       pm_pos = pci_find_capability(dev, PCI_CAP_ID_PM);
939 +       if (pm_pos == 0)
940 +               return -ENXIO;
941 +
942 +       dev_dbg(&dev->dev, "doing Dstate transition reset\n");  
943 +
944 +       /* No_Soft_Reset - When set 1, this bit indicates that devices
945 +        * transitioning from D3hot to D0 because of PowerState commands 
946 +        * do not perform an internal reset.
947 +        */
948 +       pci_read_config_dword(dev, pm_pos + PCI_PM_CTRL, &pm_ctl);
949 +       if (pm_ctl & PCI_PM_CTRL_NO_SOFT_RESET)
950 +               return -ENXIO;
951 +       
952 +       pci_block_user_cfg_access(dev);
953 +
954 +       pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
955 +       pm_ctl |= PCI_PM_CTRL_D3HOT;
956 +       pci_write_config_word(dev, pm_pos + PCI_PM_CTRL, pm_ctl);
957 +       mdelay(10);
958 +
959 +       pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
960 +       pm_ctl |= PCI_PM_CTRL_D0;
961 +       pci_write_config_word(dev, pm_pos + PCI_PM_CTRL, pm_ctl);
962 +       mdelay(10);
963 +
964 +       pciback_reload_config_space(dev);
965 +
966 +       pci_unblock_user_cfg_access(dev);
967 +       
968 +       return 0;
969 +}
970 +
971 +/* Do a secondary bus reset on a bridge. This is only done if all
972 + * co-assignment rules are satisfied and if it was explicitly 
973 + * requested via pciback parameters.
974 + */
975 +static int pciback_do_secondary_bus_reset(struct pci_dev *dev, u32 dev_type)
976 +{
977 +       struct pcistub_sbr_list sbr_list;
978 +       struct pcistub_sbr_entry *entry;
979 +       u16 pci_bctl = 0;
980 +       int err = 0;
981 +
982 +       /* Call helper to get the device list needed for the device type. */
983 +       err = pciback_get_sbr_list(dev, &sbr_list,
984 +                       (dev_type == PCIBACK_TYPE_PCIe_ENDPOINT ? 1 : 0));
985 +       if (err) {
986 +               dev_warn(&dev->dev, 
987 +                       "secondary bus reset failed for device - all functions need to be co-assigned - err: %d\n", err);
988 +               return err;
989 +       }
990 +
991 +       pci_block_user_cfg_access(dev);
992 +
993 +       /* Reset the secondary bus and restore the PCI space for all the devfn found above.
994 +        */
995 +       pci_read_config_word(sbr_list.bridge, PCI_BRIDGE_CONTROL, &pci_bctl);
996 +       pci_write_config_word(sbr_list.bridge, PCI_BRIDGE_CONTROL, pci_bctl | PCI_BRIDGE_CTL_BUS_RESET);
997 +       msleep(200);
998 +       pci_write_config_word(sbr_list.bridge, PCI_BRIDGE_CONTROL, pci_bctl);
999 +       msleep(200);
1000 +       
1001 +       list_for_each_entry(entry, &sbr_list.dev_list, dev_list) {
1002 +               pciback_reload_config_space(entry->dev);
1003 +       }
1004 +       
1005 +       pci_unblock_user_cfg_access(dev);
1006 +
1007 +       pciback_cleanup_sbr_list(&sbr_list);
1008 +
1009 +       return 0;
1010 +}
1011 +
1012 +/* This function is used to do a function level reset on a singe 
1013 + * device/function. FLRs must be done on devices before they are 
1014 + * unassigned from one domain and passed through to another. The 
1015 + * preferred method is to do an actual FLR on the device but the 
1016 + * functionality may not be present or exposed. In the later case
1017 + * we attempt to locate the capability even though it is not 
1018 + * chained into the capabilities list.
1019 + *
1020 + * In some cases, there is no way to perform the actual FLR so we 
1021 + * fall back to some alternate methods (which are not as effective
1022 + * or useful).
1023 + */
1024 +void pciback_flr_device(struct pci_dev *dev)
1025 +{
1026 +       struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
1027 +       int err = 0;
1028 +
1029 +       if (dev_data->no_flr) {
1030 +               dev_dbg(&dev->dev, "FLR disabled for device\n");
1031 +               return;
1032 +       }
1033 +       dev_dbg(&dev->dev, "FLR invoked for device\n");
1034 +
1035 +       do {
1036 +               /* First, always try to do an FLR */
1037 +               if (dev_data->dev_type == PCIBACK_TYPE_PCIe_ENDPOINT &&
1038 +                       dev_data->exp_flr_offset != 0) {
1039 +                       pciback_do_pcie_flr(dev, dev_data->exp_flr_offset);
1040 +                       break;
1041 +               }
1042 +               if (dev_data->dev_type == PCIBACK_TYPE_PCI &&
1043 +                       dev_data->af_flr_offset != 0) {
1044 +                       pciback_do_pci_flr(dev, dev_data->af_flr_offset, 1);
1045 +                       break;
1046 +               }
1047 +               
1048 +               /* Next for integrated devices on the host bus 0, try some other methods */
1049 +               if (dev->bus->number == 0) {
1050 +                       err = pciback_do_vendor_specific_reset(dev);
1051 +                       if (err && dev_data->use_d3r)
1052 +                               err = pciback_do_dstate_transition_reset(dev);
1053 +                       if (err)
1054 +                               dev_warn(&dev->dev, "FLR functionality not supported; "
1055 +                                               "attempts to use vendor FLR or D-states unsuccessful\n");
1056 +                       break;
1057 +               }
1058 +
1059 +               /* Else attempt a secondary bus reset if all conditions are met */
1060 +               if (dev_data->use_sbr) {
1061 +                       err = pciback_do_secondary_bus_reset(dev, dev_data->dev_type);
1062 +                       if (err)
1063 +                               dev_warn(&dev->dev, "FLR functionality not supported; "
1064 +                                               "attempts to use secondary bus reset unsuccessful;\n");
1065 +                       break;
1066 +               }
1067 +
1068 +               err = -ENODEV;          
1069 +       } while (0);
1070 +
1071 +       if (err)
1072 +               dev_warn(&dev->dev, "FLR not performed for device\n");
1073 +}
1074 +
1075 +/* Helper used to location the FLR capabilities for a PCIe device.
1076 + * When the capability cannot be found in the chain but is present,
1077 + * special logic is used to attempt to locate functionality.
1078 + *
1079 + * returns: the offset to the capability, zero if not found.
1080 + */
1081 +static int pciback_find_pcie_flr_caps(struct pci_dev *dev)
1082 +{
1083 +       int exp_pos;
1084 +       u32 cap = 0;
1085 +
1086 +       /* First look for the PCIe FLR capabilities using the capabilities list */
1087 +       exp_pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1088 +       if (exp_pos) {
1089 +               pci_read_config_dword(dev, exp_pos + PCI_EXP_DEVCAP, &cap);
1090 +               if (cap & PCI_EXP_DEVCAP_FLR) {
1091 +                       return exp_pos;
1092 +               }
1093 +       }
1094 +
1095 +       return 0;
1096 +}
1097 +
1098 +/* Helper used to location the AF FLR capabilities for a PCI device.
1099 + * When the capability cannot be found in the chain but is present,
1100 + * special logic is used to attempt to locate functionality.
1101 + *
1102 + * returns: the offset to the capability, zero if not found.
1103 + */
1104 +static int pciback_find_pci_flr_caps(struct pci_dev *dev)
1105 +{
1106 +       struct pci_dev *gmch;
1107 +       int af_pos;
1108 +       u16 device_id;
1109 +       u8 cap = 0, reg8 = 0;
1110 +
1111 +       /* First look for the PCI AF capabilities for FLR using the capabilities list. This
1112 +        * is only used on the devices on the root/host bus (integrated devices). 
1113 +        */
1114 +       if (dev->bus->number != 0)
1115 +               return 0;
1116 +
1117 +       af_pos = pci_find_capability(dev, PCI_CAP_ID_AF);
1118 +       if (af_pos) {
1119 +               pci_read_config_byte(dev, af_pos + PCI_AF_DEVCAP, &cap);
1120 +               if (cap & PCI_AF_CAP_FLR) {
1121 +                       return af_pos;
1122 +               }
1123 +       }
1124 +
1125 +       /* Next look for the unchained AF capabilities for FLR using specific 
1126 +        * logic. Currently only the graphics device on the Intel Q45 etc 
1127 +        * systems has special logic for locating the hidden FLR caps.
1128 +     */
1129 +       do {
1130 +               if (dev->bus->number != 0 || dev->devfn != PCI_DEVFN(2,0) ||
1131 +                       dev->vendor != PCIBACK_VENDOR_INTEL || (dev->class >> 8) != PCIBACK_CLASS_ID_VGA)
1132 +                       break;
1133 +
1134 +               /* Locate the GMCH (north bridge) and test for specific Intel devices */
1135 +               gmch = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
1136 +               if (!gmch)
1137 +                       break;
1138 +
1139 +               device_id = gmch->device;
1140 +               pci_dev_put(gmch);
1141 +
1142 +               if (device_id != PCI_DEVICE_ID_INTEL_GMCHQ45 &&
1143 +                       device_id != PCI_DEVICE_ID_INTEL_GMCHG45 &&
1144 +                       device_id != PCI_DEVICE_ID_INTEL_GMCHG41)
1145 +                       break;
1146 +               
1147 +               /* Correct device and platform, assume AF offset */
1148 +               af_pos = PCIBACK_IGFX_CAP13_OFFSET;
1149 +               pci_read_config_byte(dev, af_pos + PCI_AF_LENFLD, &reg8);
1150 +               if (reg8 == PCI_AF_LENGTH) {
1151 +                       pci_read_config_byte(dev, af_pos + PCI_AF_DEVCAP, &cap);
1152 +                       if (cap & PCI_AF_CAP_FLR) {
1153 +                               return af_pos;
1154 +                       }
1155 +               }
1156 +       } while (0);
1157 +
1158 +       /* Else not found */
1159 +       return 0;
1160 +}
1161 +
1162 +/* Classify the device, specifically determine if it is PCIe/PCI 
1163 + * and whether it is a PCIe endpoint, bridge, or other PCI device. 
1164 + */
1165 +void pciback_classify_device(struct pci_dev *dev)
1166 +{
1167 +       struct pciback_dev_data *dev_data;
1168 +       int exp_pos;
1169 +       u16 exp_caps = 0;
1170 +
1171 +       dev_data = pci_get_drvdata(dev);
1172 +       dev_data->dev_type = PCIBACK_TYPE_UNKNOWN;
1173 +
1174 +       exp_pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1175 +       
1176 +       if ((dev->class >> 8) != DEV_CLASS_PCI_PCI_BRIDGE) {
1177 +               if (exp_pos != 0) {
1178 +                       dev_data->dev_type = PCIBACK_TYPE_PCIe_ENDPOINT;
1179 +                       dev_data->exp_flr_offset = pciback_find_pcie_flr_caps(dev);
1180 +               } else {
1181 +                       dev_data->dev_type = PCIBACK_TYPE_PCI;
1182 +                       dev_data->af_flr_offset = pciback_find_pci_flr_caps(dev);
1183 +               }
1184 +               goto classify_done;
1185 +       }
1186 +       
1187 +       if (exp_pos == 0) {
1188 +               dev_data->dev_type = PCIBACK_TYPE_PCI_BRIDGE;
1189 +               goto classify_done;
1190 +       }
1191 +
1192 +       pci_read_config_word(dev, exp_pos + PCI_EXP_FLAGS, &exp_caps);
1193 +       dev_data->dev_type = (((exp_caps & PCI_EXP_FLAGS_TYPE) >> 4) == PCI_EXP_TYPE_PCI_BRIDGE) ? PCIBACK_TYPE_PCI_BRIDGE : PCIBACK_TYPE_PCIe_BRIDGE;
1194 +
1195 +classify_done:
1196 +
1197 +       return;
1198 +}
1199 +
1200  extern wait_queue_head_t aer_wait_queue;
1201  extern struct workqueue_struct *pciback_wq;
1202  /*
1203 @@ -132,3 +719,51 @@
1204  
1205         return IRQ_HANDLED;
1206  }
1207 +
1208 +/* Helper routine used to parse command line parameters passed to the 
1209 + * pciback module from the boot loader. These params all have the form
1210 + * of a list of one or more devices, e.g.:
1211 + * (XXXX:XX:XX.X)(XXXX:XX:XX.X)
1212 + * Which is: (domain/segment:bus:dev.func)
1213 + */
1214 +int pciback_parse_device_params(const char *device_args, int type, 
1215 +                       int (*add_func) (int domain, int bus, int slot, int func, int type))
1216 +{
1217 +       int pos = 0;
1218 +       int err = 0;
1219 +       int domain, bus, slot, func;
1220 +       int parsed;
1221 +
1222 +       if (device_args && *device_args) {
1223 +               do {
1224 +                       parsed = 0;
1225 +
1226 +                       err = sscanf(device_args + pos,
1227 +                                    " (%x:%x:%x.%x) %n",
1228 +                                    &domain, &bus, &slot, &func, &parsed);
1229 +                       if (err != 4) {
1230 +                               domain = 0;
1231 +                               err = sscanf(device_args + pos,
1232 +                                            " (%x:%x.%x) %n",
1233 +                                            &bus, &slot, &func, &parsed);
1234 +                               if (err != 3)
1235 +                                       goto parse_error;
1236 +                       }
1237 +
1238 +                       err = add_func(domain, bus, slot, func, type);
1239 +                       if (err)
1240 +                               goto out;
1241 +
1242 +                       /* if parsed<=0, we've reached the end of the string */
1243 +                       pos += parsed;
1244 +               } while (parsed > 0 && device_args[pos]);
1245 +       }
1246 +
1247 +out:
1248 +       return err;
1249 +
1250 +parse_error:
1251 +       printk(KERN_ERR "pciback: Error parsing device parameters \"%s\" at \"%s\"\n",
1252 +              device_args, device_args + pos);
1253 +       return -EINVAL;
1254 +}
1255 diff --git a/drivers/xen/pciback/slot.c b/drivers/xen/pciback/slot.c
1256 --- a/drivers/xen/pciback/slot.c
1257 +++ b/drivers/xen/pciback/slot.c
1258 @@ -109,7 +109,7 @@
1259         spin_unlock_irqrestore(&slot_dev->lock, flags);
1260  
1261         if (found_dev)
1262 -               pcistub_put_pci_dev(found_dev);
1263 +               pcistub_put_pci_dev(found_dev, 0);
1264  }
1265  
1266  int pciback_init_devices(struct pciback_device *pdev)
1267 @@ -149,7 +149,7 @@
1268                 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
1269                         dev = slot_dev->slots[bus][slot];
1270                         if (dev != NULL)
1271 -                               pcistub_put_pci_dev(dev);
1272 +                               pcistub_put_pci_dev(dev, 0);
1273                 }
1274  
1275         kfree(slot_dev);
1276 diff --git a/drivers/xen/pciback/vpci.c b/drivers/xen/pciback/vpci.c
1277 --- a/drivers/xen/pciback/vpci.c
1278 +++ b/drivers/xen/pciback/vpci.c
1279 @@ -162,7 +162,7 @@
1280         spin_unlock_irqrestore(&vpci_dev->lock, flags);
1281  
1282         if (found_dev)
1283 -               pcistub_put_pci_dev(found_dev);
1284 +               pcistub_put_pci_dev(found_dev, 0);
1285  }
1286  
1287  int pciback_init_devices(struct pciback_device *pdev)
1288 @@ -202,7 +202,7 @@
1289                 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
1290                                          list) {
1291                         list_del(&e->list);
1292 -                       pcistub_put_pci_dev(e->dev);
1293 +                       pcistub_put_pci_dev(e->dev, 0);
1294                         kfree(e);
1295                 }
1296         }
1297 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
1298 --- a/include/linux/pci_ids.h
1299 +++ b/include/linux/pci_ids.h
1300 @@ -2501,6 +2501,14 @@
1301  #define PCI_DEVICE_ID_INTEL_IXP2800    0x9004
1302  #define PCI_DEVICE_ID_INTEL_S21152BB   0xb152
1303  
1304 +#define PCI_DEVICE_ID_INTEL_GMCHQ45 0x2e10
1305 +#define PCI_DEVICE_ID_INTEL_GMCHG45 0x2e20
1306 +#define PCI_DEVICE_ID_INTEL_MCHP45  0x2e20
1307 +#define PCI_DEVICE_ID_INTEL_GMCHG41 0x2e30
1308 +#define PCI_DEVICE_ID_INTEL_GMCHGM45 0x2a40
1309 +
1310 +#define PCI_DEVICE_ID_INTEL_GMCHG41 0x2e30
1311 +
1312  #define PCI_VENDOR_ID_SCALEMP          0x8686
1313  #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010
1314  
1315 diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
1316 --- a/include/linux/pci_regs.h
1317 +++ b/include/linux/pci_regs.h
1318 @@ -210,6 +210,7 @@
1319  #define  PCI_CAP_ID_AGP3       0x0E    /* AGP Target PCI-PCI bridge */
1320  #define  PCI_CAP_ID_EXP        0x10    /* PCI Express */
1321  #define  PCI_CAP_ID_MSIX       0x11    /* MSI-X */
1322 +#define  PCI_CAP_ID_AF      0x13    /* Advanced Features Capability */
1323  #define PCI_CAP_LIST_NEXT      1       /* Next capability in the list */
1324  #define PCI_CAP_FLAGS          2       /* Capability defined flags (16 bits) */
1325  #define PCI_CAP_SIZEOF         4
1326 @@ -239,6 +240,11 @@
1327  #define  PCI_PM_CTRL_DATA_SEL_MASK     0x1e00  /* Data select (??) */
1328  #define  PCI_PM_CTRL_DATA_SCALE_MASK   0x6000  /* Data scale (??) */
1329  #define  PCI_PM_CTRL_PME_STATUS        0x8000  /* PME pin status */
1330 +#define  PCI_PM_CTRL_DATA_DSTATE_MASK 0x3      /* D0 - D3 */
1331 +#define  PCI_PM_CTRL_D0 0x0
1332 +#define  PCI_PM_CTRL_D1 0x1
1333 +#define  PCI_PM_CTRL_D2 0x2
1334 +#define  PCI_PM_CTRL_D3HOT 0x3
1335  #define PCI_PM_PPB_EXTENSIONS  6       /* PPB support extensions (??) */
1336  #define  PCI_PM_PPB_B2_B3      0x40    /* Stop clock when in D3hot (??) */
1337  #define  PCI_PM_BPCC_ENABLE    0x80    /* Bus power/clock control enable (??) */
1338 @@ -558,6 +564,17 @@
1339  #define  PCI_ARI_CTRL_ACS      0x0002  /* ACS Function Groups Enable */
1340  #define  PCI_ARI_CTRL_FG(x)    (((x) >> 4) & 7) /* Function Group */
1341  
1342 +/* Advanced Features Capability */
1343 +#define PCI_AF_LENFLD    0x02 /* Device length offset */
1344 +#define  PCI_AF_LENGTH   0x06
1345 +#define PCI_AF_DEVCAP    0x03 /* Device capabilities offset */
1346 +#define  PCI_AF_CAP_TP   0x01
1347 +#define  PCI_AF_CAP_FLR  0x02
1348 +#define PCI_AF_CTRL      0x04 /* Device CTRL offset */
1349 +#define  PCI_AF_CTRL_FLR 0x01
1350 +#define PCI_AF_STA       0x05 /* Device STATUS offset */
1351 +#define  PCI_AF_STA_TP   0x01
1352 +
1353  /* Single Root I/O Virtualization */
1354  #define PCI_SRIOV_CAP          0x04    /* SR-IOV Capabilities */
1355  #define  PCI_SRIOV_CAP_VFM     0x01    /* VF Migration Capable */