#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/system.h>
#include <asm/io.h>
#define NR_PORTS 64 /* maximum number of ports */
#define NR_PRIMARY 8 /* maximum number of primary ports */
+#define REGION_SIZE 8 /* size of io region to request */
/* The following variables can be set by giving module options */
static int irq[NR_PRIMARY]; /* IRQ for each base port */
MODULE_LICENSE("GPL");
-MODULE_PARM(irq, "1-8i");
-MODULE_PARM(divisor, "1-8i");
-MODULE_PARM(dma, "i");
-MODULE_PARM(rx_trigger, "i");
-MODULE_PARM(tx_trigger, "i");
-MODULE_PARM(flow_off, "i");
-MODULE_PARM(flow_on, "i");
-MODULE_PARM(rx_timeout, "i");
-MODULE_PARM(pio_threshold, "i");
+module_param_array(irq, int, NULL, 0);
+module_param_array(divisor, uint, NULL, 0);
+module_param(dma, uint, 0);
+module_param(rx_trigger, uint, 0);
+module_param(tx_trigger, uint, 0);
+module_param(flow_off, uint, 0);
+module_param(flow_on, uint, 0);
+module_param(rx_timeout, uint, 0);
+module_param(pio_threshold, uint, 0);
/* END */
restore_flags(flags);
}
-static int rs_write(struct tty_struct * tty, int from_user,
+static int rs_write(struct tty_struct * tty,
const unsigned char *buf, int count)
{
int c, t, ret = 0;
if (!tty || !info->xmit_buf || !tmp_buf)
return 0;
- if (from_user)
- down(&tmp_buf_sem);
-
while (1) {
/* Thanks to R. Wolff for suggesting how to do this with */
/* interrupts enabled */
if (c <= 0)
break;
- if (from_user) {
- c -= copy_from_user(tmp_buf, buf, c);
-
- if (!c) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
-
- memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
- } else
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ memcpy(info->xmit_buf + info->xmit_head, buf, c);
info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1);
info->xmit_cnt += c;
ret += c;
}
- if (from_user)
- up(&tmp_buf_sem);
-
save_flags(flags); cli();
if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
if (info->blocked_open) {
if (info->close_delay) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(info->close_delay);
+ msleep_interruptible(jiffies_to_msecs(info->close_delay));
}
wake_up_interruptible(&info->open_wait);
}
while ((serial_in(info, UART_ESI_STAT1) != 0x03) ||
(serial_in(info, UART_ESI_STAT2) != 0xff)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(char_time);
+ msleep_interruptible(jiffies_to_msecs(char_time));
if (signal_pending(current))
break;
* This routine is called by espserial_init() to initialize a specific serial
* port.
*/
-static _INLINE_ int autoconfig(struct esp_struct * info, int *region_start)
+static _INLINE_ int autoconfig(struct esp_struct * info)
{
int port_detected = 0;
unsigned long flags;
+ if (!request_region(info->port, REGION_SIZE, "esp serial"))
+ return -EIO;
+
save_flags(flags); cli();
/*
* Check for ESP card
*/
- if (!check_region(info->port, 8) &&
- serial_in(info, UART_ESI_BASE) == 0xf3) {
+ if (serial_in(info, UART_ESI_BASE) == 0xf3) {
serial_out(info, UART_ESI_CMD1, 0x00);
serial_out(info, UART_ESI_CMD1, 0x01);
info->irq = 4;
}
- if (ports && (ports->port == (info->port - 8))) {
- release_region(*region_start,
- info->port - *region_start);
- } else
- *region_start = info->port;
-
- if (!request_region(*region_start,
- info->port - *region_start + 8,
- "esp serial"))
- {
- restore_flags(flags);
- return -EIO;
- }
/* put card in enhanced mode */
/* this prevents access through */
serial_out(info, UART_ESI_CMD2, 0x00);
}
}
+ if (!port_detected)
+ release_region(info->port, REGION_SIZE);
restore_flags(flags);
return (port_detected);
/*
* The serial driver boot-time initialization code!
*/
-int __init espserial_init(void)
+static int __init espserial_init(void)
{
int i, offset;
- int region_start;
struct esp_struct * info;
struct esp_struct *last_primary = NULL;
int esp[] = {0x100,0x140,0x180,0x200,0x240,0x280,0x300,0x380};
info->irq = irq[i];
info->line = (i * 8) + (offset / 8);
- if (!autoconfig(info, ®ion_start)) {
+ if (!autoconfig(info)) {
i++;
offset = 0;
continue;
{
unsigned long flags;
int e1;
- unsigned int region_start, region_end;
struct esp_struct *temp_async;
struct esp_pio_buffer *pio_buf;
while (ports) {
if (ports->port) {
- region_start = region_end = ports->port;
- temp_async = ports;
-
- while (temp_async) {
- if ((region_start - temp_async->port) == 8) {
- region_start = temp_async->port;
- temp_async->port = 0;
- temp_async = ports;
- } else if ((temp_async->port - region_end)
- == 8) {
- region_end = temp_async->port;
- temp_async->port = 0;
- temp_async = ports;
- } else
- temp_async = temp_async->next_port;
- }
-
- release_region(region_start,
- region_end - region_start + 8);
+ release_region(ports->port, REGION_SIZE);
}
-
temp_async = ports->next_port;
kfree(ports);
ports = temp_async;