diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-05-16 11:16:44 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2006-06-30 16:09:10 -0400 |
commit | c533120b8da215dc02310c535fa87c5c480d0f14 (patch) | |
tree | 5142cad1107953e1655c7153ef10b7cc0719f068 | |
parent | d29693bf10f376870d9bfd34bde80dd061cc4575 (diff) |
[PATCH] pcmcia: warn if driver requests exclusive, but gets a shared IRQ
The patch below cleans up the pcmcia code a bit on the IRQ side (I did
this while debugging the problem just so I could read wtf it was doing),
and also adds a warning and passes back the correct information when a
device asks for exclusive but gets given shared. This at least means the
dmesg dump of a problem triggered by this will have a signature to find.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 3131bb0a0095..3281e519e714 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -788,6 +788,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
788 | struct pcmcia_socket *s = p_dev->socket; | 788 | struct pcmcia_socket *s = p_dev->socket; |
789 | config_t *c; | 789 | config_t *c; |
790 | int ret = CS_IN_USE, irq = 0; | 790 | int ret = CS_IN_USE, irq = 0; |
791 | int type; | ||
791 | 792 | ||
792 | if (!(s->state & SOCKET_PRESENT)) | 793 | if (!(s->state & SOCKET_PRESENT)) |
793 | return CS_NO_CARD; | 794 | return CS_NO_CARD; |
@@ -797,6 +798,13 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
797 | if (c->state & CONFIG_IRQ_REQ) | 798 | if (c->state & CONFIG_IRQ_REQ) |
798 | return CS_IN_USE; | 799 | return CS_IN_USE; |
799 | 800 | ||
801 | /* Decide what type of interrupt we are registering */ | ||
802 | type = 0; | ||
803 | if (s->functions > 1) /* All of this ought to be handled higher up */ | ||
804 | type = SA_SHIRQ; | ||
805 | if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) | ||
806 | type = SA_SHIRQ; | ||
807 | |||
800 | #ifdef CONFIG_PCMCIA_PROBE | 808 | #ifdef CONFIG_PCMCIA_PROBE |
801 | if (s->irq.AssignedIRQ != 0) { | 809 | if (s->irq.AssignedIRQ != 0) { |
802 | /* If the interrupt is already assigned, it must be the same */ | 810 | /* If the interrupt is already assigned, it must be the same */ |
@@ -822,9 +830,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
822 | * marked as used by the kernel resource management core */ | 830 | * marked as used by the kernel resource management core */ |
823 | ret = request_irq(irq, | 831 | ret = request_irq(irq, |
824 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, | 832 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, |
825 | ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || | 833 | type, |
826 | (s->functions > 1) || | ||
827 | (irq == s->pci_irq)) ? SA_SHIRQ : 0, | ||
828 | p_dev->devname, | 834 | p_dev->devname, |
829 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); | 835 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); |
830 | if (!ret) { | 836 | if (!ret) { |
@@ -839,18 +845,21 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
839 | if (ret && !s->irq.AssignedIRQ) { | 845 | if (ret && !s->irq.AssignedIRQ) { |
840 | if (!s->pci_irq) | 846 | if (!s->pci_irq) |
841 | return ret; | 847 | return ret; |
848 | type = SA_SHIRQ; | ||
842 | irq = s->pci_irq; | 849 | irq = s->pci_irq; |
843 | } | 850 | } |
844 | 851 | ||
845 | if (ret && req->Attributes & IRQ_HANDLE_PRESENT) { | 852 | if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) { |
846 | if (request_irq(irq, req->Handler, | 853 | if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance)) |
847 | ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || | ||
848 | (s->functions > 1) || | ||
849 | (irq == s->pci_irq)) ? SA_SHIRQ : 0, | ||
850 | p_dev->devname, req->Instance)) | ||
851 | return CS_IN_USE; | 854 | return CS_IN_USE; |
852 | } | 855 | } |
853 | 856 | ||
857 | /* Make sure the fact the request type was overridden is passed back */ | ||
858 | if (type == SA_SHIRQ && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { | ||
859 | req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; | ||
860 | printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n"); | ||
861 | printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n"); | ||
862 | } | ||
854 | c->irq.Attributes = req->Attributes; | 863 | c->irq.Attributes = req->Attributes; |
855 | s->irq.AssignedIRQ = req->AssignedIRQ = irq; | 864 | s->irq.AssignedIRQ = req->AssignedIRQ = irq; |
856 | s->irq.Config++; | 865 | s->irq.Config++; |