* i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
@ 2000-11-21 18:35 Michel Salim
2000-11-22 10:45 ` David Woodhouse
0 siblings, 1 reply; 6+ messages in thread
From: Michel Salim @ 2000-11-21 18:35 UTC (permalink / raw)
To: LKML
[-- Attachment #1: Type: text/plain, Size: 845 bytes --]
Hi,
Installed kernel 2.4.0-test11 on my Debian Woody box today. Had no
problem apart from getting PCMCIA to work. I have a PCI-PCMCIA adapter
on my desktop PC, using the Cirrus Logic CL6729 chipset; on a 2.2.x
kernel it is detected as an i82365 and works accordingly.
After trying 2.4.0-test9 and -test10 (which don't support i82365), it
was nice to see that test11-pre6 finally has regained PCMCIA support...
so it's weird to encounter this problem. Has anyone managed to use the
i82365 kernel module?
relevant kernel config:
PCMCIA support compiled as a module
i82365 as a module
CardBus (yenta_socket) as a module
Attached are the result of running /etc/init.d/pcmcia start and the
error message from dmesg
Any help appreciated... and looking forward to test12... or will it be
2.4.0-final, finally?
:)
Regards,
Michel Salim
[-- Attachment #2: log --]
[-- Type: text/plain, Size: 253 bytes --]
Starting PCMCIA services: modulesHint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters
Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters
cardmgr.
[-- Attachment #3: errmsg --]
[-- Type: text/plain, Size: 177 bytes --]
/lib/modules/2.4.0-test11/pcmcia/i82365.o: init_module: No such device
ds: no socket drivers loaded!
/lib/modules/2.4.0-test11/pcmcia/ds.o: init_module: Operation not permitted
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
2000-11-21 18:35 i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11 Michel Salim
@ 2000-11-22 10:45 ` David Woodhouse
2000-11-23 1:05 ` Michel Salim
[not found] ` <11299.974975638@redhat.com>
0 siblings, 2 replies; 6+ messages in thread
From: David Woodhouse @ 2000-11-22 10:45 UTC (permalink / raw)
To: Michel Salim; +Cc: LKML, dhinds
mas118@cs.york.ac.uk said:
> Installed kernel 2.4.0-test11 on my Debian Woody box today. Had no
> problem apart from getting PCMCIA to work. I have a PCI-PCMCIA adapter
> on my desktop PC, using the Cirrus Logic CL6729 chipset;
Linus got a bit carried away when stripping out all the CardBus support
from i82365, and took out the support for PCI-PCMCIA bridges too.
Try this snapshot of my development tree, or use lspci to find the IO
address of the device and specify that to the existing module.
Index: drivers/pcmcia/cirrus.h
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/cirrus.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 cirrus.h
--- drivers/pcmcia/cirrus.h 2000/06/07 10:38:28 1.1.2.2
+++ drivers/pcmcia/cirrus.h 2000/11/22 10:37:31
@@ -48,6 +48,11 @@
#define PD67_EXT_INDEX 0x2e /* Extension index */
#define PD67_EXT_DATA 0x2f /* Extension data */
+#define pd67_ext_get(s, r) \
+ (i365_set(s, PD67_EXT_INDEX, r), i365_get(s, PD67_EXT_DATA))
+#define pd67_ext_set(s, r, v) \
+ (i365_set(s, PD67_EXT_INDEX, r), i365_set(s, PD67_EXT_DATA, v))
+
/* PD6722 extension registers -- indexed in PD67_EXT_INDEX */
#define PD67_DATA_MASK0 0x01 /* Data mask 0 */
#define PD67_DATA_MASK1 0x02 /* Data mask 1 */
@@ -119,6 +124,10 @@
#define PD67_EC1_INV_CARD_IRQ 0x08
#define PD67_EC1_INV_MGMT_IRQ 0x10
#define PD67_EC1_PULLUP_CTL 0x20
+
+/* Fields in PD67_EXTERN_DATA */
+#define PD67_EXD_VS1(s) (0x01 << ((s)<<1))
+#define PD67_EXD_VS2(s) (0x02 << ((s)<<1))
/* Fields in PD67_MISC_CTL_3 */
#define PD67_MC3_IRQ_MASK 0x03
Index: drivers/pcmcia/cs.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/cs.c,v
retrieving revision 1.1.2.28
diff -u -r1.1.2.28 cs.c
--- drivers/pcmcia/cs.c 2000/11/10 14:56:32 1.1.2.28
+++ drivers/pcmcia/cs.c 2000/11/22 10:37:33
@@ -416,12 +416,10 @@
{
int i;
- for (i = 0; i < sockets; i++) {
+ for (i = sockets-1; i >= 0; i-- ) {
socket_info_t *socket = socket_table[i];
if (socket->ss_entry == ss_entry)
- pcmcia_unregister_socket (socket);
- else
- i++;
+ pcmcia_unregister_socket (socket);
}
} /* unregister_ss_entry */
Index: drivers/pcmcia/i82365.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/i82365.c,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 i82365.c
--- drivers/pcmcia/i82365.c 2000/11/17 09:35:49 1.1.2.15
+++ drivers/pcmcia/i82365.c 2000/11/22 10:37:36
@@ -142,6 +142,18 @@
MODULE_PARM(wakeup, "i");
#endif
+#ifdef CONFIG_PCI
+static int pci_irq_list[8] = { 0 }; /* PCI interrupt assignments */
+static int do_pci_probe = 1; /* Scan for PCI bridges? */
+static int fast_pci = -1;
+static int irq_mode = -1; /* Override BIOS routing? */
+
+MODULE_PARM(pci_irq_list, "1-8i");
+MODULE_PARM(do_pci_probe, "i");
+MODULE_PARM(fast_pci, "i");
+MODULE_PARM(irq_mode, "i");
+#endif
+
MODULE_PARM(do_scan, "i");
MODULE_PARM(poll_interval, "i");
MODULE_PARM(cycle_time, "i");
@@ -153,11 +165,27 @@
MODULE_PARM(setup_time, "i");
MODULE_PARM(cmd_time, "i");
MODULE_PARM(recov_time, "i");
+#if defined(CONFIG_ISA) && defined(CONFIG_PCI)
+int pci_csc = 1; /* PCI card status irqs? */
+int pci_int = 1; /* PCI IO card irqs? */
+MODULE_PARM(pci_csc, "i");
+MODULE_PARM(pci_int, "i");
+#elif defined(CONFIG_ISA) && !defined(CONFIG_PCI)
+#define pci_csc 0
+#define pci_int 0
+#elif !defined(CONFIG_ISA) && defined(CONFIG_PCI)
+#define pci_csc 0
+#define pci_int 1 /* We must use PCI irq's */
+#else
+#error "No bus architectures defined!"
+#endif
+
/*====================================================================*/
typedef struct cirrus_state_t {
u_char misc1, misc2;
+ u_char ectl1;
u_char timer[6];
} cirrus_state_t;
@@ -165,6 +193,17 @@
u_char ctl, ema;
} vg46x_state_t;
+typedef struct o2micro_state_t {
+ u_char mode_a; /* O2_MODE_A */
+ u_char mode_b; /* O2_MODE_B */
+ u_char mode_c; /* O2_MODE_C */
+ u_char mode_d; /* O2_MODE_D */
+ u_char mhpg; /* O2_MHPG_DMA */
+ u_char fifo; /* O2_FIFO_ENA */
+ u_char mode_e; /* O2_MODE_E */
+} o2micro_state_t;
+
+
typedef struct socket_info_t {
u_short type, flags;
socket_cap_t cap;
@@ -176,9 +215,15 @@
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
+ u_char pci_irq_code;
+ u_char revision;
+#ifdef CONFIG_PCI
+ struct pci_dev *dev;
+#endif
union {
cirrus_state_t cirrus;
vg46x_state_t vg46x;
+ o2micro_state_t o2micro;
} state;
} socket_info_t;
@@ -216,6 +261,18 @@
IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
IS_PD6710, IS_PD672X, IS_VT83C469,
#endif
+#ifdef CONFIG_PCI
+ /*
+ * There are many cards which were supported by the i82365 driver
+ * in the standalone package, but which are not listed here.
+ * This is because they are CardBus-capable and hence now supported
+ * by the Yenta driver.
+ */
+ IS_I82092AA, IS_OM82C092G, /* Intel 82092-based */
+ IS_PD6729, IS_PD6730, /* Cirrus */
+ IS_OZ6729, IS_OZ6730, /* O2Micro */
+ IS_UNK_PCI
+#endif
} pcic_id;
/* Flags for classifying groups of controllers */
@@ -251,7 +308,86 @@
{ "Cirrus PD672x", IS_CIRRUS },
{ "VIA VT83C469", IS_CIRRUS|IS_VIA },
#endif
+#ifdef CONFIG_PCI
+ { "Intel 82092AA", IS_PCI },
+ { "Omega Micro 82C092G", IS_PCI },
+ { "Cirrus PD6729", IS_CIRRUS|IS_PCI },
+ { "Cirrus PD6730", IS_CIRRUS|IS_PCI },
+ { "O2Micro OZ6729", IS_O2MICRO|IS_PCI|IS_VG_PWR },
+ { "O2Micro OZ6730", IS_O2MICRO|IS_PCI|IS_VG_PWR },
+ { "Unknown", IS_PCI|IS_UNKNOWN },
+#endif
+};
+
+#ifdef CONFIG_PCI
+static struct pci_device_id i82365_pci_ids[] = {
+ {
+ vendor: PCI_VENDOR_ID_INTEL,
+ device: PCI_DEVICE_ID_INTEL_82092AA_0,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0, class_mask: 0,
+ driver_data: IS_I82092AA
+ }, {
+ vendor: PCI_VENDOR_ID_OMEGA,
+ device: PCI_DEVICE_ID_OMEGA_82C092G,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0, class_mask: 0,
+ driver_data: IS_OM82C092G
+ }, {
+ vendor: PCI_VENDOR_ID_CIRRUS,
+ device: PCI_DEVICE_ID_CIRRUS_6729,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0, class_mask: 0,
+ driver_data: IS_PD6729
+ }, {
+ vendor: PCI_VENDOR_ID_CIRRUS,
+ device: PCI_ANY_ID,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: PCI_CLASS_BRIDGE_PCMCIA,
+ class_mask: 0xffff,
+ driver_data: IS_PD6730
+ }, {
+ vendor: PCI_VENDOR_ID_O2,
+ device: PCI_DEVICE_ID_O2_6729,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0, class_mask: 0,
+ driver_data: IS_OZ6729
+ }, {
+ vendor: PCI_VENDOR_ID_O2,
+ device: PCI_DEVICE_ID_O2_6730,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0, class_mask: 0,
+ driver_data: IS_OZ6730
+ }, {
+ vendor: PCI_ANY_ID,
+ device: PCI_ANY_ID,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: PCI_CLASS_BRIDGE_PCMCIA,
+ class_mask: 0xffff,
+ driver_data: IS_UNK_PCI
+ },
+ { /* Terminating entry */ }
+};
+
+static int i82365_pci_probe(struct pci_dev *dev, const struct pci_device_id *id);
+static void i82365_pci_remove(struct pci_dev *dev);
+
+static struct pci_driver i82365_pci_drv = {
+ name: "i82365",
+ id_table: i82365_pci_ids,
+ probe: i82365_pci_probe,
+ remove: i82365_pci_remove,
+ suspend: NULL,
+ resume: NULL
};
+#endif
#define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t))
@@ -315,6 +451,22 @@
i365_set(sock, reg+1, data >> 8);
}
+#ifdef CONFIG_PCI
+
+static int __init get_pci_irq(u_short s)
+{
+ socket_info_t *t = &socket[s];
+ u8 irq;
+
+ irq = t->dev->irq;
+ if ((irq == 0) && (pci_csc || pci_int))
+ irq = pci_irq_list[t - socket];
+ if (irq >= NR_IRQS) irq = 0;
+ t->cap.pci_irq = irq;
+ return irq;
+}
+
+#endif
/*======================================================================
Code to save and restore global state information for Cirrus
@@ -384,6 +536,23 @@
if (p->misc2 & PD67_MC2_FREQ_BYPASS)
strcat(buf, " [freq bypass]");
}
+#ifdef CONFIG_PCI
+ } else {
+ p->misc1 &= ~PD67_MC1_MEDIA_ENA;
+ p->misc1 &= ~(PD67_MC1_PULSE_MGMT | PD67_MC1_PULSE_IRQ);
+ p->ectl1 &= ~(PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ);
+ flip(p->misc2, PD67_MC2_FAST_PCI, fast_pci);
+ if (p->misc2 & PD67_MC2_IRQ15_RI)
+ mask &= (t->type == IS_PD6730) ? ~0x0400 : ~0x8000;
+ if ((irq_mode == 1) && get_pci_irq(s)) {
+ /* Configure PD6729 bridge for PCI interrupts */
+ p->ectl1 |= PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;
+ t->pci_irq_code = 3; /* PCI INTA = "irq 3" */
+ buf += strlen(buf);
+ sprintf(buf, " [pci irq %d]", t->cap.pci_irq);
+ mask = 0;
+ }
+#endif
}
if (!(t->flags & IS_VIA)) {
if (setup_time >= 0)
@@ -459,7 +628,79 @@
#endif
+/*======================================================================
+
+ Code to save and restore global state information for O2Micro
+ controllers, and to set and report global configuration options.
+
+======================================================================*/
+
+#ifdef CONFIG_PCI
+
+static void __init o2micro_get_state(u_short s)
+{
+ o2micro_state_t *p = &socket[s].state.o2micro;
+
+ if (((socket[s].revision & 0xff) == 0x34) ||
+ ((socket[s].revision & 0xff) == 0x62)) {
+ p->mode_a = i365_get(s, O2_MODE_A_2);
+ p->mode_b = i365_get(s, O2_MODE_B_2);
+ } else {
+ p->mode_a = i365_get(s, O2_MODE_A);
+ p->mode_b = i365_get(s, O2_MODE_B);
+ }
+ p->mode_c = i365_get(s, O2_MODE_C);
+ p->mode_d = i365_get(s, O2_MODE_D);
+}
+
+static void o2micro_set_state(u_short s)
+{
+ o2micro_state_t *p = &socket[s].state.o2micro;
+
+ if (((socket[s].revision & 0xff) == 0x34) ||
+ ((socket[s].revision & 0xff) == 0x62)) {
+ i365_set(s, O2_MODE_A_2, p->mode_a);
+ i365_set(s, O2_MODE_B_2, p->mode_b);
+ } else {
+ i365_set(s, O2_MODE_A, p->mode_a);
+ i365_set(s, O2_MODE_B, p->mode_b);
+ }
+ i365_set(s, O2_MODE_C, p->mode_c);
+ i365_set(s, O2_MODE_D, p->mode_d);
+}
+
+static u_int __init o2micro_set_opts(u_short s, char *buf)
+{
+ o2micro_state_t *p = &socket[s].state.o2micro;
+ u_int mask = 0xffff;
+ p->mode_b = (p->mode_b & ~O2_MODE_B_IDENT) | O2_MODE_B_ID_CSTEP;
+ flip(p->mode_b, O2_MODE_B_IRQ15_RI, has_ring);
+ p->mode_c &= ~(O2_MODE_C_ZVIDEO | O2_MODE_C_DREQ_MASK);
+
+ if (p->mode_b & O2_MODE_B_IRQ15_RI) {
+ mask &= ~0x8000;
+ strcat(buf, " [ring]");
+ }
+ if (irq_mode != -1)
+ p->mode_d = irq_mode;
+ if (p->mode_d & O2_MODE_D_ISA_IRQ) {
+ strcat(buf, " [pci+isa]");
+ } else {
+ switch (p->mode_d & O2_MODE_D_IRQ_MODE) {
+ case O2_MODE_D_IRQ_PCPCI:
+ strcat(buf, " [pc/pci]"); break;
+ case O2_MODE_D_IRQ_PCIWAY:
+ strcat(buf, " [pci/way]"); break;
+ case O2_MODE_D_IRQ_PCI:
+ strcat(buf, " [pci only]"); mask = 0; break;
+ }
+ }
+ return mask;
+}
+
+#endif
+
/*======================================================================
Generic routines to get and set controller options
@@ -475,6 +716,10 @@
else if (t->flags & IS_VADEM)
vg46x_get_state(s);
#endif
+#ifdef CONFIG_PCI
+ else if (t->flags & IS_O2MICRO)
+ o2micro_get_state(s);
+#endif
}
static void set_bridge_state(u_short s)
@@ -491,6 +736,10 @@
if (t->flags & IS_VADEM)
vg46x_set_state(s);
#endif
+#ifdef CONFIG_PCI
+ if (t->flags & IS_O2MICRO)
+ o2micro_set_state(s);
+#endif
}
static u_int __init set_bridge_opts(u_short s, u_short ns)
@@ -512,6 +761,10 @@
else if (socket[i].flags & IS_VADEM)
m = vg46x_set_opts(i, buf);
#endif
+#ifdef CONFIG_PCI
+ else if (socket[i].flags & IS_O2MICRO)
+ m = o2micro_set_opts(s+i, buf);
+#endif
set_bridge_state(i);
printk(KERN_INFO " host opts [%d]:%s\n", i,
(*buf) ? buf : " none");
@@ -535,12 +788,15 @@
DEBUG(2, "-> hit on irq %d\n", irq);
}
-static u_int __init test_irq(u_short sock, int irq)
+static u_int __init test_irq(u_short sock, int irq, int pci)
{
- DEBUG(2, " testing ISA irq %d\n", irq);
+ int csc = (pci) ? 0 : irq;
+
+ DEBUG(2, " testing %s irq %d\n", pci?"PCI":"ISA", irq);
if (request_irq(irq, irq_count, 0, "scan", irq_count) != 0)
return 1;
- irq_hits = 0; irq_sock = sock;
+ irq_hits = 0;
+ irq_sock = sock;
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/100);
if (irq_hits) {
@@ -550,7 +806,7 @@
}
/* Generate one interrupt */
- i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
+ i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (csc << 4));
i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
udelay(1000);
@@ -560,7 +816,10 @@
i365_set(sock, I365_CSCINT, 0);
DEBUG(2, " hits = %d\n", irq_hits);
- return (irq_hits != 1);
+ if (pci)
+ return (irq_hits == 0);
+ else
+ return (irq_hits != 1);
}
#ifdef CONFIG_ISA
@@ -580,10 +839,10 @@
set_bridge_state(sock);
i365_set(sock, I365_CSCINT, 0);
for (i = 0; i < 16; i++)
- if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
+ if ((mask0 & (1 << i)) && (test_irq(sock, i, 0) == 0))
mask1 |= (1 << i);
for (i = 0; i < 16; i++)
- if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
+ if ((mask1 & (1 << i)) && (test_irq(sock, i, 0) != 0))
mask1 ^= (1 << i);
}
@@ -611,6 +870,22 @@
#endif /* CONFIG_ISA */
+#ifdef CONFIG_PCI
+static int __init pci_scan(u_short sock)
+{
+ socket_info_t *t = &socket[sock];
+
+ /* for PCI-to-PCMCIA bridges, just check for wedged irq */
+ irq_sock = sock; irq_hits = 0;
+ if (request_irq(t->cap.pci_irq, irq_count, 0, "scan", irq_count))
+ return 1;
+ udelay(50);
+ free_irq(t->cap.pci_irq, irq_count);
+ DEBUG(2,"pci_scan: %d hits on IRQ %d\n", irq_hits, t->cap.pci_irq);
+ return (!irq_hits);
+}
+#endif /* CONFIG_PCI */
+
/*====================================================================*/
/* Time conversion functions */
@@ -629,7 +904,7 @@
#ifdef CONFIG_ISA
-static int __init identify(u_short port, u_short sock)
+static int __init isa_identify(u_short port, u_short sock)
{
u_char val;
int type = -1;
@@ -741,8 +1016,17 @@
if (base == 0) printk("\n");
printk(KERN_INFO " %s", pcic[type].name);
- printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
- t->ioaddr, t->psock*0x40);
+#ifdef CONFIG_PCI
+ if (t->flags & IS_UNKNOWN)
+ printk(" [%04x %04x]", t->dev->vendor, t->dev->device);
+ printk(" rev %02x", t->revision);
+ if (t->flags & IS_PCI)
+ printk(" PCI-to-PCMCIA at slot %02x:%02x, port %#x",
+ t->dev->bus->number, PCI_SLOT(t->dev->devfn), t->ioaddr);
+ else
+#endif
+ printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
+ t->ioaddr, t->psock*0x40);
printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
#ifdef CONFIG_ISA
@@ -754,13 +1038,27 @@
mask |= (1<<irq_list[i]);
#endif
mask &= I365_MASK & set_bridge_opts(base, ns);
+#ifdef CONFIG_PCI
+ /* Can we use PCI interrupts for card status changes? */
+ if (pci_csc || pci_int) {
+ for (i = base; i < base + ns; i++)
+ if (!socket[i].cap.pci_irq || test_irq(i, socket[i].cap.pci_irq, 1)) break;
+ use_pci = (i==ns);
+ }
+#endif
#ifdef CONFIG_ISA
/* Scan for ISA interrupts */
mask = isa_scan(base, mask);
-#else
- printk(KERN_INFO " PCI card interrupts,");
+#endif
+
+#ifdef CONFIG_PCI
+ if (!mask)
+ printk(KERN_INFO " %s card interrupts,",
+ (use_pci && pci_int) ? "PCI" : "*NO*");
+ if (use_pci && pci_csc)
+ printk(" PCI status changes\n");
#endif
-
+
#ifdef CONFIG_ISA
/* Poll if only two interrupts available */
if (!use_pci && !poll_interval) {
@@ -770,7 +1068,8 @@
poll_interval = HZ;
}
/* Only try an ISA cs_irq if this is the first controller */
- if (!use_pci && !grab_irq && (cs_irq || !poll_interval)) {
+ if (!(use_pci && pci_csc) && !grab_irq &&
+ (cs_irq || !poll_interval)) {
/* Avoid irq 12 unless it is explicitly requested */
u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
for (cs_irq = 15; cs_irq > 0; cs_irq--)
@@ -785,7 +1084,7 @@
}
#endif
- if (!use_pci && !isa_irq) {
+ if (!(use_pci && pci_csc) && !isa_irq) {
if (poll_interval == 0)
poll_interval = HZ;
printk(" polling interval = %d ms\n",
@@ -798,6 +1097,8 @@
t[i].cap.features |= SS_CAP_PCCARD;
t[i].cap.map_size = 0x1000;
t[i].cap.irq_mask = mask;
+ if (!use_pci)
+ t[i].cap.pci_irq = 0;
t[i].cs_irq = isa_irq;
}
@@ -819,13 +1120,13 @@
return;
}
- id = identify(i365_base, 0);
- if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
+ id = isa_identify(i365_base, 0);
+ if ((id == IS_I82365DF) && (isa_identify(i365_base, 1) != id)) {
for (i = 0; i < 4; i++) {
if (i == ignore) continue;
port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
sock = (i & 1) << 1;
- if (identify(port, sock) == IS_I82365DF) {
+ if (isa_identify(port, sock) == IS_I82365DF) {
add_socket(port, sock, IS_VLSI);
add_pcic(1, IS_VLSI);
}
@@ -834,12 +1135,12 @@
for (i = 0; i < (extra_sockets ? 8 : 4); i += 2) {
port = i365_base + 2*(i>>2);
sock = (i & 3);
- id = identify(port, sock);
+ id = isa_identify(port, sock);
if (id < 0) continue;
for (j = ns = 0; j < 2; j++) {
/* Does the socket exist? */
- if ((ignore == i+j) || (identify(port, sock+j) < 0))
+ if ((ignore == i+j) || (isa_identify(port, sock+j) < 0))
continue;
/* Check for bad socket decode */
for (k = 0; k <= sockets; k++)
@@ -857,6 +1158,47 @@
#endif
+#ifdef CONFIG_PCI
+static void pcic_interrupt(int irq, void *dev,
+ struct pt_regs *regs);
+
+static int i82365_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ socket_info_t *s = &socket[sockets];
+ int type = id->driver_data;
+ unsigned long addr;
+ int ns;
+
+ dev->driver_data = (void *)sockets;
+ printk("i82365_pci_probe\n");
+
+ if (pci_enable_device(dev))
+ return -EIO;
+
+ addr = dev->resource[0].start & ~1;
+ for (ns=0; ns < ((type == IS_I82092AA) ? 4 : 2); ns++) {
+ s[ns].dev = dev;
+ s[ns].cap.pci_irq = dev->irq;
+ pci_read_config_byte(dev, PCI_REVISION_ID, &s[ns].revision);
+ add_socket(addr, ns, type);
+ }
+
+ add_pcic(ns, type);
+ if (pci_csc && s[0].cap.pci_irq)
+ request_irq(dev->irq, pcic_interrupt, SA_SHIRQ, "i82365", pcic_interrupt);
+ return 0;
+
+}
+static void i82365_pci_remove(struct pci_dev *dev)
+{
+ u_short s = (u_short)dev->driver_data;
+
+ if (pci_csc && socket[s].cap.pci_irq)
+ free_irq(dev->irq, pcic_interrupt);
+}
+
+#endif
+
/*====================================================================*/
static u_int pending_events[8];
@@ -980,6 +1322,20 @@
*value |= (status & I365_CS_READY) ? SS_READY : 0;
*value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
+#ifdef CONFIG_PCI
+ if (socket[sock].flags & IS_O2MICRO) {
+ status = i365_get(sock, O2_MODE_B);
+ *value |= (status & O2_MODE_B_VS1) ? 0 : SS_3VCARD;
+ *value |= (status & O2_MODE_B_VS2) ? 0 : SS_XVCARD;
+ } else if (socket[sock].type == IS_PD6729) {
+ status = pd67_ext_get(sock + (1-socket[sock].psock), PD67_EXTERN_DATA);
+ *value |= (status & PD67_EXD_VS1(socket[sock].psock)) ? 0 : SS_3VCARD;
+ *value |= (status & PD67_EXD_VS2(socket[sock].psock)) ? 0 : SS_XVCARD;
+ }
+ /* For now, ignore cards with unsupported voltage keys */
+ if (*value & SS_XVCARD)
+ *value &= ~(SS_DETECT|SS_3VCARD|SS_XVCARD);
+#endif
#ifdef CONFIG_ISA
if (socket[sock].type == IS_VG469) {
status = i365_get(sock, VG469_VSENSE);
@@ -1044,7 +1400,13 @@
reg = i365_get(sock, I365_INTCTL);
state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
- state->io_irq = reg & I365_IRQ_MASK;
+
+#ifdef CONFIG_PCI
+ if (socket[sock].cap.pci_irq)
+ state->io_irq = socket[sock].cap.pci_irq;
+ else
+#endif
+ state->io_irq = reg & I365_IRQ_MASK;
/* speaker control */
if (t->flags & IS_CIRRUS) {
@@ -1084,8 +1446,8 @@
set_bridge_state(sock);
/* IO card, RESET flag, IO interrupt */
- reg = t->intr;
- if (state->io_irq != t->cap.pci_irq) reg |= state->io_irq;
+ reg = t->intr | ((state->io_irq == t->cap.pci_irq) ?
+ t->pci_irq_code : state->io_irq);
reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
i365_set(sock, I365_INTCTL, reg);
@@ -1164,7 +1526,7 @@
}
/* Card status change interrupt mask */
- reg = t->cs_irq << 4;
+ reg = (t->cap.pci_irq ? t->pci_irq_code : t->cs_irq) << 4;
if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
@@ -1261,6 +1623,13 @@
mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
mem->card_start &= 0x3ffffff;
+#ifdef CONFIG_PCI
+ /* Take care of high byte, for PCI controllers */
+ if (socket[sock].type == IS_PD6729) {
+ i365_set(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
+ addr = i365_get(sock, PD67_EXT_DATA) << 24;
+ }
+#endif
DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
"5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
mem->sys_start, mem->sys_stop, mem->card_start);
@@ -1290,6 +1659,13 @@
if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
+#ifdef CONFIG_PCI
+ /* Take care of high byte, for PCI controllers */
+ if (socket[sock].type == IS_PD6729) {
+ i365_set(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
+ i365_set(sock, PD67_EXT_DATA, (mem->sys_start >> 24));
+ }
+#endif
base = I365_MEM(map);
i = (mem->sys_start >> 12) & 0x0fff;
if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
@@ -1332,6 +1708,12 @@
char *p = buf;
p += sprintf(p, "type: %s\npsock: %d\n",
pcic[s->type].name, s->psock);
+#ifdef CONFIG_PCI
+ if (s->flags & (IS_PCI))
+ p += sprintf(p, "bus: %02x\ndevfn: %02x.%1x\n",
+ s->dev->bus->number, PCI_SLOT(s->dev->devfn),
+ PCI_FUNC(s->dev->devfn));
+#endif
return (p - buf);
}
@@ -1361,6 +1743,26 @@
return (p - buf);
}
+#ifdef CONFIG_PCI
+static int proc_read_pci(char *buf, char **start, off_t pos,
+ int count, int *eof, void *data)
+{
+ struct pci_dev *dev = ((socket_info_t *)data)->dev;
+ char *p = buf;
+ u_int a, b, c, d;
+ int i;
+
+ for (i = 0; i < 0xc0; i += 0x10) {
+ pci_read_config_dword(dev, i, &a);
+ pci_read_config_dword(dev, i+4, &b);
+ pci_read_config_dword(dev, i+8, &c);
+ pci_read_config_dword(dev, i+12, &d);
+ p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d);
+ }
+ return (p - buf);
+}
+#endif
+
static void pcic_proc_setup(unsigned int sock, struct proc_dir_entry *base)
{
socket_info_t *s = &socket[sock];
@@ -1370,15 +1772,26 @@
create_proc_read_entry("info", 0, base, proc_read_info, s);
create_proc_read_entry("exca", 0, base, proc_read_exca, s);
+#ifdef CONFIG_PCI
+ if (s->flags & IS_PCI)
+ create_proc_read_entry("pci", 0, base, proc_read_pci, s);
+#endif
s->proc = base;
}
static void pcic_proc_remove(u_short sock)
{
struct proc_dir_entry *base = socket[sock].proc;
- if (base == NULL) return;
+
+ if (base == NULL)
+ return;
+
remove_proc_entry("info", base);
remove_proc_entry("exca", base);
+#ifdef CONFIG_PCI
+ if (socket[sock].flags & IS_PCI)
+ remove_proc_entry("pci", base);
+#endif
}
#else
@@ -1523,12 +1936,19 @@
printk(KERN_INFO "Intel PCIC probe: ");
sockets = 0;
+#ifdef CONFIG_PCI
+ if (do_pci_probe)
+ pci_register_driver (&i82365_pci_drv);
+#endif
#ifdef CONFIG_ISA
isa_probe();
#endif
-
if (sockets == 0) {
printk("not found.\n");
+#ifdef CONFIG_PCI
+ if (do_pci_probe)
+ pci_unregister_driver (&i82365_pci_drv);
+#endif
return -ENODEV;
}
@@ -1537,7 +1957,7 @@
if (grab_irq != 0)
request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
#endif
-
+
if (register_ss_entry(sockets, &pcic_operations) != 0)
printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
@@ -1567,6 +1987,11 @@
if (grab_irq != 0)
free_irq(cs_irq, pcic_interrupt);
#endif
+#ifdef CONFIG_PCI
+ if (do_pci_probe)
+ pci_unregister_driver (&i82365_pci_drv);
+#endif
+
for (i = 0; i < sockets; i++) {
/* Turn off all interrupt sources! */
i365_set(i, I365_CSCINT, 0);
Index: drivers/pcmcia/i82365.h
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/i82365.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 i82365.h
--- drivers/pcmcia/i82365.h 2000/06/07 10:38:28 1.1.2.2
+++ drivers/pcmcia/i82365.h 2000/11/22 10:37:36
@@ -132,4 +132,9 @@
#define I365_REG(slot, reg) (((slot) << 6) + reg)
+#define O2_MODE_D_IRQ_MODE 0x03
+#define O2_MODE_D_IRQ_PCPCI 0x00
+#define O2_MODE_D_IRQ_PCIWAY 0x02
+#define O2_MODE_D_IRQ_PCI 0x03
+
#endif /* _LINUX_I82365_H */
--
dwmw2
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
2000-11-22 10:45 ` David Woodhouse
@ 2000-11-23 1:05 ` Michel Salim
[not found] ` <11299.974975638@redhat.com>
1 sibling, 0 replies; 6+ messages in thread
From: Michel Salim @ 2000-11-23 1:05 UTC (permalink / raw)
To: David Woodhouse; +Cc: Michel Salim, LKML, dhinds
Thanks for the patch... but it does not quite work. It applies cleanly,
but upon booting the patched kernel, the machine freezes completely upon
PCMCIA initialisation (it got to the point where the init script said
'Loading modules' then nothing). CTRL+ALT+DEL does not work, either.
Anyone got a clue? Would love to help debug this if someone would just
walk me through it.
Michel
David Woodhouse wrote:
> mas118@cs.york.ac.uk said:
>
>> Installed kernel 2.4.0-test11 on my Debian Woody box today. Had no
>> problem apart from getting PCMCIA to work. I have a PCI-PCMCIA adapter
>> on my desktop PC, using the Cirrus Logic CL6729 chipset;
>
>
> Linus got a bit carried away when stripping out all the CardBus support
> from i82365, and took out the support for PCI-PCMCIA bridges too.
>
> Try this snapshot of my development tree, or use lspci to find the IO
> address of the device and specify that to the existing module.
>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
[not found] ` <11299.974975638@redhat.com>
@ 2001-01-03 9:39 ` Michel Salim
2001-01-03 9:58 ` David Woodhouse
1 sibling, 0 replies; 6+ messages in thread
From: Michel Salim @ 2001-01-03 9:39 UTC (permalink / raw)
To: David Woodhouse; +Cc: LKML, dhinds
Manually inputting i365_base=0x1030 when loading the module results in
the same freeze - nothing works at all, had to do a full hardware reset.
This is on the latest 2.4.0-prerelease...
David, any luck on your side? Sorry for the long absence, been a bit
busy and then I went on holiday.
Any chance it's due to IRQ sharing? Since I've been struggling to use my
PCMCIA modem under kernel 2.2.x too... pcmcia-cs detects it and minicom
can dial using it but nothing else... :( the PCMCIA controller is on IRQ
11, same as my video card. Haven't tried swapping it since the cables
are a mess to reattach :p
A belated Happy New Year,
Michel
David Woodhouse wrote:
> mas118@demeter.cs.york.ac.uk said:
>
>> Thanks for the patch... but it does not quite work. It applies
>> cleanly, but upon booting the patched kernel, the machine freezes
>> completely upon PCMCIA initialisation (it got to the point where the
>> init script said 'Loading modules' then nothing). CTRL+ALT+DEL does
>> not work, either.
>
>
> Hmmm.
>
> mas118@demeter.cs.york.ac.uk said:
>
>> Anyone got a clue? Would love to help debug this if someone would
>> just walk me through it.
>
>
> I think you may have to wait until I next get left alone in the house with
> the opportunity to gut my girlfriend's machine and stick a PCMCIA
> controller in it, unless you're willing to work on this yourself.
>
> What I've done so far is to refer to the current i82365 code from David
> Hinds' standalone package, and put back into Linus' version all the
> non-CardBus CONFIG_PCI code which deals with PCI-PCMCIA bridges. As some
> changes have been made to the pcmcia core in David's version since the
> merge, that's not trivial, although it's quite simple.
>
> I probably missed something - probably a change which isn't in CONFIG_PCI
> ifdefs. Did it print anything before dying? Does it die if you haven't got
> any cards present when it initialises? Does it die if you ensure it's
> polling the socket for status changes and doesn't register the interrupt?
>
> Does it work with the standard driver in -test11 if you specify the correct
> i365_base= parameter as obtained from lspci?
>
> If it does work with the current driver, I'm half inclined to leave it
> alone until 2.5 when we can re-sync the pcmcia core and hopefully then
> it'll 'just work' if we drop in the standalone driver, perhaps with the
> cardbus-specific parts stripped out.
>
> --
> dwmw2
--
Michèl Alexandre Salim
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
[not found] ` <11299.974975638@redhat.com>
2001-01-03 9:39 ` Michel Salim
@ 2001-01-03 9:58 ` David Woodhouse
2001-01-05 15:32 ` Michel Salim
1 sibling, 1 reply; 6+ messages in thread
From: David Woodhouse @ 2001-01-03 9:58 UTC (permalink / raw)
To: Michel Salim; +Cc: LKML, dhinds
mas118@demeter.cs.york.ac.uk said:
> Manually inputting i365_base=0x1030 when loading the module results in
> the same freeze - nothing works at all, had to do a full hardware
> reset. This is on the latest 2.4.0-prerelease...
Is this the code in 2.4.0-prerelease or the code I sent you? Sounds like
it's probably dying in an IRQ storm.
mas118@demeter.cs.york.ac.uk said:
> David, any luck on your side? Sorry for the long absence, been a bit
> busy and then I went on holiday.
I have a full databook for the i82092aa and a selection of example boards -
was yours one of those or another type? I'm not entirely sure when I'll
have time to poke at it again - I may wait for the 2.5 branch.
mas118@demeter.cs.york.ac.uk said:
> Any chance it's due to IRQ sharing?
Possibly. Is any driver trying to use irq 11? Can you disable the irq for
the video card in your BIOS?
--
dwmw2
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11
2001-01-03 9:58 ` David Woodhouse
@ 2001-01-05 15:32 ` Michel Salim
0 siblings, 0 replies; 6+ messages in thread
From: Michel Salim @ 2001-01-05 15:32 UTC (permalink / raw)
To: David Woodhouse; +Cc: LKML, dhinds
David Woodhouse wrote:
> mas118@demeter.cs.york.ac.uk said:
>
>> Manually inputting i365_base=0x1030 when loading the module results in
>> the same freeze - nothing works at all, had to do a full hardware
>> reset. This is on the latest 2.4.0-prerelease...
>
>
> Is this the code in 2.4.0-prerelease or the code I sent you? Sounds like
> it's probably dying in an IRQ storm.
>
The one in prerelease.
> I have a full databook for the i82092aa and a selection of example boards -
> was yours one of those or another type? I'm not entirely sure when I'll
> have time to poke at it again - I may wait for the 2.5 branch.
>
> mas118@demeter.cs.york.ac.uk said:
>
>> Any chance it's due to IRQ sharing?
>
>
> Possibly. Is any driver trying to use irq 11? Can you disable the irq for
> the video card in your BIOS?
>
> --
> dwmw2
Well, got it working under 2.2.17. I suspect it is just a matter of the
drivers in 2.4.x not accomodating desktop-based PCMCIA readers. In the
latest PCMCIA Howto there is a subsection under 2.3 on such devices and
workarounds needed to get them running - none of them are recognised by
the i82365 driver in 2.4.0-prerelease.
I think I'll just stick to 2.2.x for the time being - if anyone fancy a
go at it I'm more than willing to try out the code.
Regards,
--
Michèl Alexandre Salim
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2001-01-05 15:33 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-21 18:35 i82365 PCI-PCMCIA bridge still not working in 2.4.0-test11 Michel Salim
2000-11-22 10:45 ` David Woodhouse
2000-11-23 1:05 ` Michel Salim
[not found] ` <11299.974975638@redhat.com>
2001-01-03 9:39 ` Michel Salim
2001-01-03 9:58 ` David Woodhouse
2001-01-05 15:32 ` Michel Salim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox