patch-2.3.23 linux/drivers/pcmcia/i82365.c
Next file: linux/drivers/pcmcia/o2micro.h
Previous file: linux/drivers/pcmcia/cs.c
Back to the patch index
Back to the overall index
- Lines: 656
- Date:
Wed Oct 20 21:33:12 1999
- Orig file:
v2.3.22/linux/drivers/pcmcia/i82365.c
- Orig date:
Mon Oct 4 15:49:29 1999
diff -u --recursive --new-file v2.3.22/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
@@ -3,7 +3,7 @@
Device driver for Intel 82365 and compatible PC Card controllers,
and Yenta-compatible PCI-to-CardBus controllers.
- i82365.c 1.254 1999/09/15 15:32:19
+ i82365.c 1.260 1999/10/21 00:56:07
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
@@ -76,7 +76,7 @@
MODULE_PARM(pc_debug, "i");
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static const char *version =
-"i82365.c 1.254 1999/09/15 15:32:19 (David Hinds)";
+"i82365.c 1.260 1999/10/21 00:56:07 (David Hinds)";
#else
#define DEBUG(n, args...) do { } while (0)
#endif
@@ -189,7 +189,7 @@
#ifdef CONFIG_ISA
#ifdef CONFIG_PCI
/* PCI card status change interrupts? */
-static int pci_csc = 0;
+static int pci_csc = 1;
/* PCI IO card functional interrupts? */
static int pci_int = 0;
MODULE_PARM(pci_csc, "i");
@@ -240,7 +240,7 @@
typedef struct socket_info_t {
u_short type, flags;
socket_cap_t cap;
- u_short ioaddr;
+ ioaddr_t ioaddr;
u_short psock;
u_char cs_irq, intr;
void (*handler)(void *info, u_int events);
@@ -278,18 +278,18 @@
/* Default ISA interrupt mask */
#define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */
-static void pcic_interrupt_wrapper(u_long);
-static void pcic_interrupt(int irq, void *dev,
- struct pt_regs *regs);
-static int pcic_service(u_int sock, u_int cmd, void *arg);
-#ifdef CONFIG_PROC_FS
-static void pcic_proc_remove(u_short sock);
-#endif
-
#ifdef CONFIG_ISA
static int grab_irq;
static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
+#define ISA_LOCK(n, f) \
+ if (!(socket[n].flags & IS_CARDBUS)) spin_lock_irqsave(&isa_lock, f)
+#define ISA_UNLOCK(n, f) \
+ if (!(socket[n].flags & IS_CARDBUS)) spin_unlock_irqrestore(&isa_lock, f)
+#else
+#define ISA_LOCK(n, f) do { } while (0)
+#define ISA_UNLOCK(n, f) do { } while (0)
#endif
+
static struct timer_list poll_timer;
/*====================================================================*/
@@ -322,7 +322,7 @@
#ifdef CONFIG_PCI
IS_PD6729, IS_PD6730, IS_OZ6729, IS_OZ6730,
IS_I82092AA, IS_OM82C092G,
- IS_PD6832, IS_OZ6832, IS_OZ6836,
+ IS_PD6832, IS_OZ6832, IS_OZ6836, IS_OZ6812,
IS_RL5C465, IS_RL5C466, IS_RL5C475, IS_RL5C476, IS_RL5C478,
IS_SMC34C90,
IS_TI1130, IS_TI1131, IS_TI1250A, IS_TI1220, IS_TI1221, IS_TI1210,
@@ -388,6 +388,8 @@
PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6832 },
{ "O2Micro OZ6836/OZ6860", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR,
PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6836 },
+ { "O2Micro OZ6812", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR,
+ PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6812 },
{ "Ricoh RL5C465", IS_RICOH|IS_CARDBUS|IS_DF_PWR,
PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465 },
{ "Ricoh RL5C466", IS_RICOH|IS_CARDBUS|IS_DF_PWR,
@@ -441,8 +443,6 @@
/* Some PCI shortcuts */
-#ifdef CONFIG_PCI
-
#define pci_readb pcibios_read_config_byte
#define pci_writeb pcibios_write_config_byte
#define pci_readw pcibios_read_config_word
@@ -457,7 +457,6 @@
static void cb_get_power(u_short sock, socket_state_t *state);
static void cb_set_power(u_short sock, socket_state_t *state);
-#endif
/*====================================================================*/
@@ -469,7 +468,7 @@
else
#endif
{
- u_short port = socket[sock].ioaddr;
+ ioaddr_t port = socket[sock].ioaddr;
u_char val;
reg = I365_REG(socket[sock].psock, reg);
outb(reg, port); val = inb(port+1);
@@ -485,7 +484,7 @@
else
#endif
{
- u_short port = socket[sock].ioaddr;
+ ioaddr_t port = socket[sock].ioaddr;
u_char val = I365_REG(socket[sock].psock, reg);
outb(val, port); outb(data, port+1);
}
@@ -954,6 +953,8 @@
p->mode_e &= ~O2_MODE_E_MHPG_DMA;
p->mhpg |= O2_MHPG_CINT_ENA | O2_MHPG_CSC_ENA;
p->mhpg &= ~O2_MHPG_CHANNEL;
+ if (t->revision == 0x34)
+ p->mode_c = 0x20;
} else {
if (p->mode_b & O2_MODE_B_IRQ15_RI) mask &= ~0x8000;
}
@@ -1125,7 +1126,7 @@
======================================================================*/
-static void get_host_state(u_short s)
+static void get_bridge_state(u_short s)
{
socket_info_t *t = &socket[s];
if (t->flags & IS_CIRRUS)
@@ -1148,7 +1149,7 @@
#endif
}
-static void set_host_state(u_short s)
+static void set_bridge_state(u_short s)
{
socket_info_t *t = &socket[s];
#ifdef CONFIG_PCI
@@ -1178,7 +1179,7 @@
#endif
}
-static u_int __init set_host_opts(u_short s, u_short ns)
+static u_int __init set_bridge_opts(u_short s, u_short ns)
{
u_short i;
u_int m = 0xffff;
@@ -1190,7 +1191,7 @@
continue;
}
buf[0] = '\0';
- get_host_state(i);
+ get_bridge_state(i);
if (socket[i].flags & IS_CIRRUS)
m = cirrus_set_opts(i, buf);
#ifdef CONFIG_ISA
@@ -1209,7 +1210,7 @@
if (socket[i].flags & IS_CARDBUS)
cb_set_opts(i, buf+strlen(buf));
#endif
- set_host_state(i);
+ set_bridge_state(i);
printk(KERN_INFO " host opts [%d]:%s\n", i,
(*buf) ? buf : " none");
}
@@ -1255,7 +1256,7 @@
if (request_irq(irq, irq_count, (pci?SA_SHIRQ:0), "scan", NULL) != 0)
return 1;
irq_hits = 0; irq_sock = sock;
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/100);
if (irq_hits) {
free_irq(irq, NULL);
@@ -1310,7 +1311,7 @@
(cb_set_irq_mode(sock, 0, 0) == 0))
#endif
if (do_scan) {
- set_host_state(sock);
+ 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) == 0))
@@ -1351,7 +1352,7 @@
u_int i;
cb_set_irq_mode(sock, 1, 0);
- set_host_state(sock);
+ set_bridge_state(sock);
i365_set(sock, I365_CSCINT, 0);
/* Only probe irq's 9..11, to be conservative */
for (i = 9; i < 12; i++) {
@@ -1371,7 +1372,7 @@
static int to_cycles(int ns)
{
return ns/cycle_time;
-} /* speed_convert */
+}
static int to_ns(int cycles)
{
@@ -1517,7 +1518,7 @@
for (i = mask = 0; i < 16; i++)
mask |= (1<<irq_list[i]);
#endif
- mask &= I365_MASK & set_host_opts(base, ns);
+ mask &= I365_MASK & set_bridge_opts(base, ns);
#ifdef CONFIG_ISA
/* Scan for ISA interrupts */
mask = isa_scan(base, mask);
@@ -1672,8 +1673,7 @@
s->cb_virt = ioremap(s->cb_phys, 0x1000);
pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, s->cb_phys);
/* Simple sanity checks */
- if (((readb(s->cb_virt+0x800+I365_IDENT) & 0xf0)
- == 0x80) &&
+ if (!(readb(s->cb_virt+0x800+I365_IDENT) & 0x70) &&
!(readb(s->cb_virt+0x800+I365_CSC) &&
readb(s->cb_virt+0x800+I365_CSC) &&
readb(s->cb_virt+0x800+I365_CSC)))
@@ -1712,7 +1712,7 @@
/* Re-do card type & voltage detection */
cb_writel(sockets-ns, CB_SOCKET_FORCE, CB_SF_CVSTEST);
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/5);
/* Set up PCI bus bridge structures if needed */
@@ -1762,9 +1762,8 @@
static void __init isa_probe(void)
{
- int i, j, sock, k;
- int ns, id;
- u_short port;
+ int i, j, sock, k, ns, id;
+ ioaddr_t port;
if (check_region(i365_base, 2) != 0) {
if (sockets == 0)
@@ -1812,115 +1811,6 @@
/*====================================================================*/
-static int __init init_i82365(void)
-{
- servinfo_t serv;
- CardServices(GetCardServicesInfo, &serv);
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "i82365: Card Services release "
- "does not match!\n");
- return -1;
- }
- DEBUG(0, "%s\n", version);
- printk(KERN_INFO "Intel PCIC probe: ");
- sockets = 0;
-
-#ifdef CONFIG_PCI
- if (do_pci_probe && pcibios_present()) {
- pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge);
- pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge);
- }
-#endif
-
-#ifdef CONFIG_ISA
- isa_probe();
-#endif
-
- if (sockets == 0) {
- printk("not found.\n");
- return -ENODEV;
- }
-
- /* Set up interrupt handler(s) */
-#ifdef CONFIG_ISA
- if (grab_irq != 0)
- request_irq(cs_irq, pcic_interrupt, 0, "i82365", NULL);
-#endif
-#ifdef CONFIG_PCI
- if (pci_csc) {
- u_int i, irq, mask = 0;
- for (i = 0; i < sockets; i++) {
- irq = socket[i].cap.pci_irq;
- if (irq && !(mask & (1<<irq)))
- request_irq(irq, pcic_interrupt, SA_SHIRQ, "i82365", NULL);
- mask |= (1<<irq);
- }
- }
-#endif
-
- if (register_ss_entry(sockets, &pcic_service) != 0)
- printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
-
- /* Finally, schedule a polling interrupt */
- if (poll_interval != 0) {
- poll_timer.function = pcic_interrupt_wrapper;
- poll_timer.data = 0;
- poll_timer.prev = poll_timer.next = NULL;
- poll_timer.expires = jiffies + poll_interval;
- add_timer(&poll_timer);
- }
-
- return 0;
-
-} /* init_i82365 */
-
-/*====================================================================*/
-
-static void __exit exit_i82365(void)
-{
- int i;
-#ifdef CONFIG_PROC_FS
- for (i = 0; i < sockets; i++) pcic_proc_remove(i);
-#endif
- unregister_ss_entry(&pcic_service);
- if (poll_interval != 0)
- del_timer(&poll_timer);
-#ifdef CONFIG_ISA
- if (grab_irq != 0)
- free_irq(cs_irq, NULL);
-#endif
-#ifdef CONFIG_PCI
- if (pci_csc) {
- u_int irq, mask = 0;
- for (i = 0; i < sockets; i++) {
- irq = socket[i].cap.pci_irq;
- if (irq && !(mask & (1<<irq)))
- free_irq(irq, NULL);
- mask |= (1<<irq);
- }
- }
-#endif
- for (i = 0; i < sockets; i++) {
- i365_set(i, I365_CSCINT, 0);
-#ifdef CONFIG_PCI
- if (socket[i].cb_virt) {
- iounmap(socket[i].cb_virt);
- release_mem_region(socket[i].cb_phys, 0x1000);
- } else
-#endif
- release_region(socket[i].ioaddr, 2);
- }
-} /* exit_i82365 */
-
-/*====================================================================*/
-
-static void pcic_interrupt_wrapper(u_long data)
-{
- pcic_interrupt(0, NULL, NULL);
- poll_timer.expires = jiffies + poll_interval;
- add_timer(&poll_timer);
-}
-
static void pcic_interrupt(int irq, void *dev,
struct pt_regs *regs)
{
@@ -1938,17 +1828,18 @@
if ((socket[i].cs_irq != irq) &&
(socket[i].cap.pci_irq != irq))
continue;
-#ifdef CONFIG_ISA
- if (!(socket[i].flags & IS_CARDBUS))
- spin_lock_irqsave(&isa_lock, flags);
-#endif
+ ISA_LOCK(i, flags);
csc = i365_get(i, I365_CSC);
+#ifdef CONFIG_PCI
+ if ((socket[i].flags & IS_CARDBUS) &&
+ (cb_readl(i,CB_SOCKET_EVENT) & (CB_SE_CCD1|CB_SE_CCD2))) {
+ cb_writel(i, CB_SOCKET_EVENT, CB_SE_CCD1|CB_SE_CCD2);
+ csc |= I365_CSC_DETECT;
+ }
+#endif
if ((csc == 0) || (!socket[i].handler) ||
(i365_get(i, I365_IDENT) & 0x70)) {
-#ifdef CONFIG_ISA
- if (!(socket[i].flags & IS_CARDBUS))
- spin_unlock_irqrestore(&isa_lock, flags);
-#endif
+ ISA_UNLOCK(i, flags);
continue;
}
events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
@@ -1959,10 +1850,7 @@
events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
}
-#ifdef CONFIG_ISA
- if (!(socket[i].flags & IS_CARDBUS))
- spin_unlock_irqrestore(&isa_lock, flags);
-#endif
+ ISA_UNLOCK(i, flags);
DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
if (events)
socket[i].handler(socket[i].info, events);
@@ -1976,6 +1864,13 @@
DEBUG(4, "i82365: interrupt done\n");
} /* pcic_interrupt */
+static void pcic_interrupt_wrapper(u_long data)
+{
+ pcic_interrupt(0, NULL, NULL);
+ poll_timer.expires = jiffies + poll_interval;
+ add_timer(&poll_timer);
+}
+
/*====================================================================*/
static int pcic_register_callback(u_short sock, ss_callback_t *call)
@@ -2149,7 +2044,7 @@
(t->cap.pci_irq == state->io_irq));
t->bcr &= ~CB_BCR_CB_RESET;
#endif
- set_host_state(sock);
+ set_bridge_state(sock);
/* IO card, RESET flag, IO interrupt */
reg = t->intr;
@@ -2250,6 +2145,13 @@
}
i365_set(sock, I365_CSCINT, reg);
i365_get(sock, I365_CSC);
+#ifdef CONFIG_PCI
+ if (t->flags & IS_CARDBUS) {
+ if (t->cs_irq || (pci_csc && t->cap.pci_irq))
+ cb_writel(sock, CB_SOCKET_MASK, CB_SM_CCD);
+ cb_writel(sock, CB_SOCKET_EVENT, -1);
+ }
+#endif
return 0;
} /* i365_set_socket */
@@ -2428,7 +2330,7 @@
case CB_SC_VCC_3V: state->Vcc = 33; break;
case CB_SC_VCC_5V: state->Vcc = 50; break;
}
- switch (reg & CB_SC_VCC_MASK) {
+ switch (reg & CB_SC_VPP_MASK) {
case CB_SC_VPP_3V: state->Vpp = 33; break;
case CB_SC_VPP_5V: state->Vpp = 50; break;
case CB_SC_VPP_12V: state->Vpp = 120; break;
@@ -2509,12 +2411,12 @@
(s->cap.pci_irq == state->io_irq));
s->bcr &= ~CB_BCR_CB_RESET;
s->bcr |= (state->flags & SS_RESET) ? CB_BCR_CB_RESET : 0;
- set_host_state(sock);
+ set_bridge_state(sock);
cb_set_power(sock, state);
/* Handle IO interrupt using ISA routing */
- reg = i365_get(sock, I365_INTCTL) & ~I365_IRQ_MASK;
+ reg = s->intr;
if (state->io_irq != s->cap.pci_irq) reg |= state->io_irq;
i365_set(sock, I365_INTCTL, reg);
@@ -2523,6 +2425,9 @@
if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
i365_set(sock, I365_CSCINT, reg);
i365_get(sock, I365_CSC);
+ if (s->cs_irq || (pci_csc && s->cap.pci_irq))
+ cb_writel(sock, CB_SOCKET_MASK, CB_SM_CCD);
+ cb_writel(sock, CB_SOCKET_EVENT, -1);
return 0;
} /* cb_set_socket */
@@ -2623,9 +2528,8 @@
#ifdef CONFIG_ISA
u_long flags = 0;
- if (!(socket[sock].flags & IS_CARDBUS))
- spin_lock_irqsave(&isa_lock, flags);
#endif
+ ISA_LOCK(sock, flags);
top = 0x40;
if (socket[sock].flags & IS_CARDBUS)
top = (socket[sock].flags & IS_CIRRUS) ? 0x140 : 0x50;
@@ -2639,10 +2543,7 @@
i365_get(sock,i+2), i365_get(sock,i+3),
((i % 16) == 12) ? "\n" : " ");
}
-#ifdef CONFIG_ISA
- if (!(socket[sock].flags & IS_CARDBUS))
- spin_unlock_irqrestore(&isa_lock, flags);
-#endif
+ ISA_UNLOCK(sock, flags);
return (p - buf);
}
@@ -2672,13 +2573,15 @@
int count, int *eof, void *data)
{
u_short sock = (socket_info_t *)data - socket;
- int len;
-
- len = sprintf(buf, "%08x %08x %08x %08x %08x %08x\n",
- cb_readl(sock,0), cb_readl(sock,4),
- cb_readl(sock,8), cb_readl(sock,12),
- cb_readl(sock,16), cb_readl(sock,32));
- return len;
+ char *p = buf;
+ int i, top;
+
+ top = (socket[sock].flags & IS_O2MICRO) ? 0x30 : 0x20;
+ for (i = 0; i < top; i += 0x10)
+ p += sprintf(p, "%08x %08x %08x %08x\n",
+ cb_readl(sock,i+0x00), cb_readl(sock,i+0x04),
+ cb_readl(sock,i+0x08), cb_readl(sock,i+0x0c));
+ return (p - buf);
}
#endif
@@ -2757,7 +2660,11 @@
static int pcic_service(u_int sock, u_int cmd, void *arg)
{
subfn_t fn;
-
+ int ret;
+#ifdef CONFIG_ISA
+ u_long flags = 0;
+#endif
+
DEBUG(2, "pcic_ioctl(%d, %d, 0x%p)\n", sock, cmd, arg);
if (cmd >= NFUNC)
@@ -2782,20 +2689,114 @@
}
#endif
+ ISA_LOCK(sock, flags);
+ ret = (fn == NULL) ? -EINVAL : fn(sock, arg);
+ ISA_UNLOCK(sock, flags);
+ return ret;
+} /* pcic_service */
+
+/*====================================================================*/
+
+static int __init init_i82365(void)
+{
+ servinfo_t serv;
+ CardServices(GetCardServicesInfo, &serv);
+ if (serv.Revision != CS_RELEASE_CODE) {
+ printk(KERN_NOTICE "i82365: Card Services release "
+ "does not match!\n");
+ return -1;
+ }
+ DEBUG(0, "%s\n", version);
+ printk(KERN_INFO "Intel PCIC probe: ");
+ sockets = 0;
+
+#ifdef CONFIG_PCI
+ if (do_pci_probe && pcibios_present()) {
+ pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge);
+ pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge);
+ }
+#endif
+
#ifdef CONFIG_ISA
- if (!(socket[sock].flags & IS_CARDBUS)) {
- int ret;
- u_long flags;
- spin_lock_irqsave(&isa_lock, flags);
- ret = (fn == NULL) ? -EINVAL : fn(sock, arg);
- spin_unlock_irqrestore(&isa_lock, flags);
- return ret;
+ isa_probe();
+#endif
+
+ if (sockets == 0) {
+ printk("not found.\n");
+ return -ENODEV;
}
+
+ /* Set up interrupt handler(s) */
+#ifdef CONFIG_ISA
+ if (grab_irq != 0)
+ request_irq(cs_irq, pcic_interrupt, 0, "i82365", NULL);
#endif
- return (fn == NULL) ? -EINVAL : fn(sock, arg);
-} /* pcic_service */
+#ifdef CONFIG_PCI
+ if (pci_csc) {
+ u_int i, irq, mask = 0;
+ for (i = 0; i < sockets; i++) {
+ irq = socket[i].cap.pci_irq;
+ if (irq && !(mask & (1<<irq)))
+ request_irq(irq, pcic_interrupt, SA_SHIRQ, "i82365", NULL);
+ mask |= (1<<irq);
+ }
+ }
+#endif
+
+ if (register_ss_entry(sockets, &pcic_service) != 0)
+ printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
-/*====================================================================*/
+ /* Finally, schedule a polling interrupt */
+ if (poll_interval != 0) {
+ poll_timer.function = pcic_interrupt_wrapper;
+ poll_timer.data = 0;
+ poll_timer.prev = poll_timer.next = NULL;
+ poll_timer.expires = jiffies + poll_interval;
+ add_timer(&poll_timer);
+ }
+
+ return 0;
+
+} /* init_i82365 */
+
+static void __exit exit_i82365(void)
+{
+ int i;
+#ifdef CONFIG_PROC_FS
+ for (i = 0; i < sockets; i++) pcic_proc_remove(i);
+#endif
+ unregister_ss_entry(&pcic_service);
+ if (poll_interval != 0)
+ del_timer(&poll_timer);
+#ifdef CONFIG_ISA
+ if (grab_irq != 0)
+ free_irq(cs_irq, NULL);
+#endif
+#ifdef CONFIG_PCI
+ if (pci_csc) {
+ u_int irq, mask = 0;
+ for (i = 0; i < sockets; i++) {
+ irq = socket[i].cap.pci_irq;
+ if (irq && !(mask & (1<<irq)))
+ free_irq(irq, NULL);
+ mask |= (1<<irq);
+ }
+ }
+#endif
+ for (i = 0; i < sockets; i++) {
+ /* Turn off all interrupt sources! */
+ i365_set(i, I365_CSCINT, 0);
+#ifdef CONFIG_PCI
+ if (socket[i].flags & IS_CARDBUS)
+ cb_writel(i, CB_SOCKET_MASK, 0);
+ if (socket[i].cb_virt) {
+ iounmap(socket[i].cb_virt);
+ release_mem_region(socket[i].cb_phys, 0x1000);
+ } else
+#endif
+ release_region(socket[i].ioaddr, 2);
+ }
+} /* exit_i82365 */
module_init(init_i82365);
module_exit(exit_i82365);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)