diff options
-rw-r--r-- | drivers/pci/msi.c | 425 | ||||
-rw-r--r-- | drivers/pci/msi.h | 7 |
2 files changed, 168 insertions, 264 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a32e75a4417e..da2c6c2b6b11 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/err.h> | ||
9 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
10 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
11 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
@@ -27,12 +28,6 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; | |||
27 | static kmem_cache_t* msi_cachep; | 28 | static kmem_cache_t* msi_cachep; |
28 | 29 | ||
29 | static int pci_msi_enable = 1; | 30 | static int pci_msi_enable = 1; |
30 | static int last_alloc_vector; | ||
31 | static int nr_released_vectors; | ||
32 | |||
33 | #ifndef CONFIG_X86_IO_APIC | ||
34 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; | ||
35 | #endif | ||
36 | 31 | ||
37 | static struct msi_ops *msi_ops; | 32 | static struct msi_ops *msi_ops; |
38 | 33 | ||
@@ -53,11 +48,11 @@ static int msi_cache_init(void) | |||
53 | return 0; | 48 | return 0; |
54 | } | 49 | } |
55 | 50 | ||
56 | static void msi_set_mask_bit(unsigned int vector, int flag) | 51 | static void msi_set_mask_bit(unsigned int irq, int flag) |
57 | { | 52 | { |
58 | struct msi_desc *entry; | 53 | struct msi_desc *entry; |
59 | 54 | ||
60 | entry = (struct msi_desc *)msi_desc[vector]; | 55 | entry = msi_desc[irq]; |
61 | if (!entry || !entry->dev || !entry->mask_base) | 56 | if (!entry || !entry->dev || !entry->mask_base) |
62 | return; | 57 | return; |
63 | switch (entry->msi_attrib.type) { | 58 | switch (entry->msi_attrib.type) { |
@@ -181,23 +176,23 @@ static void set_msi_affinity(unsigned int irq, cpumask_t cpu_mask) | |||
181 | #define set_msi_affinity NULL | 176 | #define set_msi_affinity NULL |
182 | #endif /* CONFIG_SMP */ | 177 | #endif /* CONFIG_SMP */ |
183 | 178 | ||
184 | static void mask_MSI_irq(unsigned int vector) | 179 | static void mask_MSI_irq(unsigned int irq) |
185 | { | 180 | { |
186 | msi_set_mask_bit(vector, 1); | 181 | msi_set_mask_bit(irq, 1); |
187 | } | 182 | } |
188 | 183 | ||
189 | static void unmask_MSI_irq(unsigned int vector) | 184 | static void unmask_MSI_irq(unsigned int irq) |
190 | { | 185 | { |
191 | msi_set_mask_bit(vector, 0); | 186 | msi_set_mask_bit(irq, 0); |
192 | } | 187 | } |
193 | 188 | ||
194 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) | 189 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) |
195 | { | 190 | { |
196 | struct msi_desc *entry; | 191 | struct msi_desc *entry; |
197 | unsigned long flags; | 192 | unsigned long flags; |
198 | 193 | ||
199 | spin_lock_irqsave(&msi_lock, flags); | 194 | spin_lock_irqsave(&msi_lock, flags); |
200 | entry = msi_desc[vector]; | 195 | entry = msi_desc[irq]; |
201 | if (!entry || !entry->dev) { | 196 | if (!entry || !entry->dev) { |
202 | spin_unlock_irqrestore(&msi_lock, flags); | 197 | spin_unlock_irqrestore(&msi_lock, flags); |
203 | return 0; | 198 | return 0; |
@@ -208,39 +203,39 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) | |||
208 | return 0; /* never anything pending */ | 203 | return 0; /* never anything pending */ |
209 | } | 204 | } |
210 | 205 | ||
211 | static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) | 206 | static unsigned int startup_msi_irq_w_maskbit(unsigned int irq) |
212 | { | 207 | { |
213 | startup_msi_irq_wo_maskbit(vector); | 208 | startup_msi_irq_wo_maskbit(irq); |
214 | unmask_MSI_irq(vector); | 209 | unmask_MSI_irq(irq); |
215 | return 0; /* never anything pending */ | 210 | return 0; /* never anything pending */ |
216 | } | 211 | } |
217 | 212 | ||
218 | static void shutdown_msi_irq(unsigned int vector) | 213 | static void shutdown_msi_irq(unsigned int irq) |
219 | { | 214 | { |
220 | struct msi_desc *entry; | 215 | struct msi_desc *entry; |
221 | unsigned long flags; | 216 | unsigned long flags; |
222 | 217 | ||
223 | spin_lock_irqsave(&msi_lock, flags); | 218 | spin_lock_irqsave(&msi_lock, flags); |
224 | entry = msi_desc[vector]; | 219 | entry = msi_desc[irq]; |
225 | if (entry && entry->dev) | 220 | if (entry && entry->dev) |
226 | entry->msi_attrib.state = 0; /* Mark it not active */ | 221 | entry->msi_attrib.state = 0; /* Mark it not active */ |
227 | spin_unlock_irqrestore(&msi_lock, flags); | 222 | spin_unlock_irqrestore(&msi_lock, flags); |
228 | } | 223 | } |
229 | 224 | ||
230 | static void end_msi_irq_wo_maskbit(unsigned int vector) | 225 | static void end_msi_irq_wo_maskbit(unsigned int irq) |
231 | { | 226 | { |
232 | move_native_irq(vector); | 227 | move_native_irq(irq); |
233 | ack_APIC_irq(); | 228 | ack_APIC_irq(); |
234 | } | 229 | } |
235 | 230 | ||
236 | static void end_msi_irq_w_maskbit(unsigned int vector) | 231 | static void end_msi_irq_w_maskbit(unsigned int irq) |
237 | { | 232 | { |
238 | move_native_irq(vector); | 233 | move_native_irq(irq); |
239 | unmask_MSI_irq(vector); | 234 | unmask_MSI_irq(irq); |
240 | ack_APIC_irq(); | 235 | ack_APIC_irq(); |
241 | } | 236 | } |
242 | 237 | ||
243 | static void do_nothing(unsigned int vector) | 238 | static void do_nothing(unsigned int irq) |
244 | { | 239 | { |
245 | } | 240 | } |
246 | 241 | ||
@@ -291,86 +286,7 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = { | |||
291 | .set_affinity = set_msi_affinity | 286 | .set_affinity = set_msi_affinity |
292 | }; | 287 | }; |
293 | 288 | ||
294 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); | 289 | static int msi_free_irq(struct pci_dev* dev, int irq); |
295 | static int assign_msi_vector(void) | ||
296 | { | ||
297 | static int new_vector_avail = 1; | ||
298 | int vector; | ||
299 | unsigned long flags; | ||
300 | |||
301 | /* | ||
302 | * msi_lock is provided to ensure that successful allocation of MSI | ||
303 | * vector is assigned unique among drivers. | ||
304 | */ | ||
305 | spin_lock_irqsave(&msi_lock, flags); | ||
306 | |||
307 | if (!new_vector_avail) { | ||
308 | int free_vector = 0; | ||
309 | |||
310 | /* | ||
311 | * vector_irq[] = -1 indicates that this specific vector is: | ||
312 | * - assigned for MSI (since MSI have no associated IRQ) or | ||
313 | * - assigned for legacy if less than 16, or | ||
314 | * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping | ||
315 | * vector_irq[] = 0 indicates that this vector, previously | ||
316 | * assigned for MSI, is freed by hotplug removed operations. | ||
317 | * This vector will be reused for any subsequent hotplug added | ||
318 | * operations. | ||
319 | * vector_irq[] > 0 indicates that this vector is assigned for | ||
320 | * IOxAPIC IRQs. This vector and its value provides a 1-to-1 | ||
321 | * vector-to-IOxAPIC IRQ mapping. | ||
322 | */ | ||
323 | for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { | ||
324 | if (vector_irq[vector] != 0) | ||
325 | continue; | ||
326 | free_vector = vector; | ||
327 | if (!msi_desc[vector]) | ||
328 | break; | ||
329 | else | ||
330 | continue; | ||
331 | } | ||
332 | if (!free_vector) { | ||
333 | spin_unlock_irqrestore(&msi_lock, flags); | ||
334 | return -EBUSY; | ||
335 | } | ||
336 | vector_irq[free_vector] = -1; | ||
337 | nr_released_vectors--; | ||
338 | spin_unlock_irqrestore(&msi_lock, flags); | ||
339 | if (msi_desc[free_vector] != NULL) { | ||
340 | struct pci_dev *dev; | ||
341 | int tail; | ||
342 | |||
343 | /* free all linked vectors before re-assign */ | ||
344 | do { | ||
345 | spin_lock_irqsave(&msi_lock, flags); | ||
346 | dev = msi_desc[free_vector]->dev; | ||
347 | tail = msi_desc[free_vector]->link.tail; | ||
348 | spin_unlock_irqrestore(&msi_lock, flags); | ||
349 | msi_free_vector(dev, tail, 1); | ||
350 | } while (free_vector != tail); | ||
351 | } | ||
352 | |||
353 | return free_vector; | ||
354 | } | ||
355 | vector = assign_irq_vector(AUTO_ASSIGN); | ||
356 | last_alloc_vector = vector; | ||
357 | if (vector == LAST_DEVICE_VECTOR) | ||
358 | new_vector_avail = 0; | ||
359 | |||
360 | spin_unlock_irqrestore(&msi_lock, flags); | ||
361 | return vector; | ||
362 | } | ||
363 | |||
364 | static int get_new_vector(void) | ||
365 | { | ||
366 | int vector = assign_msi_vector(); | ||
367 | |||
368 | if (vector > 0) | ||
369 | set_intr_gate(vector, interrupt[vector]); | ||
370 | |||
371 | return vector; | ||
372 | } | ||
373 | |||
374 | static int msi_init(void) | 290 | static int msi_init(void) |
375 | { | 291 | { |
376 | static int status = -ENOMEM; | 292 | static int status = -ENOMEM; |
@@ -394,13 +310,13 @@ static int msi_init(void) | |||
394 | } | 310 | } |
395 | 311 | ||
396 | if (! msi_ops) { | 312 | if (! msi_ops) { |
313 | pci_msi_enable = 0; | ||
397 | printk(KERN_WARNING | 314 | printk(KERN_WARNING |
398 | "PCI: MSI ops not registered. MSI disabled.\n"); | 315 | "PCI: MSI ops not registered. MSI disabled.\n"); |
399 | status = -EINVAL; | 316 | status = -EINVAL; |
400 | return status; | 317 | return status; |
401 | } | 318 | } |
402 | 319 | ||
403 | last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); | ||
404 | status = msi_cache_init(); | 320 | status = msi_cache_init(); |
405 | if (status < 0) { | 321 | if (status < 0) { |
406 | pci_msi_enable = 0; | 322 | pci_msi_enable = 0; |
@@ -408,23 +324,9 @@ static int msi_init(void) | |||
408 | return status; | 324 | return status; |
409 | } | 325 | } |
410 | 326 | ||
411 | if (last_alloc_vector < 0) { | ||
412 | pci_msi_enable = 0; | ||
413 | printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); | ||
414 | status = -EBUSY; | ||
415 | return status; | ||
416 | } | ||
417 | vector_irq[last_alloc_vector] = 0; | ||
418 | nr_released_vectors++; | ||
419 | |||
420 | return status; | 327 | return status; |
421 | } | 328 | } |
422 | 329 | ||
423 | static int get_msi_vector(struct pci_dev *dev) | ||
424 | { | ||
425 | return get_new_vector(); | ||
426 | } | ||
427 | |||
428 | static struct msi_desc* alloc_msi_entry(void) | 330 | static struct msi_desc* alloc_msi_entry(void) |
429 | { | 331 | { |
430 | struct msi_desc *entry; | 332 | struct msi_desc *entry; |
@@ -439,29 +341,45 @@ static struct msi_desc* alloc_msi_entry(void) | |||
439 | return entry; | 341 | return entry; |
440 | } | 342 | } |
441 | 343 | ||
442 | static void attach_msi_entry(struct msi_desc *entry, int vector) | 344 | static void attach_msi_entry(struct msi_desc *entry, int irq) |
443 | { | 345 | { |
444 | unsigned long flags; | 346 | unsigned long flags; |
445 | 347 | ||
446 | spin_lock_irqsave(&msi_lock, flags); | 348 | spin_lock_irqsave(&msi_lock, flags); |
447 | msi_desc[vector] = entry; | 349 | msi_desc[irq] = entry; |
448 | spin_unlock_irqrestore(&msi_lock, flags); | 350 | spin_unlock_irqrestore(&msi_lock, flags); |
449 | } | 351 | } |
450 | 352 | ||
451 | static void irq_handler_init(int cap_id, int pos, int mask) | 353 | static int create_msi_irq(struct hw_interrupt_type *handler) |
452 | { | 354 | { |
453 | unsigned long flags; | 355 | struct msi_desc *entry; |
356 | int irq; | ||
357 | |||
358 | entry = alloc_msi_entry(); | ||
359 | if (!entry) | ||
360 | return -ENOMEM; | ||
454 | 361 | ||
455 | spin_lock_irqsave(&irq_desc[pos].lock, flags); | 362 | irq = create_irq(); |
456 | if (cap_id == PCI_CAP_ID_MSIX) | 363 | if (irq < 0) { |
457 | irq_desc[pos].chip = &msix_irq_type; | 364 | kmem_cache_free(msi_cachep, entry); |
458 | else { | 365 | return -EBUSY; |
459 | if (!mask) | ||
460 | irq_desc[pos].chip = &msi_irq_wo_maskbit_type; | ||
461 | else | ||
462 | irq_desc[pos].chip = &msi_irq_w_maskbit_type; | ||
463 | } | 366 | } |
464 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); | 367 | |
368 | set_irq_chip(irq, handler); | ||
369 | set_irq_data(irq, entry); | ||
370 | |||
371 | return irq; | ||
372 | } | ||
373 | |||
374 | static void destroy_msi_irq(unsigned int irq) | ||
375 | { | ||
376 | struct msi_desc *entry; | ||
377 | |||
378 | entry = get_irq_data(irq); | ||
379 | set_irq_chip(irq, NULL); | ||
380 | set_irq_data(irq, NULL); | ||
381 | destroy_irq(irq); | ||
382 | kmem_cache_free(msi_cachep, entry); | ||
465 | } | 383 | } |
466 | 384 | ||
467 | static void enable_msi_mode(struct pci_dev *dev, int pos, int type) | 385 | static void enable_msi_mode(struct pci_dev *dev, int pos, int type) |
@@ -506,21 +424,21 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) | |||
506 | } | 424 | } |
507 | } | 425 | } |
508 | 426 | ||
509 | static int msi_lookup_vector(struct pci_dev *dev, int type) | 427 | static int msi_lookup_irq(struct pci_dev *dev, int type) |
510 | { | 428 | { |
511 | int vector; | 429 | int irq; |
512 | unsigned long flags; | 430 | unsigned long flags; |
513 | 431 | ||
514 | spin_lock_irqsave(&msi_lock, flags); | 432 | spin_lock_irqsave(&msi_lock, flags); |
515 | for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { | 433 | for (irq = 0; irq < NR_IRQS; irq++) { |
516 | if (!msi_desc[vector] || msi_desc[vector]->dev != dev || | 434 | if (!msi_desc[irq] || msi_desc[irq]->dev != dev || |
517 | msi_desc[vector]->msi_attrib.type != type || | 435 | msi_desc[irq]->msi_attrib.type != type || |
518 | msi_desc[vector]->msi_attrib.default_vector != dev->irq) | 436 | msi_desc[irq]->msi_attrib.default_irq != dev->irq) |
519 | continue; | 437 | continue; |
520 | spin_unlock_irqrestore(&msi_lock, flags); | 438 | spin_unlock_irqrestore(&msi_lock, flags); |
521 | /* This pre-assigned MSI vector for this device | 439 | /* This pre-assigned MSI irq for this device |
522 | already exits. Override dev->irq with this vector */ | 440 | already exits. Override dev->irq with this irq */ |
523 | dev->irq = vector; | 441 | dev->irq = irq; |
524 | return 0; | 442 | return 0; |
525 | } | 443 | } |
526 | spin_unlock_irqrestore(&msi_lock, flags); | 444 | spin_unlock_irqrestore(&msi_lock, flags); |
@@ -605,7 +523,7 @@ int pci_save_msix_state(struct pci_dev *dev) | |||
605 | { | 523 | { |
606 | int pos; | 524 | int pos; |
607 | int temp; | 525 | int temp; |
608 | int vector, head, tail = 0; | 526 | int irq, head, tail = 0; |
609 | u16 control; | 527 | u16 control; |
610 | struct pci_cap_saved_state *save_state; | 528 | struct pci_cap_saved_state *save_state; |
611 | 529 | ||
@@ -627,20 +545,20 @@ int pci_save_msix_state(struct pci_dev *dev) | |||
627 | 545 | ||
628 | /* save the table */ | 546 | /* save the table */ |
629 | temp = dev->irq; | 547 | temp = dev->irq; |
630 | if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 548 | if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
631 | kfree(save_state); | 549 | kfree(save_state); |
632 | return -EINVAL; | 550 | return -EINVAL; |
633 | } | 551 | } |
634 | 552 | ||
635 | vector = head = dev->irq; | 553 | irq = head = dev->irq; |
636 | while (head != tail) { | 554 | while (head != tail) { |
637 | struct msi_desc *entry; | 555 | struct msi_desc *entry; |
638 | 556 | ||
639 | entry = msi_desc[vector]; | 557 | entry = msi_desc[irq]; |
640 | read_msi_msg(entry, &entry->msg_save); | 558 | read_msi_msg(entry, &entry->msg_save); |
641 | 559 | ||
642 | tail = msi_desc[vector]->link.tail; | 560 | tail = msi_desc[irq]->link.tail; |
643 | vector = tail; | 561 | irq = tail; |
644 | } | 562 | } |
645 | dev->irq = temp; | 563 | dev->irq = temp; |
646 | 564 | ||
@@ -653,7 +571,7 @@ void pci_restore_msix_state(struct pci_dev *dev) | |||
653 | { | 571 | { |
654 | u16 save; | 572 | u16 save; |
655 | int pos; | 573 | int pos; |
656 | int vector, head, tail = 0; | 574 | int irq, head, tail = 0; |
657 | struct msi_desc *entry; | 575 | struct msi_desc *entry; |
658 | int temp; | 576 | int temp; |
659 | struct pci_cap_saved_state *save_state; | 577 | struct pci_cap_saved_state *save_state; |
@@ -671,15 +589,15 @@ void pci_restore_msix_state(struct pci_dev *dev) | |||
671 | 589 | ||
672 | /* route the table */ | 590 | /* route the table */ |
673 | temp = dev->irq; | 591 | temp = dev->irq; |
674 | if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) | 592 | if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) |
675 | return; | 593 | return; |
676 | vector = head = dev->irq; | 594 | irq = head = dev->irq; |
677 | while (head != tail) { | 595 | while (head != tail) { |
678 | entry = msi_desc[vector]; | 596 | entry = msi_desc[irq]; |
679 | write_msi_msg(entry, &entry->msg_save); | 597 | write_msi_msg(entry, &entry->msg_save); |
680 | 598 | ||
681 | tail = msi_desc[vector]->link.tail; | 599 | tail = msi_desc[irq]->link.tail; |
682 | vector = tail; | 600 | irq = tail; |
683 | } | 601 | } |
684 | dev->irq = temp; | 602 | dev->irq = temp; |
685 | 603 | ||
@@ -726,55 +644,54 @@ static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) | |||
726 | * @dev: pointer to the pci_dev data structure of MSI device function | 644 | * @dev: pointer to the pci_dev data structure of MSI device function |
727 | * | 645 | * |
728 | * Setup the MSI capability structure of device function with a single | 646 | * Setup the MSI capability structure of device function with a single |
729 | * MSI vector, regardless of device function is capable of handling | 647 | * MSI irq, regardless of device function is capable of handling |
730 | * multiple messages. A return of zero indicates the successful setup | 648 | * multiple messages. A return of zero indicates the successful setup |
731 | * of an entry zero with the new MSI vector or non-zero for otherwise. | 649 | * of an entry zero with the new MSI irq or non-zero for otherwise. |
732 | **/ | 650 | **/ |
733 | static int msi_capability_init(struct pci_dev *dev) | 651 | static int msi_capability_init(struct pci_dev *dev) |
734 | { | 652 | { |
735 | int status; | 653 | int status; |
736 | struct msi_desc *entry; | 654 | struct msi_desc *entry; |
737 | int pos, vector; | 655 | int pos, irq; |
738 | u16 control; | 656 | u16 control; |
657 | struct hw_interrupt_type *handler; | ||
739 | 658 | ||
740 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 659 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
741 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 660 | pci_read_config_word(dev, msi_control_reg(pos), &control); |
742 | /* MSI Entry Initialization */ | 661 | /* MSI Entry Initialization */ |
743 | entry = alloc_msi_entry(); | 662 | handler = &msi_irq_wo_maskbit_type; |
744 | if (!entry) | 663 | if (is_mask_bit_support(control)) |
745 | return -ENOMEM; | 664 | handler = &msi_irq_w_maskbit_type; |
746 | 665 | ||
747 | vector = get_msi_vector(dev); | 666 | irq = create_msi_irq(handler); |
748 | if (vector < 0) { | 667 | if (irq < 0) |
749 | kmem_cache_free(msi_cachep, entry); | 668 | return irq; |
750 | return -EBUSY; | 669 | |
751 | } | 670 | entry = get_irq_data(irq); |
752 | entry->link.head = vector; | 671 | entry->link.head = irq; |
753 | entry->link.tail = vector; | 672 | entry->link.tail = irq; |
754 | entry->msi_attrib.type = PCI_CAP_ID_MSI; | 673 | entry->msi_attrib.type = PCI_CAP_ID_MSI; |
755 | entry->msi_attrib.state = 0; /* Mark it not active */ | 674 | entry->msi_attrib.state = 0; /* Mark it not active */ |
756 | entry->msi_attrib.is_64 = is_64bit_address(control); | 675 | entry->msi_attrib.is_64 = is_64bit_address(control); |
757 | entry->msi_attrib.entry_nr = 0; | 676 | entry->msi_attrib.entry_nr = 0; |
758 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 677 | entry->msi_attrib.maskbit = is_mask_bit_support(control); |
759 | entry->msi_attrib.default_vector = dev->irq; /* Save IOAPIC IRQ */ | 678 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
760 | entry->msi_attrib.pos = pos; | 679 | entry->msi_attrib.pos = pos; |
761 | dev->irq = vector; | 680 | dev->irq = irq; |
762 | entry->dev = dev; | 681 | entry->dev = dev; |
763 | if (is_mask_bit_support(control)) { | 682 | if (is_mask_bit_support(control)) { |
764 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, | 683 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, |
765 | is_64bit_address(control)); | 684 | is_64bit_address(control)); |
766 | } | 685 | } |
767 | /* Replace with MSI handler */ | ||
768 | irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); | ||
769 | /* Configure MSI capability structure */ | 686 | /* Configure MSI capability structure */ |
770 | status = msi_register_init(dev, entry); | 687 | status = msi_register_init(dev, entry); |
771 | if (status != 0) { | 688 | if (status != 0) { |
772 | dev->irq = entry->msi_attrib.default_vector; | 689 | dev->irq = entry->msi_attrib.default_irq; |
773 | kmem_cache_free(msi_cachep, entry); | 690 | destroy_msi_irq(irq); |
774 | return status; | 691 | return status; |
775 | } | 692 | } |
776 | 693 | ||
777 | attach_msi_entry(entry, vector); | 694 | attach_msi_entry(entry, irq); |
778 | /* Set MSI enabled bits */ | 695 | /* Set MSI enabled bits */ |
779 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | 696 | enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); |
780 | 697 | ||
@@ -788,8 +705,8 @@ static int msi_capability_init(struct pci_dev *dev) | |||
788 | * @nvec: number of @entries | 705 | * @nvec: number of @entries |
789 | * | 706 | * |
790 | * Setup the MSI-X capability structure of device function with a | 707 | * Setup the MSI-X capability structure of device function with a |
791 | * single MSI-X vector. A return of zero indicates the successful setup of | 708 | * single MSI-X irq. A return of zero indicates the successful setup of |
792 | * requested MSI-X entries with allocated vectors or non-zero for otherwise. | 709 | * requested MSI-X entries with allocated irqs or non-zero for otherwise. |
793 | **/ | 710 | **/ |
794 | static int msix_capability_init(struct pci_dev *dev, | 711 | static int msix_capability_init(struct pci_dev *dev, |
795 | struct msix_entry *entries, int nvec) | 712 | struct msix_entry *entries, int nvec) |
@@ -797,7 +714,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
797 | struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; | 714 | struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; |
798 | struct msi_msg msg; | 715 | struct msi_msg msg; |
799 | int status; | 716 | int status; |
800 | int vector, pos, i, j, nr_entries, temp = 0; | 717 | int irq, pos, i, j, nr_entries, temp = 0; |
801 | unsigned long phys_addr; | 718 | unsigned long phys_addr; |
802 | u32 table_offset; | 719 | u32 table_offset; |
803 | u16 control; | 720 | u16 control; |
@@ -819,54 +736,50 @@ static int msix_capability_init(struct pci_dev *dev, | |||
819 | 736 | ||
820 | /* MSI-X Table Initialization */ | 737 | /* MSI-X Table Initialization */ |
821 | for (i = 0; i < nvec; i++) { | 738 | for (i = 0; i < nvec; i++) { |
822 | entry = alloc_msi_entry(); | 739 | irq = create_msi_irq(&msix_irq_type); |
823 | if (!entry) | 740 | if (irq < 0) |
824 | break; | 741 | break; |
825 | vector = get_msi_vector(dev); | ||
826 | if (vector < 0) { | ||
827 | kmem_cache_free(msi_cachep, entry); | ||
828 | break; | ||
829 | } | ||
830 | 742 | ||
743 | entry = get_irq_data(irq); | ||
831 | j = entries[i].entry; | 744 | j = entries[i].entry; |
832 | entries[i].vector = vector; | 745 | entries[i].vector = irq; |
833 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; | 746 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; |
834 | entry->msi_attrib.state = 0; /* Mark it not active */ | 747 | entry->msi_attrib.state = 0; /* Mark it not active */ |
835 | entry->msi_attrib.is_64 = 1; | 748 | entry->msi_attrib.is_64 = 1; |
836 | entry->msi_attrib.entry_nr = j; | 749 | entry->msi_attrib.entry_nr = j; |
837 | entry->msi_attrib.maskbit = 1; | 750 | entry->msi_attrib.maskbit = 1; |
838 | entry->msi_attrib.default_vector = dev->irq; | 751 | entry->msi_attrib.default_irq = dev->irq; |
839 | entry->msi_attrib.pos = pos; | 752 | entry->msi_attrib.pos = pos; |
840 | entry->dev = dev; | 753 | entry->dev = dev; |
841 | entry->mask_base = base; | 754 | entry->mask_base = base; |
842 | if (!head) { | 755 | if (!head) { |
843 | entry->link.head = vector; | 756 | entry->link.head = irq; |
844 | entry->link.tail = vector; | 757 | entry->link.tail = irq; |
845 | head = entry; | 758 | head = entry; |
846 | } else { | 759 | } else { |
847 | entry->link.head = temp; | 760 | entry->link.head = temp; |
848 | entry->link.tail = tail->link.tail; | 761 | entry->link.tail = tail->link.tail; |
849 | tail->link.tail = vector; | 762 | tail->link.tail = irq; |
850 | head->link.head = vector; | 763 | head->link.head = irq; |
851 | } | 764 | } |
852 | temp = vector; | 765 | temp = irq; |
853 | tail = entry; | 766 | tail = entry; |
854 | /* Replace with MSI-X handler */ | ||
855 | irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); | ||
856 | /* Configure MSI-X capability structure */ | 767 | /* Configure MSI-X capability structure */ |
857 | status = msi_ops->setup(dev, vector, &msg); | 768 | status = msi_ops->setup(dev, irq, &msg); |
858 | if (status < 0) | 769 | if (status < 0) { |
770 | destroy_msi_irq(irq); | ||
859 | break; | 771 | break; |
772 | } | ||
860 | 773 | ||
861 | write_msi_msg(entry, &msg); | 774 | write_msi_msg(entry, &msg); |
862 | attach_msi_entry(entry, vector); | 775 | attach_msi_entry(entry, irq); |
863 | } | 776 | } |
864 | if (i != nvec) { | 777 | if (i != nvec) { |
865 | int avail = i - 1; | 778 | int avail = i - 1; |
866 | i--; | 779 | i--; |
867 | for (; i >= 0; i--) { | 780 | for (; i >= 0; i--) { |
868 | vector = (entries + i)->vector; | 781 | irq = (entries + i)->vector; |
869 | msi_free_vector(dev, vector, 0); | 782 | msi_free_irq(dev, irq); |
870 | (entries + i)->vector = 0; | 783 | (entries + i)->vector = 0; |
871 | } | 784 | } |
872 | /* If we had some success report the number of irqs | 785 | /* If we had some success report the number of irqs |
@@ -914,10 +827,10 @@ int pci_msi_supported(struct pci_dev * dev) | |||
914 | * @dev: pointer to the pci_dev data structure of MSI device function | 827 | * @dev: pointer to the pci_dev data structure of MSI device function |
915 | * | 828 | * |
916 | * Setup the MSI capability structure of device function with | 829 | * Setup the MSI capability structure of device function with |
917 | * a single MSI vector upon its software driver call to request for | 830 | * a single MSI irq upon its software driver call to request for |
918 | * MSI mode enabled on its hardware device function. A return of zero | 831 | * MSI mode enabled on its hardware device function. A return of zero |
919 | * indicates the successful setup of an entry zero with the new MSI | 832 | * indicates the successful setup of an entry zero with the new MSI |
920 | * vector or non-zero for otherwise. | 833 | * irq or non-zero for otherwise. |
921 | **/ | 834 | **/ |
922 | int pci_enable_msi(struct pci_dev* dev) | 835 | int pci_enable_msi(struct pci_dev* dev) |
923 | { | 836 | { |
@@ -941,13 +854,13 @@ int pci_enable_msi(struct pci_dev* dev) | |||
941 | if (!is_64bit_address(control) && msi_ops->needs_64bit_address) | 854 | if (!is_64bit_address(control) && msi_ops->needs_64bit_address) |
942 | return -EINVAL; | 855 | return -EINVAL; |
943 | 856 | ||
944 | WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSI)); | 857 | WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); |
945 | 858 | ||
946 | /* Check whether driver already requested for MSI-X vectors */ | 859 | /* Check whether driver already requested for MSI-X irqs */ |
947 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 860 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); |
948 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 861 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
949 | printk(KERN_INFO "PCI: %s: Can't enable MSI. " | 862 | printk(KERN_INFO "PCI: %s: Can't enable MSI. " |
950 | "Device already has MSI-X vectors assigned\n", | 863 | "Device already has MSI-X irq assigned\n", |
951 | pci_name(dev)); | 864 | pci_name(dev)); |
952 | dev->irq = temp; | 865 | dev->irq = temp; |
953 | return -EINVAL; | 866 | return -EINVAL; |
@@ -959,7 +872,7 @@ int pci_enable_msi(struct pci_dev* dev) | |||
959 | void pci_disable_msi(struct pci_dev* dev) | 872 | void pci_disable_msi(struct pci_dev* dev) |
960 | { | 873 | { |
961 | struct msi_desc *entry; | 874 | struct msi_desc *entry; |
962 | int pos, default_vector; | 875 | int pos, default_irq; |
963 | u16 control; | 876 | u16 control; |
964 | unsigned long flags; | 877 | unsigned long flags; |
965 | 878 | ||
@@ -987,30 +900,30 @@ void pci_disable_msi(struct pci_dev* dev) | |||
987 | if (entry->msi_attrib.state) { | 900 | if (entry->msi_attrib.state) { |
988 | spin_unlock_irqrestore(&msi_lock, flags); | 901 | spin_unlock_irqrestore(&msi_lock, flags); |
989 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " | 902 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " |
990 | "free_irq() on MSI vector %d\n", | 903 | "free_irq() on MSI irq %d\n", |
991 | pci_name(dev), dev->irq); | 904 | pci_name(dev), dev->irq); |
992 | BUG_ON(entry->msi_attrib.state > 0); | 905 | BUG_ON(entry->msi_attrib.state > 0); |
993 | } else { | 906 | } else { |
994 | default_vector = entry->msi_attrib.default_vector; | 907 | default_irq = entry->msi_attrib.default_irq; |
995 | spin_unlock_irqrestore(&msi_lock, flags); | 908 | spin_unlock_irqrestore(&msi_lock, flags); |
996 | msi_free_vector(dev, dev->irq, 0); | 909 | msi_free_irq(dev, dev->irq); |
997 | 910 | ||
998 | /* Restore dev->irq to its default pin-assertion vector */ | 911 | /* Restore dev->irq to its default pin-assertion irq */ |
999 | dev->irq = default_vector; | 912 | dev->irq = default_irq; |
1000 | } | 913 | } |
1001 | } | 914 | } |
1002 | 915 | ||
1003 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | 916 | static int msi_free_irq(struct pci_dev* dev, int irq) |
1004 | { | 917 | { |
1005 | struct msi_desc *entry; | 918 | struct msi_desc *entry; |
1006 | int head, entry_nr, type; | 919 | int head, entry_nr, type; |
1007 | void __iomem *base; | 920 | void __iomem *base; |
1008 | unsigned long flags; | 921 | unsigned long flags; |
1009 | 922 | ||
1010 | msi_ops->teardown(vector); | 923 | msi_ops->teardown(irq); |
1011 | 924 | ||
1012 | spin_lock_irqsave(&msi_lock, flags); | 925 | spin_lock_irqsave(&msi_lock, flags); |
1013 | entry = msi_desc[vector]; | 926 | entry = msi_desc[irq]; |
1014 | if (!entry || entry->dev != dev) { | 927 | if (!entry || entry->dev != dev) { |
1015 | spin_unlock_irqrestore(&msi_lock, flags); | 928 | spin_unlock_irqrestore(&msi_lock, flags); |
1016 | return -EINVAL; | 929 | return -EINVAL; |
@@ -1022,22 +935,16 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | |||
1022 | msi_desc[entry->link.head]->link.tail = entry->link.tail; | 935 | msi_desc[entry->link.head]->link.tail = entry->link.tail; |
1023 | msi_desc[entry->link.tail]->link.head = entry->link.head; | 936 | msi_desc[entry->link.tail]->link.head = entry->link.head; |
1024 | entry->dev = NULL; | 937 | entry->dev = NULL; |
1025 | if (!reassign) { | 938 | msi_desc[irq] = NULL; |
1026 | vector_irq[vector] = 0; | ||
1027 | nr_released_vectors++; | ||
1028 | } | ||
1029 | msi_desc[vector] = NULL; | ||
1030 | spin_unlock_irqrestore(&msi_lock, flags); | 939 | spin_unlock_irqrestore(&msi_lock, flags); |
1031 | 940 | ||
1032 | kmem_cache_free(msi_cachep, entry); | 941 | destroy_msi_irq(irq); |
1033 | 942 | ||
1034 | if (type == PCI_CAP_ID_MSIX) { | 943 | if (type == PCI_CAP_ID_MSIX) { |
1035 | if (!reassign) | 944 | writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + |
1036 | writel(1, base + | 945 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); |
1037 | entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
1038 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); | ||
1039 | 946 | ||
1040 | if (head == vector) | 947 | if (head == irq) |
1041 | iounmap(base); | 948 | iounmap(base); |
1042 | } | 949 | } |
1043 | 950 | ||
@@ -1048,15 +955,15 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | |||
1048 | * pci_enable_msix - configure device's MSI-X capability structure | 955 | * pci_enable_msix - configure device's MSI-X capability structure |
1049 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 956 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
1050 | * @entries: pointer to an array of MSI-X entries | 957 | * @entries: pointer to an array of MSI-X entries |
1051 | * @nvec: number of MSI-X vectors requested for allocation by device driver | 958 | * @nvec: number of MSI-X irqs requested for allocation by device driver |
1052 | * | 959 | * |
1053 | * Setup the MSI-X capability structure of device function with the number | 960 | * Setup the MSI-X capability structure of device function with the number |
1054 | * of requested vectors upon its software driver call to request for | 961 | * of requested irqs upon its software driver call to request for |
1055 | * MSI-X mode enabled on its hardware device function. A return of zero | 962 | * MSI-X mode enabled on its hardware device function. A return of zero |
1056 | * indicates the successful configuration of MSI-X capability structure | 963 | * indicates the successful configuration of MSI-X capability structure |
1057 | * with new allocated MSI-X vectors. A return of < 0 indicates a failure. | 964 | * with new allocated MSI-X irqs. A return of < 0 indicates a failure. |
1058 | * Or a return of > 0 indicates that driver request is exceeding the number | 965 | * Or a return of > 0 indicates that driver request is exceeding the number |
1059 | * of vectors available. Driver should use the returned value to re-send | 966 | * of irqs available. Driver should use the returned value to re-send |
1060 | * its request. | 967 | * its request. |
1061 | **/ | 968 | **/ |
1062 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | 969 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) |
@@ -1091,13 +998,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | |||
1091 | } | 998 | } |
1092 | } | 999 | } |
1093 | temp = dev->irq; | 1000 | temp = dev->irq; |
1094 | WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)); | 1001 | WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)); |
1095 | 1002 | ||
1096 | /* Check whether driver already requested for MSI vector */ | 1003 | /* Check whether driver already requested for MSI irq */ |
1097 | if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && | 1004 | if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && |
1098 | !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { | 1005 | !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1099 | printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " | 1006 | printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " |
1100 | "Device already has an MSI vector assigned\n", | 1007 | "Device already has an MSI irq assigned\n", |
1101 | pci_name(dev)); | 1008 | pci_name(dev)); |
1102 | dev->irq = temp; | 1009 | dev->irq = temp; |
1103 | return -EINVAL; | 1010 | return -EINVAL; |
@@ -1127,27 +1034,27 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1127 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | 1034 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); |
1128 | 1035 | ||
1129 | temp = dev->irq; | 1036 | temp = dev->irq; |
1130 | if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 1037 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1131 | int state, vector, head, tail = 0, warning = 0; | 1038 | int state, irq, head, tail = 0, warning = 0; |
1132 | unsigned long flags; | 1039 | unsigned long flags; |
1133 | 1040 | ||
1134 | vector = head = dev->irq; | 1041 | irq = head = dev->irq; |
1135 | dev->irq = temp; /* Restore pin IRQ */ | 1042 | dev->irq = temp; /* Restore pin IRQ */ |
1136 | while (head != tail) { | 1043 | while (head != tail) { |
1137 | spin_lock_irqsave(&msi_lock, flags); | 1044 | spin_lock_irqsave(&msi_lock, flags); |
1138 | state = msi_desc[vector]->msi_attrib.state; | 1045 | state = msi_desc[irq]->msi_attrib.state; |
1139 | tail = msi_desc[vector]->link.tail; | 1046 | tail = msi_desc[irq]->link.tail; |
1140 | spin_unlock_irqrestore(&msi_lock, flags); | 1047 | spin_unlock_irqrestore(&msi_lock, flags); |
1141 | if (state) | 1048 | if (state) |
1142 | warning = 1; | 1049 | warning = 1; |
1143 | else if (vector != head) /* Release MSI-X vector */ | 1050 | else if (irq != head) /* Release MSI-X irq */ |
1144 | msi_free_vector(dev, vector, 0); | 1051 | msi_free_irq(dev, irq); |
1145 | vector = tail; | 1052 | irq = tail; |
1146 | } | 1053 | } |
1147 | msi_free_vector(dev, vector, 0); | 1054 | msi_free_irq(dev, irq); |
1148 | if (warning) { | 1055 | if (warning) { |
1149 | printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " | 1056 | printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " |
1150 | "free_irq() on all MSI-X vectors\n", | 1057 | "free_irq() on all MSI-X irqs\n", |
1151 | pci_name(dev)); | 1058 | pci_name(dev)); |
1152 | BUG_ON(warning > 0); | 1059 | BUG_ON(warning > 0); |
1153 | } | 1060 | } |
@@ -1155,11 +1062,11 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1155 | } | 1062 | } |
1156 | 1063 | ||
1157 | /** | 1064 | /** |
1158 | * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state | 1065 | * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state |
1159 | * @dev: pointer to the pci_dev data structure of MSI(X) device function | 1066 | * @dev: pointer to the pci_dev data structure of MSI(X) device function |
1160 | * | 1067 | * |
1161 | * Being called during hotplug remove, from which the device function | 1068 | * Being called during hotplug remove, from which the device function |
1162 | * is hot-removed. All previous assigned MSI/MSI-X vectors, if | 1069 | * is hot-removed. All previous assigned MSI/MSI-X irqs, if |
1163 | * allocated for this device function, are reclaimed to unused state, | 1070 | * allocated for this device function, are reclaimed to unused state, |
1164 | * which may be used later on. | 1071 | * which may be used later on. |
1165 | **/ | 1072 | **/ |
@@ -1173,42 +1080,42 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1173 | 1080 | ||
1174 | temp = dev->irq; /* Save IOAPIC IRQ */ | 1081 | temp = dev->irq; /* Save IOAPIC IRQ */ |
1175 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 1082 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
1176 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { | 1083 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1177 | spin_lock_irqsave(&msi_lock, flags); | 1084 | spin_lock_irqsave(&msi_lock, flags); |
1178 | state = msi_desc[dev->irq]->msi_attrib.state; | 1085 | state = msi_desc[dev->irq]->msi_attrib.state; |
1179 | spin_unlock_irqrestore(&msi_lock, flags); | 1086 | spin_unlock_irqrestore(&msi_lock, flags); |
1180 | if (state) { | 1087 | if (state) { |
1181 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 1088 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1182 | "called without free_irq() on MSI vector %d\n", | 1089 | "called without free_irq() on MSI irq %d\n", |
1183 | pci_name(dev), dev->irq); | 1090 | pci_name(dev), dev->irq); |
1184 | BUG_ON(state > 0); | 1091 | BUG_ON(state > 0); |
1185 | } else /* Release MSI vector assigned to this device */ | 1092 | } else /* Release MSI irq assigned to this device */ |
1186 | msi_free_vector(dev, dev->irq, 0); | 1093 | msi_free_irq(dev, dev->irq); |
1187 | dev->irq = temp; /* Restore IOAPIC IRQ */ | 1094 | dev->irq = temp; /* Restore IOAPIC IRQ */ |
1188 | } | 1095 | } |
1189 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 1096 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); |
1190 | if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { | 1097 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1191 | int vector, head, tail = 0, warning = 0; | 1098 | int irq, head, tail = 0, warning = 0; |
1192 | void __iomem *base = NULL; | 1099 | void __iomem *base = NULL; |
1193 | 1100 | ||
1194 | vector = head = dev->irq; | 1101 | irq = head = dev->irq; |
1195 | while (head != tail) { | 1102 | while (head != tail) { |
1196 | spin_lock_irqsave(&msi_lock, flags); | 1103 | spin_lock_irqsave(&msi_lock, flags); |
1197 | state = msi_desc[vector]->msi_attrib.state; | 1104 | state = msi_desc[irq]->msi_attrib.state; |
1198 | tail = msi_desc[vector]->link.tail; | 1105 | tail = msi_desc[irq]->link.tail; |
1199 | base = msi_desc[vector]->mask_base; | 1106 | base = msi_desc[irq]->mask_base; |
1200 | spin_unlock_irqrestore(&msi_lock, flags); | 1107 | spin_unlock_irqrestore(&msi_lock, flags); |
1201 | if (state) | 1108 | if (state) |
1202 | warning = 1; | 1109 | warning = 1; |
1203 | else if (vector != head) /* Release MSI-X vector */ | 1110 | else if (irq != head) /* Release MSI-X irq */ |
1204 | msi_free_vector(dev, vector, 0); | 1111 | msi_free_irq(dev, irq); |
1205 | vector = tail; | 1112 | irq = tail; |
1206 | } | 1113 | } |
1207 | msi_free_vector(dev, vector, 0); | 1114 | msi_free_irq(dev, irq); |
1208 | if (warning) { | 1115 | if (warning) { |
1209 | iounmap(base); | 1116 | iounmap(base); |
1210 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 1117 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1211 | "called without free_irq() on all MSI-X vectors\n", | 1118 | "called without free_irq() on all MSI-X irqs\n", |
1212 | pci_name(dev)); | 1119 | pci_name(dev)); |
1213 | BUG_ON(warning > 0); | 1120 | BUG_ON(warning > 0); |
1214 | } | 1121 | } |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 6793241f3884..435d05aae4ba 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -8,9 +8,6 @@ | |||
8 | 8 | ||
9 | #include <asm/msi.h> | 9 | #include <asm/msi.h> |
10 | 10 | ||
11 | extern int vector_irq[NR_VECTORS]; | ||
12 | extern void (*interrupt[NR_IRQS])(void); | ||
13 | |||
14 | /* | 11 | /* |
15 | * MSI-X Address Register | 12 | * MSI-X Address Register |
16 | */ | 13 | */ |
@@ -58,9 +55,9 @@ struct msi_desc { | |||
58 | __u8 maskbit : 1; /* mask-pending bit supported ? */ | 55 | __u8 maskbit : 1; /* mask-pending bit supported ? */ |
59 | __u8 state : 1; /* {0: free, 1: busy} */ | 56 | __u8 state : 1; /* {0: free, 1: busy} */ |
60 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ | 57 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ |
61 | __u8 entry_nr; /* specific enabled entry */ | ||
62 | __u8 default_vector; /* default pre-assigned vector */ | ||
63 | __u8 pos; /* Location of the msi capability */ | 58 | __u8 pos; /* Location of the msi capability */ |
59 | __u16 entry_nr; /* specific enabled entry */ | ||
60 | unsigned default_irq; /* default pre-assigned irq */ | ||
64 | }msi_attrib; | 61 | }msi_attrib; |
65 | 62 | ||
66 | struct { | 63 | struct { |