patch-2.0.37 linux/drivers/char/cyclades.c
Next file: linux/drivers/char/isicom.c
Previous file: linux/drivers/char/apm_bios.c
Back to the patch index
Back to the overall index
- Lines: 265
- Date:
Sun Jun 13 10:21:00 1999
- Orig file:
v2.0.36/linux/drivers/char/cyclades.c
- Orig date:
Sun Nov 15 21:51:46 1998
diff -u --recursive --new-file v2.0.36/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
@@ -1,7 +1,7 @@
#define BLOCKMOVE
#define Z_WAKE
static char rcsid[] =
-"$Revision: 2.1.1.10 $$Date: 1998/11/12 16:08:23 $";
+"$Revision: 2.1.2.1 $$Date: 1999/04/08 16:17:18 $";
/*
* linux/drivers/char/cyclades.c
@@ -31,7 +31,21 @@
* void cleanup_module(void);
*
* $Log: cyclades.c,v $
- * Revision: 2.1.1.10 1998/11/12 16:08:23 ivan
+ * Revision 2.1.2.1 1999/04/08 16:17:18 ivan
+ * cy_wait_until_sent function revisited;
+ * Module usage counter scheme revisited;
+ * Added support to the upcoming Y PCI boards (i.e., support to additional
+ * PCI Device ID's).
+ *
+ * Revision 2.1.1.12 1999/01/19 13:08:18 ivan
+ * Fixed PLX PCI bridge registers mapping for Cyclom-Y boards, so
+ * that it works even with addresses out of memory page boundaries.
+ *
+ * Revision 2.1.1.11 1998/12/30 18:58:47 ivan
+ * Changed access to PLX PCI bridge registers from I/O to MMIO, in
+ * order to make PLX9050-based boards work with certain motherboards.
+ *
+ * Revision 2.1.1.10 1998/11/12 16:08:23 ivan
* cy_close function now resets (correctly) the tty->closing flag;
* JIFFIES_DIFF macro fixed.
*
@@ -519,6 +533,7 @@
#undef CY_DEBUG_COUNT
#undef CY_DEBUG_DTR
#undef CY_DEBUG_WAIT_UNTIL_SENT
+#undef CY_DEBUG_INTERRUPTS
#undef CY_16Y_HACK
#undef CY_ENABLE_MONITORING
#undef CY_PCI_DEBUG
@@ -758,16 +773,20 @@
/* PCI related definitions */
-static unsigned short cy_pci_nboard = 0;
-static unsigned short cy_isa_nboard = 0;
-static unsigned short cy_nboard = 0;
-static unsigned short cy_pci_dev_id[] = {
- PCI_DEVICE_ID_CYCLOM_Y_Lo,/* PCI below 1Mb */
- PCI_DEVICE_ID_CYCLOM_Y_Hi,/* PCI above 1Mb */
- PCI_DEVICE_ID_CYCLOM_Z_Lo,/* PCI below 1Mb */
- PCI_DEVICE_ID_CYCLOM_Z_Hi,/* PCI above 1Mb */
- 0 /* end of table */
- };
+static unsigned short cy_pci_nboard = 0;
+static unsigned short cy_isa_nboard = 0;
+static unsigned short cy_nboard = 0;
+static unsigned short cy_pci_dev_id[] = {
+ PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */
+ PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */
+ PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
+ PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
+ PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
+ PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
+ PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */
+ PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */
+ 0 /* end of table */
+ };
static void cy_start(struct tty_struct *);
@@ -2508,13 +2527,17 @@
{
struct cyclades_port *info;
int retval, line;
+ unsigned long page;
+ MOD_INC_USE_COUNT;
line = MINOR(tty->device) - tty->driver.minor_start;
if ((line < 0) || (NR_PORTS <= line)){
+ MOD_DEC_USE_COUNT;
return -ENODEV;
}
info = &cy_port[line];
if (info->line < 0){
+ MOD_DEC_USE_COUNT;
return -ENODEV;
}
@@ -2540,6 +2563,8 @@
#ifdef CY_DEBUG_OTHER
printk("cyc:cy_open ttyC%d\n", info->line); /* */
#endif
+ tty->driver_data = info;
+ info->tty = tty;
if (serial_paranoia_check(info, tty->device, "cy_open")){
return -ENODEV;
}
@@ -2552,16 +2577,15 @@
printk("cyc:cy_open (%d): incrementing count to %d\n",
current->pid, info->count);
#endif
- tty->driver_data = info;
- info->tty = tty;
- /* Some drivers have (incorrect/incomplete) code to test
- against a race condition. Should add good code here!!! */
if (!tmp_buf) {
- tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
- if (!tmp_buf){
- return -ENOMEM;
- }
+ page = get_free_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+ if (tmp_buf)
+ free_page(page);
+ else
+ tmp_buf = (unsigned char *) page;
}
if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
@@ -2578,8 +2602,6 @@
return retval;
}
- MOD_INC_USE_COUNT;
-
retval = block_til_ready(tty, filp, info);
if (retval) {
#ifdef CY_DEBUG_OPEN
@@ -2612,6 +2634,9 @@
if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
return;
+ if (info->xmit_fifo_size == 0)
+ return; /* Just in case.... */
+
orig_jiffies = jiffies;
/*
* Set the check interval to be 1/5 of the estimated time to
@@ -2629,6 +2654,17 @@
timeout = 0;
if (timeout)
char_time = MIN(char_time, timeout);
+ /*
+ * If the transmitter hasn't cleared in twice the approximate
+ * amount of time to send the entire FIFO, it probably won't
+ * ever clear. This assumes the UART isn't doing flow
+ * control, which is currently the case. Hence, if it ever
+ * takes longer than info->timeout, this is probably due to a
+ * UART bug of some kind. So, we clamp the timeout parameter at
+ * 2*info->timeout.
+ */
+ if (!timeout || timeout > 2*info->timeout)
+ timeout = 2*info->timeout;
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
printk("jiff=%lu...", jiffies);
@@ -2682,8 +2718,7 @@
printk("cyc:cy_close ttyC%d\n", info->line);
#endif
- if (!info
- || serial_paranoia_check(info, tty->device, "cy_close")){
+ if (!info || serial_paranoia_check(info, tty->device, "cy_close")){
return;
}
#ifdef CY_DEBUG_OPEN
@@ -4707,7 +4742,6 @@
{
#ifdef CONFIG_PCI
unsigned char cyy_bus, cyy_dev_fn, cyy_rev_id;
- unsigned long pci_intr_ctrl;
unsigned char cy_pci_irq;
uclong cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
unsigned short i,j,cy_pci_nchan, plx_ver;
@@ -4751,6 +4785,8 @@
pcibios_read_config_byte(cyy_bus, cyy_dev_fn,
PCI_REVISION_ID, &cyy_rev_id);
+ device_id &= ~PCI_DEVICE_ID_MASK;
+
if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
|| (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
#ifdef CY_PCI_DEBUG
@@ -4758,11 +4794,11 @@
cyy_bus, cyy_dev_fn);
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx ioaddr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr1);
+ printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
+ (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
#endif
- cy_pci_addr1 &= PCI_BASE_ADDRESS_IO_MASK;
- cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+ cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
#if defined(__alpha__)
if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
@@ -4770,21 +4806,24 @@
cyy_bus, cyy_dev_fn);
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx ioaddr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr1);
+ printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
+ (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
printk("Cyclom-Y/PCI not supported for low addresses in "
"Alpha systems.\n");
i--;
continue;
}
#else
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0 & PAGE_MASK,
+ PAGE_ALIGN(CyPCI_Yctl))
+ + (cy_pci_addr0 & (PAGE_SIZE-1));
if ((ulong)cy_pci_addr2 >= 0x100000) /* above 1M? */
cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin);
#endif
#ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ioaddr=0x%lx\n",
- (u_long)cy_pci_addr2, (u_long)cy_pci_addr1);
+ printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
+ (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
#endif
cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
cyy_init_card((volatile ucchar *)cy_pci_addr2, 1));
@@ -4827,7 +4866,7 @@
/* set cy_card */
cy_card[j].base_addr = (ulong)cy_pci_addr2;
- cy_card[j].ctl_addr = 0;
+ cy_card[j].ctl_addr = (ulong)cy_pci_addr0;
cy_card[j].irq = (int) cy_pci_irq;
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
@@ -4839,20 +4878,16 @@
switch (plx_ver) {
case PLX_9050:
- outw(inw(cy_pci_addr1+0x4c)|0x0040,cy_pci_addr1+0x4c);
- pci_intr_ctrl = (unsigned long)
- (inw(cy_pci_addr1+0x4c)
- | inw(cy_pci_addr1+0x4e)<<16);
+ cy_writew(cy_pci_addr0+0x4c,
+ cy_readw(cy_pci_addr0+0x4c)|0x0040);
break;
case PLX_9060:
case PLX_9080:
default: /* Old boards, use PLX_9060 */
- outw(inw(cy_pci_addr1+0x68)|0x0900,cy_pci_addr1+0x68);
- pci_intr_ctrl = (unsigned long)
- (inw(cy_pci_addr1+0x68)
- | inw(cy_pci_addr1+0x6a)<<16);
+ cy_writew(cy_pci_addr0+0x68,
+ cy_readw(cy_pci_addr0+0x68)|0x0900);
break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov