patch-2.3.38 linux/drivers/pcmcia/cardbus.c
Next file: linux/drivers/pcmcia/cs.c
Previous file: linux/drivers/pci/setup.c
Back to the patch index
Back to the overall index
- Lines: 153
- Date:
Fri Jan 7 15:21:56 2000
- Orig file:
v2.3.37/linux/drivers/pcmcia/cardbus.c
- Orig date:
Thu Jan 6 12:57:47 2000
diff -u --recursive --new-file v2.3.37/linux/drivers/pcmcia/cardbus.c linux/drivers/pcmcia/cardbus.c
@@ -99,6 +99,11 @@
#define PCDATA_CODE_TYPE 0x0014
#define PCDATA_INDICATOR 0x0015
+#ifndef CONFIG_PROC_FS
+#define pci_proc_attach_device(dev) do { } while (0)
+#define pci_proc_detach_device(dev) do { } while (0)
+#endif
+
typedef struct cb_config_t {
struct pci_dev dev;
} cb_config_t;
@@ -313,19 +318,11 @@
res->start = 0;
pci_assign_resource(dev, r);
}
- printk("Resource %d at %08lx-%08lx (%04lx)\n",
- r,
- res->start,
- res->end,
- res->flags);
}
list_add_tail(&dev->bus_list, &bus->devices);
list_add_tail(&dev->global_list, &pci_devices);
-#ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev);
-#endif
-
pci_enable_device(dev);
}
@@ -347,20 +344,20 @@
void cb_free(socket_info_t * s)
{
cb_config_t *c = s->cb_config;
- int i;
if (c) {
+ int i;
+
+ s->cb_config = NULL;
for(i=0; i<s->functions; i++) {
struct pci_dev *dev = &c[i].dev;
+
list_del(&dev->bus_list);
list_del(&dev->global_list);
free_resources(dev);
-#ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev);
-#endif
}
- kfree(s->cb_config);
- s->cb_config = NULL;
+ kfree(c);
printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
}
}
@@ -377,59 +374,55 @@
======================================================================*/
+static int cb_assign_irq(u32 mask)
+{
+ int irq, try;
+
+ for (try = 0; try < 2; try++) {
+ for (irq = 1; irq < 32; irq++) {
+ if ((mask >> irq) & 1) {
+ if (try_irq(IRQ_TYPE_EXCLUSIVE, irq, try) == 0)
+ return irq;
+ }
+ }
+ }
+ return 0;
+}
+
int cb_config(socket_info_t * s)
{
cb_config_t *c = s->cb_config;
u_char fn = s->functions;
- u_char i, j;
- int irq, try, ret;
+ int i, irq;
printk(KERN_INFO "cs: cb_config(bus %d)\n", s->cap.cb_dev->subordinate->number);
- /* Allocate interrupt if needed */
- s->irq.AssignedIRQ = irq = 0;
- ret = -1;
+ /*
+ * If we have a PCI interrupt for the bridge,
+ * then use that..
+ */
+ irq = s->cap.pci_irq;
+
for (i = 0; i < fn; i++) {
struct pci_dev *dev = &c[i].dev;
- pci_readb(dev, PCI_INTERRUPT_PIN, &j);
- if (j == 0)
+ u8 irq_pin;
+
+ /* Does this function have an interrupt at all? */
+ pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
+ if (!irq_pin)
continue;
- if (irq == 0) {
- if (s->cap.irq_mask & (1 << s->cap.pci_irq)) {
- irq = s->cap.pci_irq;
- ret = 0;
- }
-#ifdef CONFIG_ISA
- else
- for (try = 0; try < 2; try++) {
- for (irq = 0; irq < 32; irq++)
- if ((s->cap.irq_mask >> irq) & 1) {
- ret = try_irq(IRQ_TYPE_EXCLUSIVE, irq, try);
- if (ret == 0)
- break;
- }
- if (ret == 0)
- break;
- }
- if (ret != 0) {
- printk(KERN_NOTICE "cs: could not allocate interrupt"
- " for CardBus socket %d\n", s->sock);
- goto failed;
- }
-#endif
- s->irq.AssignedIRQ = irq;
+
+ if (!irq) {
+ irq = cb_assign_irq(s->cap.irq_mask);
+ if (!irq)
+ return CS_OUT_OF_RESOURCE;
}
- }
- for (i = 0; i < fn; i++) {
- struct pci_dev *dev = &c[i].dev;
+
dev->irq = irq;
+ pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
}
-
+ s->irq.AssignedIRQ = irq;
return CS_SUCCESS;
-
- failed:
- cb_release(s);
- return CS_OUT_OF_RESOURCE;
}
/*======================================================================
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)