#define MAX_PCI_DEVICES 10
#define MAX_TOTAL_DEVICES 20
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
return mgsl_get_text_ptr;
}
+/*
+ * tmp_buf is used as a temporary buffer by mgsl_write. We need to
+ * lock it in case the COPY_FROM_USER blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ioports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static unsigned char *tmp_buf;
+
static inline int mgsl_paranoia_check(struct mgsl_struct *info,
char *name, const char *routine)
{
} else
info->input_signal_events.dcd_down++;
#ifdef CONFIG_HDLC
- if (info->netcount) {
- if (status & MISCSTATUS_DCD)
- netif_carrier_on(info->netdev);
- else
- netif_carrier_off(info->netdev);
- }
+ if (info->netcount)
+ hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev);
#endif
}
if (status & MISCSTATUS_CTS_LATCHED)
if (mgsl_paranoia_check(info, tty->name, "mgsl_write"))
goto cleanup;
- if (!tty || !info->xmit_buf)
+ if (!tty || !info->xmit_buf || !tmp_buf)
goto cleanup;
if ( info->params.mode == MGSL_MODE_HDLC ||
{
struct mgsl_struct *info;
int retval, line;
+ unsigned long page;
unsigned long flags;
/* verify range of specified line number */
goto cleanup;
}
+ if (!tmp_buf) {
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page) {
+ retval = -ENOMEM;
+ goto cleanup;
+ }
+ if (tmp_buf)
+ free_page(page);
+ else
+ tmp_buf = (unsigned char *) page;
+ }
+
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
spin_lock_irqsave(&info->netlock, flags);
kfree(tmp);
}
+ if (tmp_buf) {
+ free_page((unsigned long) tmp_buf);
+ tmp_buf = NULL;
+ }
+
if (pci_registered)
pci_unregister_driver(&synclink_pci_driver);
}
* <15..8> ? RxFIFO IRQ Request Level
*
* Note: For async mode the receive FIFO level must be set
- * to 0 to avoid the situation where the FIFO contains fewer bytes
+ * to 0 to aviod the situation where the FIFO contains fewer bytes
* than the trigger level and no more data is expected.
*
* <7> 0 Exited Hunt IA (Interrupt Arm)
}
info->params.encoding = new_encoding;
- info->params.crc_type = new_crctype;
+ info->params.crc_type = new_crctype;;
/* if network interface up, reprogram hardware */
if (info->netcount)
spin_lock_irqsave(&info->irq_spinlock, flags);
usc_get_serial_signals(info);
spin_unlock_irqrestore(&info->irq_spinlock, flags);
- if (info->serial_signals & SerialSignal_DCD)
- netif_carrier_on(dev);
- else
- netif_carrier_off(dev);
+ hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
+
return 0;
}
info->bus_type = MGSL_BUS_TYPE_PCI;
info->io_addr_size = 8;
- info->irq_flags = IRQF_SHARED;
+ info->irq_flags = SA_SHIRQ;
if (dev->device == 0x0210) {
/* Version 1 PCI9030 based universal PCI adapter */