aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-24 15:36:56 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-24 15:36:56 -0400
commitb9f12a5d97f652c77ef6803dccd0d40d1290f5be (patch)
tree8f58c8620ffef0d350a5ec022feda492a96b179a /drivers/xen
parent9d8dc3e529a19e427fd379118acd132520935c5d (diff)
parent9a3c4145af32125c5ee39c0272662b47307a8323 (diff)
Merge tag 'v3.16-rc6' into next
Merge with mainline to bring in changes to MFD to allow merging ipaq-micro-ts driver.
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/balloon.c12
-rw-r--r--drivers/xen/events/events_base.c17
-rw-r--r--drivers/xen/events/events_fifo.c41
-rw-r--r--drivers/xen/grant-table.c3
-rw-r--r--drivers/xen/manage.c50
-rw-r--r--drivers/xen/xen-acpi-processor.c4
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c25
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c4
-rw-r--r--drivers/xen/xen-pciback/xenbus.c4
9 files changed, 77 insertions, 83 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index b7a506f2bb14..5c660c77f03b 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -426,20 +426,18 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
426 * p2m are consistent. 426 * p2m are consistent.
427 */ 427 */
428 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 428 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
429 unsigned long p;
430 struct page *scratch_page = get_balloon_scratch_page();
431
432 if (!PageHighMem(page)) { 429 if (!PageHighMem(page)) {
430 struct page *scratch_page = get_balloon_scratch_page();
431
433 ret = HYPERVISOR_update_va_mapping( 432 ret = HYPERVISOR_update_va_mapping(
434 (unsigned long)__va(pfn << PAGE_SHIFT), 433 (unsigned long)__va(pfn << PAGE_SHIFT),
435 pfn_pte(page_to_pfn(scratch_page), 434 pfn_pte(page_to_pfn(scratch_page),
436 PAGE_KERNEL_RO), 0); 435 PAGE_KERNEL_RO), 0);
437 BUG_ON(ret); 436 BUG_ON(ret);
438 }
439 p = page_to_pfn(scratch_page);
440 __set_phys_to_machine(pfn, pfn_to_mfn(p));
441 437
442 put_balloon_scratch_page(); 438 put_balloon_scratch_page();
439 }
440 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
443 } 441 }
444#endif 442#endif
445 443
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index dfa12a4a0a48..c919d3d5c845 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -390,22 +390,7 @@ static void xen_irq_init(unsigned irq)
390 390
391static int __must_check xen_allocate_irqs_dynamic(int nvec) 391static int __must_check xen_allocate_irqs_dynamic(int nvec)
392{ 392{
393 int first = 0; 393 int i, irq = irq_alloc_descs(-1, 0, nvec, -1);
394 int i, irq;
395
396#ifdef CONFIG_X86_IO_APIC
397 /*
398 * For an HVM guest or domain 0 which see "real" (emulated or
399 * actual respectively) GSIs we allocate dynamic IRQs
400 * e.g. those corresponding to event channels or MSIs
401 * etc. from the range above those "real" GSIs to avoid
402 * collisions.
403 */
404 if (xen_initial_domain() || xen_hvm_domain())
405 first = get_nr_irqs_gsi();
406#endif
407
408 irq = irq_alloc_descs_from(first, nvec, -1);
409 394
410 if (irq >= 0) { 395 if (irq >= 0) {
411 for (i = 0; i < nvec; i++) 396 for (i = 0; i < nvec; i++)
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 96109a9972b6..84b4bfb84344 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -66,7 +66,22 @@ static DEFINE_PER_CPU(struct evtchn_fifo_queue, cpu_queue);
66static event_word_t *event_array[MAX_EVENT_ARRAY_PAGES] __read_mostly; 66static event_word_t *event_array[MAX_EVENT_ARRAY_PAGES] __read_mostly;
67static unsigned event_array_pages __read_mostly; 67static unsigned event_array_pages __read_mostly;
68 68
69/*
70 * sync_set_bit() and friends must be unsigned long aligned on non-x86
71 * platforms.
72 */
73#if !defined(CONFIG_X86) && BITS_PER_LONG > 32
74
75#define BM(w) (unsigned long *)((unsigned long)w & ~0x7UL)
76#define EVTCHN_FIFO_BIT(b, w) \
77 (((unsigned long)w & 0x4UL) ? (EVTCHN_FIFO_ ##b + 32) : EVTCHN_FIFO_ ##b)
78
79#else
80
69#define BM(w) ((unsigned long *)(w)) 81#define BM(w) ((unsigned long *)(w))
82#define EVTCHN_FIFO_BIT(b, w) EVTCHN_FIFO_ ##b
83
84#endif
70 85
71static inline event_word_t *event_word_from_port(unsigned port) 86static inline event_word_t *event_word_from_port(unsigned port)
72{ 87{
@@ -161,33 +176,38 @@ static void evtchn_fifo_bind_to_cpu(struct irq_info *info, unsigned cpu)
161static void evtchn_fifo_clear_pending(unsigned port) 176static void evtchn_fifo_clear_pending(unsigned port)
162{ 177{
163 event_word_t *word = event_word_from_port(port); 178 event_word_t *word = event_word_from_port(port);
164 sync_clear_bit(EVTCHN_FIFO_PENDING, BM(word)); 179 sync_clear_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word));
165} 180}
166 181
167static void evtchn_fifo_set_pending(unsigned port) 182static void evtchn_fifo_set_pending(unsigned port)
168{ 183{
169 event_word_t *word = event_word_from_port(port); 184 event_word_t *word = event_word_from_port(port);
170 sync_set_bit(EVTCHN_FIFO_PENDING, BM(word)); 185 sync_set_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word));
171} 186}
172 187
173static bool evtchn_fifo_is_pending(unsigned port) 188static bool evtchn_fifo_is_pending(unsigned port)
174{ 189{
175 event_word_t *word = event_word_from_port(port); 190 event_word_t *word = event_word_from_port(port);
176 return sync_test_bit(EVTCHN_FIFO_PENDING, BM(word)); 191 return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word));
177} 192}
178 193
179static bool evtchn_fifo_test_and_set_mask(unsigned port) 194static bool evtchn_fifo_test_and_set_mask(unsigned port)
180{ 195{
181 event_word_t *word = event_word_from_port(port); 196 event_word_t *word = event_word_from_port(port);
182 return sync_test_and_set_bit(EVTCHN_FIFO_MASKED, BM(word)); 197 return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word));
183} 198}
184 199
185static void evtchn_fifo_mask(unsigned port) 200static void evtchn_fifo_mask(unsigned port)
186{ 201{
187 event_word_t *word = event_word_from_port(port); 202 event_word_t *word = event_word_from_port(port);
188 sync_set_bit(EVTCHN_FIFO_MASKED, BM(word)); 203 sync_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word));
189} 204}
190 205
206static bool evtchn_fifo_is_masked(unsigned port)
207{
208 event_word_t *word = event_word_from_port(port);
209 return sync_test_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word));
210}
191/* 211/*
192 * Clear MASKED, spinning if BUSY is set. 212 * Clear MASKED, spinning if BUSY is set.
193 */ 213 */
@@ -211,7 +231,7 @@ static void evtchn_fifo_unmask(unsigned port)
211 BUG_ON(!irqs_disabled()); 231 BUG_ON(!irqs_disabled());
212 232
213 clear_masked(word); 233 clear_masked(word);
214 if (sync_test_bit(EVTCHN_FIFO_PENDING, BM(word))) { 234 if (evtchn_fifo_is_pending(port)) {
215 struct evtchn_unmask unmask = { .port = port }; 235 struct evtchn_unmask unmask = { .port = port };
216 (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask); 236 (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
217 } 237 }
@@ -243,7 +263,7 @@ static void handle_irq_for_port(unsigned port)
243 263
244static void consume_one_event(unsigned cpu, 264static void consume_one_event(unsigned cpu,
245 struct evtchn_fifo_control_block *control_block, 265 struct evtchn_fifo_control_block *control_block,
246 unsigned priority, uint32_t *ready) 266 unsigned priority, unsigned long *ready)
247{ 267{
248 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu); 268 struct evtchn_fifo_queue *q = &per_cpu(cpu_queue, cpu);
249 uint32_t head; 269 uint32_t head;
@@ -273,10 +293,9 @@ static void consume_one_event(unsigned cpu,
273 * copy of the ready word. 293 * copy of the ready word.
274 */ 294 */
275 if (head == 0) 295 if (head == 0)
276 clear_bit(priority, BM(ready)); 296 clear_bit(priority, ready);
277 297
278 if (sync_test_bit(EVTCHN_FIFO_PENDING, BM(word)) 298 if (evtchn_fifo_is_pending(port) && !evtchn_fifo_is_masked(port))
279 && !sync_test_bit(EVTCHN_FIFO_MASKED, BM(word)))
280 handle_irq_for_port(port); 299 handle_irq_for_port(port);
281 300
282 q->head[priority] = head; 301 q->head[priority] = head;
@@ -285,7 +304,7 @@ static void consume_one_event(unsigned cpu,
285static void evtchn_fifo_handle_events(unsigned cpu) 304static void evtchn_fifo_handle_events(unsigned cpu)
286{ 305{
287 struct evtchn_fifo_control_block *control_block; 306 struct evtchn_fifo_control_block *control_block;
288 uint32_t ready; 307 unsigned long ready;
289 unsigned q; 308 unsigned q;
290 309
291 control_block = per_cpu(cpu_control_block, cpu); 310 control_block = per_cpu(cpu_control_block, cpu);
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 6d325bda76da..5d4de88fe5b8 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -1168,7 +1168,8 @@ int gnttab_resume(void)
1168 1168
1169int gnttab_suspend(void) 1169int gnttab_suspend(void)
1170{ 1170{
1171 gnttab_interface->unmap_frames(); 1171 if (!xen_feature(XENFEAT_auto_translated_physmap))
1172 gnttab_interface->unmap_frames();
1172 return 0; 1173 return 0;
1173} 1174}
1174 1175
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 32f9236c959f..5f1e1f3cd186 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -41,9 +41,6 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
41 41
42struct suspend_info { 42struct suspend_info {
43 int cancelled; 43 int cancelled;
44 unsigned long arg; /* extra hypercall argument */
45 void (*pre)(void);
46 void (*post)(int cancelled);
47}; 44};
48 45
49static RAW_NOTIFIER_HEAD(xen_resume_notifier); 46static RAW_NOTIFIER_HEAD(xen_resume_notifier);
@@ -61,26 +58,6 @@ void xen_resume_notifier_unregister(struct notifier_block *nb)
61EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); 58EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister);
62 59
63#ifdef CONFIG_HIBERNATE_CALLBACKS 60#ifdef CONFIG_HIBERNATE_CALLBACKS
64static void xen_hvm_post_suspend(int cancelled)
65{
66 xen_arch_hvm_post_suspend(cancelled);
67 gnttab_resume();
68}
69
70static void xen_pre_suspend(void)
71{
72 xen_mm_pin_all();
73 gnttab_suspend();
74 xen_arch_pre_suspend();
75}
76
77static void xen_post_suspend(int cancelled)
78{
79 xen_arch_post_suspend(cancelled);
80 gnttab_resume();
81 xen_mm_unpin_all();
82}
83
84static int xen_suspend(void *data) 61static int xen_suspend(void *data)
85{ 62{
86 struct suspend_info *si = data; 63 struct suspend_info *si = data;
@@ -94,22 +71,23 @@ static int xen_suspend(void *data)
94 return err; 71 return err;
95 } 72 }
96 73
97 if (si->pre) 74 gnttab_suspend();
98 si->pre(); 75 xen_arch_pre_suspend();
99 76
100 /* 77 /*
101 * This hypercall returns 1 if suspend was cancelled 78 * This hypercall returns 1 if suspend was cancelled
102 * or the domain was merely checkpointed, and 0 if it 79 * or the domain was merely checkpointed, and 0 if it
103 * is resuming in a new domain. 80 * is resuming in a new domain.
104 */ 81 */
105 si->cancelled = HYPERVISOR_suspend(si->arg); 82 si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
83 ? virt_to_mfn(xen_start_info)
84 : 0);
106 85
107 if (si->post) 86 xen_arch_post_suspend(si->cancelled);
108 si->post(si->cancelled); 87 gnttab_resume();
109 88
110 if (!si->cancelled) { 89 if (!si->cancelled) {
111 xen_irq_resume(); 90 xen_irq_resume();
112 xen_console_resume();
113 xen_timer_resume(); 91 xen_timer_resume();
114 } 92 }
115 93
@@ -154,18 +132,12 @@ static void do_suspend(void)
154 132
155 si.cancelled = 1; 133 si.cancelled = 1;
156 134
157 if (xen_hvm_domain()) {
158 si.arg = 0UL;
159 si.pre = NULL;
160 si.post = &xen_hvm_post_suspend;
161 } else {
162 si.arg = virt_to_mfn(xen_start_info);
163 si.pre = &xen_pre_suspend;
164 si.post = &xen_post_suspend;
165 }
166
167 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 135 err = stop_machine(xen_suspend, &si, cpumask_of(0));
168 136
137 /* Resume console as early as possible. */
138 if (!si.cancelled)
139 xen_console_resume();
140
169 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL); 141 raw_notifier_call_chain(&xen_resume_notifier, 0, NULL);
170 142
171 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 143 dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index 82358d14ecf1..59fc190f1e92 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -127,7 +127,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
127 pr_debug(" C%d: %s %d uS\n", 127 pr_debug(" C%d: %s %d uS\n",
128 cx->type, cx->desc, (u32)cx->latency); 128 cx->type, cx->desc, (u32)cx->latency);
129 } 129 }
130 } else if (ret != -EINVAL) 130 } else if ((ret != -EINVAL) && (ret != -ENOSYS))
131 /* EINVAL means the ACPI ID is incorrect - meaning the ACPI 131 /* EINVAL means the ACPI ID is incorrect - meaning the ACPI
132 * table is referencing a non-existing CPU - which can happen 132 * table is referencing a non-existing CPU - which can happen
133 * with broken ACPI tables. */ 133 * with broken ACPI tables. */
@@ -259,7 +259,7 @@ static int push_pxx_to_hypervisor(struct acpi_processor *_pr)
259 (u32) perf->states[i].power, 259 (u32) perf->states[i].power,
260 (u32) perf->states[i].transition_latency); 260 (u32) perf->states[i].transition_latency);
261 } 261 }
262 } else if (ret != -EINVAL) 262 } else if ((ret != -EINVAL) && (ret != -ENOSYS))
263 /* EINVAL means the ACPI ID is incorrect - meaning the ACPI 263 /* EINVAL means the ACPI ID is incorrect - meaning the ACPI
264 * table is referencing a non-existing CPU - which can happen 264 * table is referencing a non-existing CPU - which can happen
265 * with broken ACPI tables. */ 265 * with broken ACPI tables. */
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 62fcd485f0a7..d57a173685f3 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -242,6 +242,15 @@ struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
242 return found_dev; 242 return found_dev;
243} 243}
244 244
245/*
246 * Called when:
247 * - XenBus state has been reconfigure (pci unplug). See xen_pcibk_remove_device
248 * - XenBus state has been disconnected (guest shutdown). See xen_pcibk_xenbus_remove
249 * - 'echo BDF > unbind' on pciback module with no guest attached. See pcistub_remove
250 * - 'echo BDF > unbind' with a guest still using it. See pcistub_remove
251 *
252 * As such we have to be careful.
253 */
245void pcistub_put_pci_dev(struct pci_dev *dev) 254void pcistub_put_pci_dev(struct pci_dev *dev)
246{ 255{
247 struct pcistub_device *psdev, *found_psdev = NULL; 256 struct pcistub_device *psdev, *found_psdev = NULL;
@@ -272,16 +281,16 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
272 * and want to inhibit the user from fiddling with 'reset' 281 * and want to inhibit the user from fiddling with 'reset'
273 */ 282 */
274 pci_reset_function(dev); 283 pci_reset_function(dev);
275 pci_restore_state(psdev->dev); 284 pci_restore_state(dev);
276 285
277 /* This disables the device. */ 286 /* This disables the device. */
278 xen_pcibk_reset_device(found_psdev->dev); 287 xen_pcibk_reset_device(dev);
279 288
280 /* And cleanup up our emulated fields. */ 289 /* And cleanup up our emulated fields. */
281 xen_pcibk_config_free_dyn_fields(found_psdev->dev); 290 xen_pcibk_config_reset_dev(dev);
282 xen_pcibk_config_reset_dev(found_psdev->dev); 291 xen_pcibk_config_free_dyn_fields(dev);
283 292
284 xen_unregister_device_domain_owner(found_psdev->dev); 293 xen_unregister_device_domain_owner(dev);
285 294
286 spin_lock_irqsave(&found_psdev->lock, flags); 295 spin_lock_irqsave(&found_psdev->lock, flags);
287 found_psdev->pdev = NULL; 296 found_psdev->pdev = NULL;
@@ -493,6 +502,8 @@ static int pcistub_seize(struct pci_dev *dev)
493 return err; 502 return err;
494} 503}
495 504
505/* Called when 'bind'. This means we must _NOT_ call pci_reset_function or
506 * other functions that take the sysfs lock. */
496static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) 507static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
497{ 508{
498 int err = 0; 509 int err = 0;
@@ -520,6 +531,8 @@ out:
520 return err; 531 return err;
521} 532}
522 533
534/* Called when 'unbind'. This means we must _NOT_ call pci_reset_function or
535 * other functions that take the sysfs lock. */
523static void pcistub_remove(struct pci_dev *dev) 536static void pcistub_remove(struct pci_dev *dev)
524{ 537{
525 struct pcistub_device *psdev, *found_psdev = NULL; 538 struct pcistub_device *psdev, *found_psdev = NULL;
@@ -551,6 +564,8 @@ static void pcistub_remove(struct pci_dev *dev)
551 pr_warn("****** shutdown driver domain before binding device\n"); 564 pr_warn("****** shutdown driver domain before binding device\n");
552 pr_warn("****** to other drivers or domains\n"); 565 pr_warn("****** to other drivers or domains\n");
553 566
567 /* N.B. This ends up calling pcistub_put_pci_dev which ends up
568 * doing the FLR. */
554 xen_pcibk_release_pci_dev(found_psdev->pdev, 569 xen_pcibk_release_pci_dev(found_psdev->pdev,
555 found_psdev->dev); 570 found_psdev->dev);
556 } 571 }
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 607e41460c0d..c4a0666de6f5 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -348,9 +348,9 @@ void xen_pcibk_do_op(struct work_struct *data)
348 notify_remote_via_irq(pdev->evtchn_irq); 348 notify_remote_via_irq(pdev->evtchn_irq);
349 349
350 /* Mark that we're done. */ 350 /* Mark that we're done. */
351 smp_mb__before_clear_bit(); /* /after/ clearing PCIF_active */ 351 smp_mb__before_atomic(); /* /after/ clearing PCIF_active */
352 clear_bit(_PDEVF_op_active, &pdev->flags); 352 clear_bit(_PDEVF_op_active, &pdev->flags);
353 smp_mb__after_clear_bit(); /* /before/ final check for work */ 353 smp_mb__after_atomic(); /* /before/ final check for work */
354 354
355 /* Check to see if the driver domain tried to start another request in 355 /* Check to see if the driver domain tried to start another request in
356 * between clearing _XEN_PCIF_active and clearing _PDEVF_op_active. 356 * between clearing _XEN_PCIF_active and clearing _PDEVF_op_active.
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index a9ed867afaba..4a7e6e0a5f4c 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -93,6 +93,8 @@ static void free_pdev(struct xen_pcibk_device *pdev)
93 93
94 xen_pcibk_disconnect(pdev); 94 xen_pcibk_disconnect(pdev);
95 95
96 /* N.B. This calls pcistub_put_pci_dev which does the FLR on all
97 * of the PCIe devices. */
96 xen_pcibk_release_devices(pdev); 98 xen_pcibk_release_devices(pdev);
97 99
98 dev_set_drvdata(&pdev->xdev->dev, NULL); 100 dev_set_drvdata(&pdev->xdev->dev, NULL);
@@ -286,6 +288,8 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev,
286 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); 288 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id);
287 xen_unregister_device_domain_owner(dev); 289 xen_unregister_device_domain_owner(dev);
288 290
291 /* N.B. This ends up calling pcistub_put_pci_dev which ends up
292 * doing the FLR. */
289 xen_pcibk_release_pci_dev(pdev, dev); 293 xen_pcibk_release_pci_dev(pdev, dev);
290 294
291out: 295out: