#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include "digiPCI.h"
*/
static DEFINE_SPINLOCK(epca_lock);
-/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. */
+/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted
+ to 7 below. */
static struct board_info boards[MAXBOARDS];
static struct tty_driver *pc_driver;
static void pc_close(struct tty_struct *, struct file *);
static void shutdown(struct channel *);
static void pc_hangup(struct tty_struct *);
-static void pc_put_char(struct tty_struct *, unsigned char);
static int pc_write_room(struct tty_struct *);
static int pc_chars_in_buffer(struct tty_struct *);
static void pc_flush_buffer(struct tty_struct *);
static void pc_flush_chars(struct tty_struct *);
static int block_til_ready(struct tty_struct *, struct file *,
- struct channel *);
+ struct channel *);
static int pc_open(struct tty_struct *, struct file *);
static void post_fep_init(unsigned int crd);
static void epcapoll(unsigned long);
static void epcaparam(struct tty_struct *, struct channel *);
static void receive_data(struct channel *);
static int pc_ioctl(struct tty_struct *, struct file *,
- unsigned int, unsigned long);
+ unsigned int, unsigned long);
static int info_ioctl(struct tty_struct *, struct file *,
- unsigned int, unsigned long);
+ unsigned int, unsigned long);
static void pc_set_termios(struct tty_struct *, struct ktermios *);
static void do_softint(struct work_struct *work);
static void pc_stop(struct tty_struct *);
static void pc_start(struct tty_struct *);
-static void pc_throttle(struct tty_struct * tty);
+static void pc_throttle(struct tty_struct *tty);
static void pc_unthrottle(struct tty_struct *tty);
static void digi_send_break(struct channel *ch, int msec);
static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
-void epca_setup(char *, int *);
+static void epca_setup(char *, int *);
static int pc_write(struct tty_struct *, const unsigned char *, int);
static int pc_init(void);
/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */
static void pcxem_memwinon(struct board_info *b, unsigned int win)
{
- outb_p(FEPWIN|win, b->port + 1);
+ outb_p(FEPWIN | win, b->port + 1);
}
static void pcxem_memwinoff(struct board_info *b, unsigned int win)
static void pcxem_globalwinon(struct channel *ch)
{
- outb_p( FEPWIN, (int)ch->board->port + 1);
+ outb_p(FEPWIN, (int)ch->board->port + 1);
}
static void pcxem_rxwinon(struct channel *ch)
*/
if (tty) {
struct channel *ch = (struct channel *)tty->driver_data;
- if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) {
+ if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) {
if (ch->magic == EPCA_MAGIC)
return ch;
}
static void epca_error(int line, char *msg)
{
- printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg);
+ printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg);
}
static void pc_close(struct tty_struct *tty, struct file *filp)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if (tty_hung_up_p(filp)) {
spin_unlock_irqrestore(&epca_lock, flags);
return;
}
- if (ch->count-- > 1) {
+ if (ch->port.count-- > 1) {
/* Begin channel is open more than once */
/*
* Return without doing anything. Someone might still
spin_unlock_irqrestore(&epca_lock, flags);
return;
}
-
/* Port open only once go ahead with shutdown & reset */
- BUG_ON(ch->count < 0);
+ BUG_ON(ch->port.count < 0);
/*
* Let the rest of the driver know the channel is being closed.
* This becomes important if an open is attempted before close
* is finished.
*/
- ch->asyncflags |= ASYNC_CLOSING;
+ ch->port.flags |= ASYNC_CLOSING;
tty->closing = 1;
spin_unlock_irqrestore(&epca_lock, flags);
- if (ch->asyncflags & ASYNC_INITIALIZED) {
- /* Setup an event to indicate when the transmit buffer empties */
+ if (ch->port.flags & ASYNC_INITIALIZED) {
+ /* Setup an event to indicate when the
+ transmit buffer empties */
setup_empty_event(tty, ch);
- tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+ /* 30 seconds timeout */
+ tty_wait_until_sent(tty, 3000);
}
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ pc_flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(ch);
spin_lock_irqsave(&epca_lock, flags);
tty->closing = 0;
ch->event = 0;
- ch->tty = NULL;
+ ch->port.tty = NULL;
spin_unlock_irqrestore(&epca_lock, flags);
- if (ch->blocked_open) {
+ if (ch->port.blocked_open) {
if (ch->close_delay)
msleep_interruptible(jiffies_to_msecs(ch->close_delay));
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
- ASYNC_CLOSING);
- wake_up_interruptible(&ch->close_wait);
+ ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
+ ASYNC_CLOSING);
+ wake_up_interruptible(&ch->port.close_wait);
}
}
struct tty_struct *tty;
struct board_chan __iomem *bc;
- if (!(ch->asyncflags & ASYNC_INITIALIZED))
+ if (!(ch->port.flags & ASYNC_INITIALIZED))
return;
spin_lock_irqsave(&epca_lock, flags);
*/
if (bc)
writeb(0, &bc->idata);
- tty = ch->tty;
+ tty = ch->port.tty;
/* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
if (tty->termios->c_cflag & HUPCL) {
* will have to reinitialized. Set a flag to indicate this.
*/
/* Prevent future Digi programmed interrupts from coming active */
- ch->asyncflags &= ~ASYNC_INITIALIZED;
+ ch->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&epca_lock, flags);
}
static void pc_hangup(struct tty_struct *tty)
{
struct channel *ch;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ pc_flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(ch);
spin_lock_irqsave(&epca_lock, flags);
- ch->tty = NULL;
+ ch->port.tty = NULL;
ch->event = 0;
- ch->count = 0;
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
+ ch->port.count = 0;
+ ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
spin_unlock_irqrestore(&epca_lock, flags);
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
}
static int pc_write(struct tty_struct *tty,
- const unsigned char *buf, int bytesAvailable)
+ const unsigned char *buf, int bytesAvailable)
{
unsigned int head, tail;
int dataLen;
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return 0;
/* Make a pointer to the channel data structure found on the board. */
return amountCopied;
}
-static void pc_put_char(struct tty_struct *tty, unsigned char c)
-{
- pc_write(tty, &c, 1);
-}
-
static int pc_write_room(struct tty_struct *tty)
{
- int remain;
+ int remain = 0;
struct channel *ch;
unsigned long flags;
unsigned int head, tail;
struct board_chan __iomem *bc;
-
- remain = 0;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
tail = readw(&bc->tout);
/* Wrap tail if necessary */
tail &= (ch->txbufsize - 1);
-
- if ((remain = tail - head - 1) < 0 )
+ remain = tail - head - 1;
+ if (remain < 0)
remain += ch->txbufsize;
if (remain && (ch->statusflags & LOWWAIT) == 0) {
unsigned long flags;
struct channel *ch;
struct board_chan __iomem *bc;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return 0;
spin_lock_irqsave(&epca_lock, flags);
head = readw(&bc->tin);
ctail = readw(&ch->mailbox->cout);
- if (tail == head && readw(&ch->mailbox->cin) == ctail && readb(&bc->tbusy) == 0)
+ if (tail == head && readw(&ch->mailbox->cin) == ctail &&
+ readb(&bc->tbusy) == 0)
chars = 0;
else { /* Begin if some space on the card has been used */
head = readw(&bc->tin) & (ch->txbufsize - 1);
* pc_write_room here we are finding the amount of bytes in the
* buffer filled. Not the amount of bytes empty.
*/
- if ((remain = tail - head - 1) < 0 )
+ remain = tail - head - 1;
+ if (remain < 0)
remain += ch->txbufsize;
chars = (int)(ch->txbufsize - remain);
/*
* transmit buffer empties.
*/
if (!(ch->statusflags & EMPTYWAIT))
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
} /* End if some space on the card has been used */
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return;
spin_lock_irqsave(&epca_lock, flags);
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
/*
* If not already set and the transmitter is busy setup an
* event to indicate when the transmit empties.
*/
- if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))
- setup_empty_event(tty,ch);
+ if ((ch->statusflags & TXBUSY) &&
+ !(ch->statusflags & EMPTYWAIT))
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
}
}
static int block_til_ready(struct tty_struct *tty,
- struct file *filp, struct channel *ch)
+ struct file *filp, struct channel *ch)
{
- DECLARE_WAITQUEUE(wait,current);
+ DECLARE_WAITQUEUE(wait, current);
int retval, do_clocal = 0;
unsigned long flags;
if (tty_hung_up_p(filp)) {
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
* If the device is in the middle of being closed, then block until
* it's done, and then try again.
*/
- if (ch->asyncflags & ASYNC_CLOSING) {
- interruptible_sleep_on(&ch->close_wait);
+ if (ch->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&ch->port.close_wait);
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
* If non-blocking mode is set, then make the check up front
* and then exit.
*/
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
if (tty->termios->c_cflag & CLOCAL)
/* Block waiting for the carrier detect and the line to become free */
retval = 0;
- add_wait_queue(&ch->open_wait, &wait);
+ add_wait_queue(&ch->port.open_wait, &wait);
spin_lock_irqsave(&epca_lock, flags);
/* We dec count so that pc_close will know when to free things */
if (!tty_hung_up_p(filp))
- ch->count--;
- ch->blocked_open++;
+ ch->port.count--;
+ ch->port.blocked_open++;
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED))
- {
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ !(ch->port.flags & ASYNC_INITIALIZED)) {
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(ch->asyncflags & ASYNC_CLOSING) &&
+ if (!(ch->port.flags & ASYNC_CLOSING) &&
(do_clocal || (ch->imodem & ch->dcd)))
break;
if (signal_pending(current)) {
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&ch->open_wait, &wait);
+ remove_wait_queue(&ch->port.open_wait, &wait);
if (!tty_hung_up_p(filp))
- ch->count++;
- ch->blocked_open--;
+ ch->port.count++;
+ ch->port.blocked_open--;
spin_unlock_irqrestore(&epca_lock, flags);
if (retval)
return retval;
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
-static int pc_open(struct tty_struct *tty, struct file * filp)
+static int pc_open(struct tty_struct *tty, struct file *filp)
{
struct channel *ch;
unsigned long flags;
return(-ENODEV);
}
- if ((bc = ch->brdchan) == 0) {
+ bc = ch->brdchan;
+ if (bc == NULL) {
tty->driver_data = NULL;
return -ENODEV;
}
* necessary because we do not wish to flush and shutdown the channel
* until the last app holding the channel open, closes it.
*/
- ch->count++;
+ ch->port.count++;
/*
* Set a kernel structures pointer to our local channel structure. This
* way we can get to it when passed only a tty struct.
writew(head, &bc->rout);
/* Set the channels associated tty structure */
- ch->tty = tty;
+ ch->port.tty = tty;
/*
* The below routine generally sets up parity, baud, flow control
* issues, etc.... It effect both control flags and input flags.
*/
- epcaparam(tty,ch);
- ch->asyncflags |= ASYNC_INITIALIZED;
+ epcaparam(tty, ch);
+ ch->port.flags |= ASYNC_INITIALIZED;
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
* waiting for the line...
*/
spin_lock_irqsave(&epca_lock, flags);
- ch->tty = tty;
+ ch->port.tty = tty;
globalwinon(ch);
/* Enable Digi Data events */
writeb(1, &bc->idata);
del_timer_sync(&epca_timer);
- if (tty_unregister_driver(pc_driver) || tty_unregister_driver(pc_info))
- {
+ if (tty_unregister_driver(pc_driver) ||
+ tty_unregister_driver(pc_info)) {
printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n");
return;
}
}
ch = card_ptr[crd];
for (count = 0; count < bd->numports; count++, ch++) {
- if (ch && ch->tty)
- tty_hangup(ch->tty);
+ if (ch && ch->port.tty)
+ tty_hangup(ch->port.tty);
}
}
pci_unregister_driver(&epca_driver);
.flush_buffer = pc_flush_buffer,
.chars_in_buffer = pc_chars_in_buffer,
.flush_chars = pc_flush_chars,
- .put_char = pc_put_char,
.ioctl = pc_ioctl,
.set_termios = pc_set_termios,
.stop = pc_stop,
.hangup = pc_hangup,
};
-static int info_open(struct tty_struct *tty, struct file * filp)
+static int info_open(struct tty_struct *tty, struct file *filp)
{
return 0;
}
* Set up interrupt, we will worry about memory allocation in
* post_fep_init.
*/
- printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION);
+ printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION);
/*
* NOTE : This code assumes that the number of ports found in the
if ((board_id & 0x30) == 0x30)
bd->memory_seg = 0x8000;
} else
- printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);
+ printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port);
break;
}
}
*/
/* PCI cards are already remapped at this point ISA are not */
bd->numports = readw(bd->re_map_membase + XEMPORTS);
- epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");
+ epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports");
nbdevs += (bd->numports);
} else {
/* Fix up the mappings for ISA/EISA etc */
/* FIXME: 64K - can we be smarter ? */
- bd->re_map_membase = ioremap(bd->membase, 0x10000);
+ bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000);
}
if (crd != 0)
* XEPORTS (address 0xc22) points at the number of channels the card
* supports. (For 64XE, XI, XEM, and XR use 0xc02)
*/
- if ((bd->type == PCXEVE || bd->type == PCXE) && (readw(memaddr + XEPORTS) < 3))
+ if ((bd->type == PCXEVE || bd->type == PCXE) &&
+ (readw(memaddr + XEPORTS) < 3))
shrinkmem = 1;
if (bd->type < PCIXEM)
if (!request_region((int)bd->port, 4, board_desc[bd->type]))
ch->boardnum = crd;
ch->channelnum = i;
ch->magic = EPCA_MAGIC;
- ch->tty = NULL;
+ ch->port.tty = NULL;
if (shrinkmem) {
fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
case PCXEVE:
case PCXE:
- ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4)
+ & 0x1fff);
ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
- ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
- ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
+ ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4)
+ & 0x1fff);
+ ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9);
break;
case PCXI:
ch->fepstopca = 0;
ch->close_delay = 50;
- ch->count = 0;
- ch->blocked_open = 0;
- init_waitqueue_head(&ch->open_wait);
- init_waitqueue_head(&ch->close_wait);
+ ch->port.count = 0;
+ ch->port.blocked_open = 0;
+ init_waitqueue_head(&ch->port.open_wait);
+ init_waitqueue_head(&ch->port.close_wait);
spin_unlock_irqrestore(&epca_lock, flags);
}
printk(KERN_INFO
- "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
- VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);
+ "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
+ VERSION, board_desc[bd->type], (long)bd->port,
+ (long)bd->membase, bd->numports);
memwinoff(bd, 0);
}
{
unsigned long flags;
int crd;
- volatile unsigned int head, tail;
+ unsigned int head, tail;
struct channel *ch;
struct board_info *bd;
chan0 = card_ptr[crd];
epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
assertgwinon(chan0);
- while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) { /* Begin while something in event queue */
+ while ((tail = readw(&chan0->mailbox->eout)) !=
+ (head = readw(&chan0->mailbox->ein))) {
+ /* Begin while something in event queue */
assertgwinon(chan0);
eventbuf = bd->re_map_membase + tail + ISTART;
/* Get the channel the event occurred on */
goto next;
}
- if ((bc = ch->brdchan) == NULL)
+ bc = ch->brdchan;
+ if (bc == NULL)
goto next;
if (event & DATA_IND) { /* Begin DATA_IND */
if (event & MODEMCHG_IND) {
/* A modem signal change has been indicated */
ch->imodem = mstat;
- if (ch->asyncflags & ASYNC_CHECK_CD) {
- if (mstat & ch->dcd) /* We are now receiving dcd */
- wake_up_interruptible(&ch->open_wait);
- else
- pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */
+ if (ch->port.flags & ASYNC_CHECK_CD) {
+ /* We are now receiving dcd */
+ if (mstat & ch->dcd)
+ wake_up_interruptible(&ch->port.open_wait);
+ else /* No dcd; hangup */
+ pc_sched_event(ch, EPCA_EVENT_HANGUP);
}
}
- tty = ch->tty;
+ tty = ch->port.tty;
if (tty) {
if (event & BREAK_IND) {
/* A break has been indicated */
tty_wakeup(tty);
}
} else if (event & EMPTYTX_IND) {
- /* This event is generated by setup_empty_event */
+ /* This event is generated by
+ setup_empty_event */
ch->statusflags &= ~TXBUSY;
if (ch->statusflags & EMPTYWAIT) {
ch->statusflags &= ~EMPTYWAIT;
}
}
}
- next:
+next:
globalwinon(ch);
BUG_ON(!bc);
writew(1, &bc->idata);
}
static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
- int byte2, int ncmds, int bytecmd)
+ int byte2, int ncmds, int bytecmd)
{
unchar __iomem *memaddr;
unsigned int head, cmdTail, cmdStart, cmdMax;
memaddr = ch->board->re_map_membase;
if (head >= (cmdMax - cmdStart) || (head & 03)) {
- printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", __LINE__, cmd, head);
- printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", __LINE__, cmdMax, cmdStart);
+ printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n",
+ __LINE__, cmd, head);
+ printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n",
+ __LINE__, cmdMax, cmdStart);
return;
}
if (bytecmd) {
static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
{
unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
- INPCK | ISTRIP|IXON|IXANY|IXOFF);
+ INPCK | ISTRIP | IXON | IXANY | IXOFF);
if (ch->digiext.digi_flags & DIGI_AIXON)
res |= IAIXON;
return res;
unsigned mval, hflow, cflag, iflag;
bc = ch->brdchan;
- epcaassert(bc !=0, "bc out of range");
+ epcaassert(bc != NULL, "bc out of range");
assertgwinon(ch);
ts = tty->termios;
* that the driver will wait on carrier detect.
*/
if (ts->c_cflag & CLOCAL)
- ch->asyncflags &= ~ASYNC_CHECK_CD;
+ ch->port.flags &= ~ASYNC_CHECK_CD;
else
- ch->asyncflags |= ASYNC_CHECK_CD;
+ ch->port.flags |= ASYNC_CHECK_CD;
mval = ch->m_dtr | ch->m_rts;
} /* End CBAUD not detected */
iflag = termios2digi_i(ch, ts->c_iflag);
* Command sets channels iflag structure on the board. Such
* things as input soft flow control, handling of parity
* errors, and break handling are all set here.
+ *
+ * break handling, parity handling, input stripping,
+ * flow control chars
*/
- /* break handling, parity handling, input stripping, flow control chars */
fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
}
/*
globalwinon(ch);
if (ch->statusflags & RXSTOPPED)
return;
- tty = ch->tty;
+ tty = ch->port.tty;
if (tty)
ts = tty->termios;
bc = ch->brdchan;
return;
/* If CREAD bit is off or device not open, set TX tail to head */
- if (!tty || !ts || !(ts->c_cflag & CREAD)) {
+ if (!tty || !ts || !(ts->c_cflag & CREAD)) {
writew(head, &bc->rout);
return;
}
if (readb(&bc->orun)) {
writeb(0, &bc->orun);
- printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name);
+ printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",
+ tty->name);
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
rxwinon(ch);
- while (bytesAvailable > 0) { /* Begin while there is data on the card */
+ while (bytesAvailable > 0) {
+ /* Begin while there is data on the card */
wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
/*
* Even if head has wrapped around only report the amount of
* data to be equal to the size - tail. Remember memcpy can't
* automaticly wrap around the receive buffer.
*/
- dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable;
+ dataToRead = (wrapgap < bytesAvailable) ? wrapgap
+ : bytesAvailable;
/* Make sure we don't overflow the buffer */
dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
if (dataToRead == 0)
globalwinon(ch);
writew(tail, &bc->rout);
/* Must be called with global data */
- tty_schedule_flip(ch->tty);
+ tty_schedule_flip(ch->port.tty);
}
static int info_ioctl(struct tty_struct *tty, struct file *file,
* The below routine generally sets up parity, baud, flow control
* issues, etc.... It effect both control flags and input flags.
*/
- epcaparam(tty,ch);
+ epcaparam(tty, ch);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
return 0;
}
-static int pc_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int pc_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
digiflow_t dflow;
int retval;
bc = ch->brdchan;
else
return -EINVAL;
-
/*
* For POSIX compliance we need to add more ioctls. See tty_ioctl.c in
* /usr/src/linux/drivers/char for a good example. In particular think
retval = tty_check_change(tty);
if (retval)
return retval;
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit
+ buffer empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
if (!arg)
retval = tty_check_change(tty);
if (retval)
return retval;
-
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit buffer
+ empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
return 0;
- case TIOCGSOFTCAR:
- if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))
- return -EFAULT;
- return 0;
- case TIOCSSOFTCAR:
- {
- unsigned int value;
-
- if (get_user(value, (unsigned __user *)argp))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (value ? CLOCAL : 0));
- return 0;
- }
case TIOCMODG:
mflag = pc_tiocmget(tty, file);
if (put_user(mflag, (unsigned long __user *)argp))
break;
case DIGI_SETAW:
case DIGI_SETAF:
+ lock_kernel();
if (cmd == DIGI_SETAW) {
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit
+ buffer empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
} else {
/* ldisc lock already held in ioctl */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ if (tty->ldisc.ops->flush_buffer)
+ tty->ldisc.ops->flush_buffer(tty);
}
+ unlock_kernel();
/* Fall Thru */
case DIGI_SETA:
if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
* control issues, etc.... It effect both control flags and
* input flags.
*/
- epcaparam(tty,ch);
+ epcaparam(tty, ch);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
break;
if (copy_from_user(&dflow, argp, sizeof(dflow)))
return -EFAULT;
- if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */
+ if (dflow.startc != startc || dflow.stopc != stopc) {
+ /* Begin if setflow toggled */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
if (cmd == DIGI_SETFLOW) {
ch->fepstartc = ch->startc = dflow.startc;
ch->fepstopc = ch->stopc = dflow.stopc;
- fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
+ fepcmd(ch, SONOFFC, ch->fepstartc,
+ ch->fepstopc, 0, 1);
} else {
ch->fepstartca = ch->startca = dflow.startc;
ch->fepstopca = ch->stopca = dflow.stopc;
- fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
+ fepcmd(ch, SAUXONOFFC, ch->fepstartca,
+ ch->fepstopca, 0, 1);
}
if (ch->statusflags & TXSTOPPED)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
+ ch = verifyChannel(tty);
+
+ if (ch != NULL) { /* Begin if channel valid */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
epcaparam(tty, ch);
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
} /* End if channel valid */
}
struct channel *ch = container_of(work, struct channel, tqueue);
/* Called in response to a modem change event */
if (ch && ch->magic == EPCA_MAGIC) {
- struct tty_struct *tty = ch->tty;
+ struct tty_struct *tty = ch->port.tty;
if (tty && tty->driver_data) {
if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
- tty_hangup(tty); /* FIXME: module removal race here - AKPM */
- wake_up_interruptible(&ch->open_wait);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
+ tty_hangup(tty);
+ wake_up_interruptible(&ch->port.open_wait);
+ ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
}
}
}
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
- if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */
+ if ((ch->statusflags & TXSTOPPED) == 0) {
+ /* Begin if transmit stop requested */
globalwinon(ch);
/* STOP transmitting now !! */
fepcmd(ch, PAUSETX, 0, 0, 0, 0);
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
- /* Just in case output was resumed because of a change in Digi-flow */
- if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */
+ /* Just in case output was resumed because of a change
+ in Digi-flow */
+ if (ch->statusflags & TXSTOPPED) {
+ /* Begin transmit resume requested */
struct board_chan __iomem *bc;
globalwinon(ch);
bc = ch->brdchan;
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if ((ch->statusflags & RXSTOPPED) == 0) {
globalwinon(ch);
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
- /* Just in case output was resumed because of a change in Digi-flow */
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
+ /* Just in case output was resumed because of a change
+ in Digi-flow */
spin_lock_irqsave(&epca_lock, flags);
if (ch->statusflags & RXSTOPPED) {
globalwinon(ch);
}
}
-void digi_send_break(struct channel *ch, int msec)
+static void digi_send_break(struct channel *ch, int msec)
{
unsigned long flags;
memoff(ch);
}
-void epca_setup(char *str, int *ints)
+static void epca_setup(char *str, int *ints)
{
struct board_info board;
int index, loop, last;
* instructing the driver to ignore epcaconfig.) For
* this reason we check for 2.
*/
- if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */
+ if (board.status == 2) {
+ /* Begin ignore epcaconfig as well as lilo cmd line */
nbdevs = 0;
num_cards = 0;
return;
} /* End ignore epcaconfig as well as lilo cmd line */
if (board.status > 2) {
- printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status);
+ printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n",
+ board.status);
invalid_lilo_config = 1;
setup_error_code |= INVALID_BOARD_STATUS;
return;
case 6:
board.membase = ints[index];
if (ints[index] <= 0) {
- printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
+ printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",
+ (unsigned int)board.membase);
invalid_lilo_config = 1;
setup_error_code |= INVALID_MEM_BASE;
return;
t2++;
if (*t2) {
- printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str);
+ printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str);
invalid_lilo_config = 1;
setup_error_code |= INVALID_MEM_BASE;
return;
/* I should REALLY validate the stuff here */
/* Copies our local copy of board into boards */
- memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board));
+ memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board));
/* Does this get called once per lilo arg are what ? */
printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
num_cards, board_desc[board.type],
if (board_idx >= MAXBOARDS)
goto err_out;
- addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx);
+ addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx);
if (!addr) {
- printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n",
+ printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n",
epca_info_tbl[info_idx].bar_idx);
goto err_out;
}
boards[board_idx].port = addr + PCI_IO_OFFSET;
boards[board_idx].membase = addr;
- if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) {
- printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
+ if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) {
+ printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out;
}
- boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000);
+ boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET,
+ 0x200000);
if (!boards[board_idx].re_map_port) {
- printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
+ printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out_free_pciio;
}
- if (!request_mem_region (addr, 0x200000, "epca")) {
- printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
+ if (!request_mem_region(addr, 0x200000, "epca")) {
+ printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
0x200000, addr);
goto err_out_free_iounmap;
}
- boards[board_idx].re_map_membase = ioremap(addr, 0x200000);
+ boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000);
if (!boards[board_idx].re_map_membase) {
- printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
+ printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out_free_memregion;
}
return 0;
err_out_free_memregion:
- release_mem_region (addr, 0x200000);
+ release_mem_region(addr, 0x200000);
err_out_free_iounmap:
- iounmap (boards[board_idx].re_map_port);
+ iounmap(boards[board_idx].re_map_port);
err_out_free_pciio:
- release_mem_region (addr + PCI_IO_OFFSET, 0x200000);
+ release_mem_region(addr + PCI_IO_OFFSET, 0x200000);
err_out:
return -ENODEV;
}
MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
-int __init init_PCI (void)
+static int __init init_PCI(void)
{
- memset (&epca_driver, 0, sizeof (epca_driver));
+ memset(&epca_driver, 0, sizeof(epca_driver));
epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl;
epca_driver.probe = epca_init_one;