staging: dgrp: remove driver

Remove the driver as it hasn't been cleaned up and it doesn't look like
anyone is going to work on it anymore. This can be reverted if someone
wants to work to fix the remaining issues the driver has.

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Cc: Bill Pemberton <wfp5p@worldbroken.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Kristina Martšenko 2014-07-01 02:14:02 +03:00 committed by Greg Kroah-Hartman
parent 929b2d483d
commit 19b1e7695b
18 changed files with 0 additions and 10404 deletions

View File

@ -114,8 +114,6 @@ source "drivers/staging/ced1401/Kconfig"
source "drivers/staging/imx-drm/Kconfig"
source "drivers/staging/dgrp/Kconfig"
source "drivers/staging/fwserial/Kconfig"
source "drivers/staging/goldfish/Kconfig"

View File

@ -50,7 +50,6 @@ obj-$(CONFIG_LTE_GDM724X) += gdm724x/
obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
obj-$(CONFIG_CED1401) += ced1401/
obj-$(CONFIG_DRM_IMX) += imx-drm/
obj-$(CONFIG_DGRP) += dgrp/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_LUSTRE_FS) += lustre/

View File

@ -1,9 +0,0 @@
config DGRP
tristate "Digi Realport driver"
default n
depends on SYSFS && TTY
---help---
Support for Digi Realport devices. These devices allow you to
access remote serial ports as if they are local tty devices. This
will build the kernel driver, you will still need the userspace
component to make your Realport device work.

View File

@ -1,12 +0,0 @@
obj-$(CONFIG_DGRP) += dgrp.o
dgrp-y := \
dgrp_common.o \
dgrp_dpa_ops.o \
dgrp_driver.o \
dgrp_mon_ops.o \
dgrp_net_ops.o \
dgrp_ports_ops.o \
dgrp_specproc.o \
dgrp_tty.o \
dgrp_sysfs.o

View File

@ -1,2 +0,0 @@
The user space code to work with this driver is located at
https://github.com/wfp5p/dgrp-utils

View File

@ -1,13 +0,0 @@
- Use configfs for config stuff. This will require changes to the
user space code.
- dgrp_send() and dgrp_receive() could use some refactoring
- Don't automatically create CHAN_MAX (64) channel array entries for
every device as many devices are going to have much less than 64
channels.
- The locking needs to be checked. It seems haphazardly done in most
places.
- Check Kconfig dependencies

View File

@ -1,169 +0,0 @@
/*
*
* Copyright 1999 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/*
*
* Filename:
*
* dgrp_common.c
*
* Description:
*
* Definitions of global variables and functions which are either
* shared by the tty, mon, and net drivers; or which cross them
* functionally (like the poller).
*
* Author:
*
* James A. Puzzo
*
*/
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/cred.h>
#include "dgrp_common.h"
/**
* dgrp_carrier -- check for carrier change state and act
* @ch: struct ch_struct *
*/
void dgrp_carrier(struct ch_struct *ch)
{
struct nd_struct *nd;
int virt_carrier = 0;
int phys_carrier = 0;
/* fix case when the tty has already closed. */
if (!ch)
return;
nd = ch->ch_nd;
if (!nd)
return;
/*
* If we are currently waiting to determine the status of the port,
* we don't yet know the state of the modem lines. As a result,
* we ignore state changes when we are waiting for the modem lines
* to be established. We know, as a result of code in dgrp_net_ops,
* that we will be called again immediately following the reception
* of the status message with the true modem status flags in it.
*/
if (ch->ch_expect & RR_STATUS)
return;
/*
* If CH_HANGUP is set, we gotta keep trying to get all the processes
* that have the port open to close the port.
* So lets just keep sending a hangup every time we get here.
*/
if ((ch->ch_flag & CH_HANGUP) &&
(ch->ch_tun.un_open_count > 0))
tty_hangup(ch->ch_tun.un_tty);
/*
* Compute the effective state of both the physical and virtual
* senses of carrier.
*/
if (ch->ch_s_mlast & DM_CD)
phys_carrier = 1;
if ((ch->ch_s_mlast & DM_CD) ||
(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
(ch->ch_flag & CH_CLOCAL))
virt_carrier = 1;
/*
* Test for a VIRTUAL carrier transition to HIGH.
*
* The CH_HANGUP condition is intended to prevent any action
* except for close. As a result, we ignore positive carrier
* transitions during CH_HANGUP.
*/
if (((ch->ch_flag & CH_HANGUP) == 0) &&
((ch->ch_flag & CH_VIRT_CD) == 0) &&
(virt_carrier == 1)) {
/*
* When carrier rises, wake any threads waiting
* for carrier in the open routine.
*/
nd->nd_tx_work = 1;
if (waitqueue_active(&ch->ch_flag_wait))
wake_up_interruptible(&ch->ch_flag_wait);
}
/*
* Test for a PHYSICAL transition to low, so long as we aren't
* currently ignoring physical transitions (which is what "virtual
* carrier" indicates).
*
* The transition of the virtual carrier to low really doesn't
* matter... it really only means "ignore carrier state", not
* "make pretend that carrier is there".
*/
if ((virt_carrier == 0) &&
((ch->ch_flag & CH_PHYS_CD) != 0) &&
(phys_carrier == 0)) {
/*
* When carrier drops:
*
* Do a Hard Hangup if that is called for.
*
* Drop carrier on all open units.
*
* Flush queues, waking up any task waiting in the
* line discipline.
*
* Send a hangup to the control terminal.
*
* Enable all select calls.
*/
nd->nd_tx_work = 1;
ch->ch_flag &= ~(CH_LOW | CH_EMPTY | CH_DRAIN | CH_INPUT);
if (waitqueue_active(&ch->ch_flag_wait))
wake_up_interruptible(&ch->ch_flag_wait);
if (ch->ch_tun.un_open_count > 0)
tty_hangup(ch->ch_tun.un_tty);
if (ch->ch_pun.un_open_count > 0)
tty_hangup(ch->ch_pun.un_tty);
}
/*
* Make sure that our cached values reflect the current reality.
*/
if (virt_carrier == 1)
ch->ch_flag |= CH_VIRT_CD;
else
ch->ch_flag &= ~CH_VIRT_CD;
if (phys_carrier == 1)
ch->ch_flag |= CH_PHYS_CD;
else
ch->ch_flag &= ~CH_PHYS_CD;
}

View File

@ -1,150 +0,0 @@
/*
*
* Copyright 1999 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
#ifndef __DGRP_COMMON_H
#define __DGRP_COMMON_H
#define DIGI_VERSION "1.9-29"
#include <linux/fs.h>
#include <linux/timer.h>
#include "drp.h"
#define DGRP_TTIME 100
#define DGRP_RTIME 100
/************************************************************************
* All global storage allocation.
************************************************************************/
extern int dgrp_register_cudevices; /* enable legacy cu devices */
extern int dgrp_register_prdevices; /* enable transparent print devices */
extern int dgrp_poll_tick; /* Poll interval - in ms */
extern struct list_head nd_struct_list;
struct dgrp_poll_data {
spinlock_t poll_lock;
struct timer_list timer;
int poll_tick;
ulong poll_round; /* Timer rouding factor */
long node_active_count;
};
extern struct dgrp_poll_data dgrp_poll_data;
extern void dgrp_poll_handler(unsigned long arg);
/* from dgrp_mon_ops.c */
extern const struct file_operations dgrp_mon_ops;
/* from dgrp_tty.c */
extern int dgrp_tty_init(struct nd_struct *nd);
extern void dgrp_tty_uninit(struct nd_struct *nd);
/* from dgrp_ports_ops.c */
extern const struct file_operations dgrp_ports_ops;
/* from dgrp_net_ops.c */
extern const struct file_operations dgrp_net_ops;
/* from dgrp_dpa_ops.c */
extern const struct file_operations dgrp_dpa_ops;
extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int);
/* from dgrp_sysfs.c */
extern int dgrp_create_class_sysfs_files(void);
extern void dgrp_remove_class_sysfs_files(void);
extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd);
extern void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd);
extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c);
extern void dgrp_remove_tty_sysfs(struct device *c);
/* from dgrp_specproc.c */
extern void dgrp_unregister_proc(void);
extern void dgrp_register_proc(void);
/*-----------------------------------------------------------------------*
*
* Declarations for common operations:
*
* (either used by more than one of net, mon, or tty,
* or in interrupt context (i.e. the poller))
*
*-----------------------------------------------------------------------*/
void dgrp_carrier(struct ch_struct *ch);
/*
* ID manipulation macros (where c1 & c2 are characters, i is
* a long integer, and s is a character array of at least three members
*/
static inline void ID_TO_CHAR(long i, char *s)
{
s[0] = ((i & 0xff00)>>8);
s[1] = (i & 0xff);
s[2] = 0;
}
static inline long CHAR_TO_ID(char *s)
{
return ((s[0] & 0xff) << 8) | (s[1] & 0xff);
}
static inline struct nd_struct *nd_struct_get(long major)
{
struct nd_struct *nd;
list_for_each_entry(nd, &nd_struct_list, list) {
if (major == nd->nd_major)
return nd;
}
return NULL;
}
static inline int nd_struct_add(struct nd_struct *entry)
{
struct nd_struct *ptr;
ptr = nd_struct_get(entry->nd_major);
if (ptr)
return -EBUSY;
list_add_tail(&entry->list, &nd_struct_list);
return 0;
}
static inline int nd_struct_del(struct nd_struct *entry)
{
struct nd_struct *nd;
nd = nd_struct_get(entry->nd_major);
if (!nd)
return -ENODEV;
list_del(&nd->list);
return 0;
}
#endif /* __DGRP_COMMON_H */

View File

@ -1,534 +0,0 @@
/*
*
* Copyright 1999 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/*
*
* Filename:
*
* dgrp_dpa_ops.c
*
* Description:
*
* Handle the file operations required for the "dpa" devices.
* Includes those functions required to register the "dpa" devices
* in "/proc".
*
* Author:
*
* James A. Puzzo
*
*/
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/tty.h>
#include <linux/poll.h>
#include <linux/cred.h>
#include <linux/sched.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include "dgrp_common.h"
/* File operation declarations */
static int dgrp_dpa_open(struct inode *, struct file *);
static int dgrp_dpa_release(struct inode *, struct file *);
static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *);
static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);
const struct file_operations dgrp_dpa_ops = {
.owner = THIS_MODULE,
.read = dgrp_dpa_read,
.poll = dgrp_dpa_select,
.unlocked_ioctl = dgrp_dpa_ioctl,
.open = dgrp_dpa_open,
.release = dgrp_dpa_release,
};
struct digi_node {
uint nd_state; /* Node state: 1 = up, 0 = down. */
uint nd_chan_count; /* Number of channels found */
uint nd_tx_byte; /* Tx data count */
uint nd_rx_byte; /* RX data count */
u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
};
#define DIGI_GETNODE (('d'<<8) | 249) /* get board info */
struct digi_chan {
uint ch_port; /* Port number to get info on */
uint ch_open; /* 1 if open, 0 if not */
uint ch_txcount; /* TX data count */
uint ch_rxcount; /* RX data count */
uint ch_s_brate; /* Realport BRATE */
uint ch_s_estat; /* Realport ELAST */
uint ch_s_cflag; /* Realport CFLAG */
uint ch_s_iflag; /* Realport IFLAG */
uint ch_s_oflag; /* Realport OFLAG */
uint ch_s_xflag; /* Realport XFLAG */
uint ch_s_mstat; /* Realport MLAST */
};
#define DIGI_GETCHAN (('d'<<8) | 248) /* get channel info */
struct digi_vpd {
int vpd_len;
char vpd_data[VPDSIZE];
};
#define DIGI_GETVPD (('d'<<8) | 246) /* get VPD info */
struct digi_debug {
int onoff;
int port;
};
#define DIGI_SETDEBUG (('d'<<8) | 247) /* set debug info */
/*
* dgrp_dpa_open -- open the DPA device for a particular PortServer
*/
static int dgrp_dpa_open(struct inode *inode, struct file *file)
{
struct nd_struct *nd;
int rtn = 0;
rtn = try_module_get(THIS_MODULE);
if (!rtn)
return -ENXIO;
rtn = 0;
if (!capable(CAP_SYS_ADMIN)) {
rtn = -EPERM;
goto done;
}
/*
* Make sure that the "private_data" field hasn't already been used.
*/
if (file->private_data) {
rtn = -EINVAL;
goto done;
}
/*
* Get the node pointer, and fail if it doesn't exist.
*/
nd = PDE_DATA(inode);
if (!nd) {
rtn = -ENXIO;
goto done;
}
file->private_data = (void *) nd;
/*
* Allocate the DPA buffer.
*/
if (nd->nd_dpa_buf) {
rtn = -EBUSY;
} else {
nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL);
if (!nd->nd_dpa_buf) {
rtn = -ENOMEM;
} else {
nd->nd_dpa_out = 0;
nd->nd_dpa_in = 0;
nd->nd_dpa_lbolt = jiffies;
}
}
done:
if (rtn)
module_put(THIS_MODULE);
return rtn;
}
/*
* dgrp_dpa_release -- close the DPA device for a particular PortServer
*/
static int dgrp_dpa_release(struct inode *inode, struct file *file)
{
struct nd_struct *nd;
u8 *buf;
unsigned long lock_flags;
/*
* Get the node pointer, and quit if it doesn't exist.
*/
nd = (struct nd_struct *)(file->private_data);
if (!nd)
goto done;
/*
* Free the dpa buffer.
*/
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
buf = nd->nd_dpa_buf;
nd->nd_dpa_buf = NULL;
nd->nd_dpa_out = nd->nd_dpa_in;
/*
* Wakeup any thread waiting for buffer space.
*/
if (nd->nd_dpa_flag & DPA_WAIT_SPACE) {
nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
wake_up_interruptible(&nd->nd_dpa_wqueue);
}
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
kfree(buf);
done:
module_put(THIS_MODULE);
file->private_data = NULL;
return 0;
}
/*
* dgrp_dpa_read
*
* Copy data from the monitoring buffer to the user, freeing space
* in the monitoring buffer for more messages
*/
static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
struct nd_struct *nd;
int n;
int r;
int offset = 0;
int res = 0;
ssize_t rtn;
unsigned long lock_flags;
/*
* Get the node pointer, and quit if it doesn't exist.
*/
nd = (struct nd_struct *)(file->private_data);
if (!nd)
return -ENXIO;
/*
* Wait for some data to appear in the buffer.
*/
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
for (;;) {
n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
if (n != 0)
break;
nd->nd_dpa_flag |= DPA_WAIT_DATA;
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
/*
* Go to sleep waiting until the condition becomes true.
*/
rtn = wait_event_interruptible(nd->nd_dpa_wqueue,
((nd->nd_dpa_flag & DPA_WAIT_DATA) == 0));
if (rtn)
return rtn;
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
}
/*
* Read whatever is there.
*/
if (n > count)
n = count;
res = n;
r = DPA_MAX - nd->nd_dpa_out;
if (r <= n) {
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
rtn = copy_to_user((void __user *)buf,
nd->nd_dpa_buf + nd->nd_dpa_out, r);
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
if (rtn) {
rtn = -EFAULT;
goto done;
}
nd->nd_dpa_out = 0;
n -= r;
offset = r;
}
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
rtn = copy_to_user((void __user *)buf + offset,
nd->nd_dpa_buf + nd->nd_dpa_out, n);
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
if (rtn) {
rtn = -EFAULT;
goto done;
}
nd->nd_dpa_out += n;
*ppos += res;
rtn = res;
/*
* Wakeup any thread waiting for buffer space.
*/
n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
if (nd->nd_dpa_flag & DPA_WAIT_SPACE &&
(DPA_MAX - n) > DPA_HIGH_WATER) {
nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
wake_up_interruptible(&nd->nd_dpa_wqueue);
}
done:
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
return rtn;
}
static unsigned int dgrp_dpa_select(struct file *file,
struct poll_table_struct *table)
{
unsigned int retval = 0;
struct nd_struct *nd = file->private_data;
if (nd->nd_dpa_out != nd->nd_dpa_in)
retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
retval |= POLLOUT | POLLWRNORM; /* Always writeable */
return retval;
}
static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct nd_struct *nd;
struct digi_chan getchan;
struct digi_node getnode;
struct ch_struct *ch;
struct digi_debug setdebug;
struct digi_vpd vpd;
unsigned int port;
void __user *uarg = (void __user *) arg;
nd = file->private_data;
switch (cmd) {
case DIGI_GETCHAN:
if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan)))
return -EFAULT;
port = getchan.ch_port;
if (port > nd->nd_chan_count)
return -EINVAL;
ch = nd->nd_chan + port;
getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0;
getchan.ch_txcount = ch->ch_txcount;
getchan.ch_rxcount = ch->ch_rxcount;
getchan.ch_s_brate = ch->ch_s_brate;
getchan.ch_s_estat = ch->ch_s_elast;
getchan.ch_s_cflag = ch->ch_s_cflag;
getchan.ch_s_iflag = ch->ch_s_iflag;
getchan.ch_s_oflag = ch->ch_s_oflag;
getchan.ch_s_xflag = ch->ch_s_xflag;
getchan.ch_s_mstat = ch->ch_s_mlast;
if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan)))
return -EFAULT;
break;
case DIGI_GETNODE:
getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0;
getnode.nd_chan_count = nd->nd_chan_count;
getnode.nd_tx_byte = nd->nd_tx_byte;
getnode.nd_rx_byte = nd->nd_rx_byte;
memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
strlcpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
return -EFAULT;
break;
case DIGI_SETDEBUG:
if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug)))
return -EFAULT;
nd->nd_dpa_debug = setdebug.onoff;
nd->nd_dpa_port = setdebug.port;
break;
case DIGI_GETVPD:
memset(&vpd, 0, sizeof(vpd));
if (nd->nd_vpd_len > 0) {
vpd.vpd_len = nd->nd_vpd_len;
memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len);
} else {
vpd.vpd_len = 0;
}
if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd)))
return -EFAULT;
break;
}
return 0;
}
/**
* dgrp_dpa() -- send data to the device monitor queue
* @nd: pointer to a node structure
* @buf: buffer of data to copy to the monitoring buffer
* @len: number of bytes to transfer to the buffer
*
* Called by the net device routines to send data to the device
* monitor queue. If the device monitor buffer is too full to
* accept the data, it waits until the buffer is ready.
*/
static void dgrp_dpa(struct nd_struct *nd, u8 *buf, int nbuf)
{
int n;
int r;
unsigned long lock_flags;
/*
* Grab DPA lock.
*/
spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
/*
* Loop while data remains.
*/
while (nbuf > 0 && nd->nd_dpa_buf != NULL) {
n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK;
/*
* Enforce flow control on the DPA device.
*/
if (n < (DPA_MAX - DPA_HIGH_WATER))
nd->nd_dpa_flag |= DPA_WAIT_SPACE;
/*
* This should never happen, as the flow control above
* should have stopped things before they got to this point.
*/
if (n == 0) {
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
return;
}
/*
* Copy as much data as will fit.
*/
if (n > nbuf)
n = nbuf;
r = DPA_MAX - nd->nd_dpa_in;
if (r <= n) {
memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, r);
n -= r;
nd->nd_dpa_in = 0;
buf += r;
nbuf -= r;
}
memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n);
nd->nd_dpa_in += n;
buf += n;
nbuf -= n;
if (nd->nd_dpa_in >= DPA_MAX)
pr_info_ratelimited("%s - nd->nd_dpa_in (%i) >= DPA_MAX\n",
__func__, nd->nd_dpa_in);
/*
* Wakeup any thread waiting for data
*/
if (nd->nd_dpa_flag & DPA_WAIT_DATA) {
nd->nd_dpa_flag &= ~DPA_WAIT_DATA;
wake_up_interruptible(&nd->nd_dpa_wqueue);
}
}
/*
* Release the DPA lock.
*/
spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
}
/**
* dgrp_monitor_data() -- builds a DPA data packet
* @nd: pointer to a node structure
* @type: type of message to be logged in the DPA buffer
* @buf: buffer of data to be logged in the DPA buffer
* @size -- number of bytes in the "buf" buffer
*/
void dgrp_dpa_data(struct nd_struct *nd, int type, u8 *buf, int size)
{
u8 header[5];
header[0] = type;
put_unaligned_be32(size, header + 1);
dgrp_dpa(nd, header, sizeof(header));
dgrp_dpa(nd, buf, size);
}

View File

@ -1,105 +0,0 @@
/*
*
* Copyright 1999-2003 Digi International (www.digi.com)
* Jeff Randall
* James Puzzo <jamesp at digi dot com>
* Scott Kilau <Scott_Kilau at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/*
* Driver specific includes
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/tty.h>
/*
* PortServer includes
*/
#include "dgrp_common.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Digi International, http://www.digi.com");
MODULE_DESCRIPTION("RealPort driver for Digi's ethernet-based serial connectivity product line");
MODULE_VERSION(DIGI_VERSION);
struct list_head nd_struct_list;
struct dgrp_poll_data dgrp_poll_data;
int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
int dgrp_poll_tick = 20; /* Poll interval - in ms */
module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
module_param_named(register_prdevices, dgrp_register_prdevices, int, 0644);
MODULE_PARM_DESC(register_prdevices, "Turn on/off registering transparent print devices");
module_param_named(pollrate, dgrp_poll_tick, int, 0644);
MODULE_PARM_DESC(pollrate, "Poll interval in ms");
/*
* init_module()
*
* Module load. This is where it all starts.
*/
static int __init dgrp_init_module(void)
{
int ret;
INIT_LIST_HEAD(&nd_struct_list);
spin_lock_init(&dgrp_poll_data.poll_lock);
init_timer(&dgrp_poll_data.timer);
dgrp_poll_data.poll_tick = dgrp_poll_tick;
dgrp_poll_data.timer.function = dgrp_poll_handler;
dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data;
ret = dgrp_create_class_sysfs_files();
if (ret)
return ret;
dgrp_register_proc();
return 0;
}
/*
* Module unload. This is where it all ends.
*/
static void __exit dgrp_cleanup_module(void)
{
struct nd_struct *nd, *next;
/*
* Attempting to free resources in backwards
* order of allocation, in case that helps
* memory pool fragmentation.
*/
dgrp_unregister_proc();
dgrp_remove_class_sysfs_files();
list_for_each_entry_safe(nd, next, &nd_struct_list, list) {
dgrp_tty_uninit(nd);
kfree(nd);
}
}
module_init(dgrp_init_module);
module_exit(dgrp_cleanup_module);

View File

@ -1,327 +0,0 @@
/*****************************************************************************
*
* Copyright 1999 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/*
*
* Filename:
*
* dgrp_mon_ops.c
*
* Description:
*
* Handle the file operations required for the "monitor" devices.
* Includes those functions required to register the "mon" devices
* in "/proc".
*
* Author:
*
* James A. Puzzo
*
*/
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <asm/unaligned.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include "dgrp_common.h"
/* File operation declarations */
static int dgrp_mon_open(struct inode *, struct file *);
static int dgrp_mon_release(struct inode *, struct file *);
static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *);
static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
const struct file_operations dgrp_mon_ops = {
.owner = THIS_MODULE,
.read = dgrp_mon_read,
.unlocked_ioctl = dgrp_mon_ioctl,
.open = dgrp_mon_open,
.release = dgrp_mon_release,
};
/**
* dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer
* @inode: struct inode *
* @file: struct file *
*
* Open function to open the /proc/dgrp/ports device for a PortServer.
*/
static int dgrp_mon_open(struct inode *inode, struct file *file)
{
struct nd_struct *nd;
struct timeval tv;
uint32_t time;
u8 *buf;
int rtn;
rtn = try_module_get(THIS_MODULE);
if (!rtn)
return -ENXIO;
rtn = 0;
if (!capable(CAP_SYS_ADMIN)) {
rtn = -EPERM;
goto done;
}
/*
* Make sure that the "private_data" field hasn't already been used.
*/
if (file->private_data) {
rtn = -EINVAL;
goto done;
}
/*
* Get the node pointer, and fail if it doesn't exist.
*/
nd = PDE_DATA(inode);
if (!nd) {
rtn = -ENXIO;
goto done;
}
file->private_data = (void *) nd;
/*
* Allocate the monitor buffer.
*/
/*
* Grab the MON lock.
*/
down(&nd->nd_mon_semaphore);
if (nd->nd_mon_buf) {
rtn = -EBUSY;
goto done_up;
}
nd->nd_mon_buf = kmalloc(MON_MAX, GFP_KERNEL);
if (!nd->nd_mon_buf) {
rtn = -ENOMEM;
goto done_up;
}
/*
* Enter an RPDUMP file header into the buffer.
*/
buf = nd->nd_mon_buf;
strcpy(buf, RPDUMP_MAGIC);
buf += strlen(buf) + 1;
do_gettimeofday(&tv);
/*
* tv.tv_sec might be a 64 bit quantity. Pare
* it down to 32 bits before attempting to encode
* it.
*/
time = (uint32_t) (tv.tv_sec & 0xffffffff);
put_unaligned_be32(time, buf);
put_unaligned_be16(0, buf + 4);
buf += 6;
if (nd->nd_tx_module) {
buf[0] = RPDUMP_CLIENT;
put_unaligned_be32(0, buf + 1);
put_unaligned_be16(1, buf + 5);
buf[7] = 0xf0 + nd->nd_tx_module;
buf += 8;
}
if (nd->nd_rx_module) {
buf[0] = RPDUMP_SERVER;
put_unaligned_be32(0, buf + 1);
put_unaligned_be16(1, buf + 5);
buf[7] = 0xf0 + nd->nd_rx_module;
buf += 8;
}
nd->nd_mon_out = 0;
nd->nd_mon_in = buf - nd->nd_mon_buf;
nd->nd_mon_lbolt = jiffies;
done_up:
up(&nd->nd_mon_semaphore);
done:
if (rtn)
module_put(THIS_MODULE);
return rtn;
}
/**
* dgrp_mon_release() - Close the MON device for a particular PortServer
* @inode: struct inode *
* @file: struct file *
*/
static int dgrp_mon_release(struct inode *inode, struct file *file)
{
struct nd_struct *nd;
/*
* Get the node pointer, and quit if it doesn't exist.
*/
nd = (struct nd_struct *)(file->private_data);
if (!nd)
goto done;
/*
* Free the monitor buffer.
*/
down(&nd->nd_mon_semaphore);
kfree(nd->nd_mon_buf);
nd->nd_mon_buf = NULL;
nd->nd_mon_out = nd->nd_mon_in;
/*
* Wakeup any thread waiting for buffer space.
*/
if (nd->nd_mon_flag & MON_WAIT_SPACE) {
nd->nd_mon_flag &= ~MON_WAIT_SPACE;
wake_up_interruptible(&nd->nd_mon_wqueue);
}
up(&nd->nd_mon_semaphore);
/*
* Make sure there is no thread in the middle of writing a packet.
*/
down(&nd->nd_net_semaphore);
up(&nd->nd_net_semaphore);
done:
module_put(THIS_MODULE);
file->private_data = NULL;
return 0;
}
/**
* dgrp_mon_read() -- Copy data from the monitoring buffer to the user
*/
static ssize_t dgrp_mon_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
struct nd_struct *nd;
int r;
int offset = 0;
int res = 0;
ssize_t rtn;
/*
* Get the node pointer, and quit if it doesn't exist.
*/
nd = (struct nd_struct *)(file->private_data);
if (!nd)
return -ENXIO;
/*
* Wait for some data to appear in the buffer.
*/
down(&nd->nd_mon_semaphore);
for (;;) {
res = (nd->nd_mon_in - nd->nd_mon_out) & MON_MASK;
if (res)
break;
nd->nd_mon_flag |= MON_WAIT_DATA;
up(&nd->nd_mon_semaphore);
/*
* Go to sleep waiting until the condition becomes true.
*/
rtn = wait_event_interruptible(nd->nd_mon_wqueue,
((nd->nd_mon_flag & MON_WAIT_DATA) == 0));
if (rtn)
return rtn;
down(&nd->nd_mon_semaphore);
}
/*
* Read whatever is there.
*/
if (res > count)
res = count;
r = MON_MAX - nd->nd_mon_out;
if (r <= res) {
rtn = copy_to_user((void __user *)buf,
nd->nd_mon_buf + nd->nd_mon_out, r);
if (rtn) {
up(&nd->nd_mon_semaphore);
return -EFAULT;
}
nd->nd_mon_out = 0;
res -= r;
offset = r;
}
rtn = copy_to_user((void __user *) buf + offset,
nd->nd_mon_buf + nd->nd_mon_out, res);
if (rtn) {
up(&nd->nd_mon_semaphore);
return -EFAULT;
}
nd->nd_mon_out += res;
*ppos += res;
up(&nd->nd_mon_semaphore);
/*
* Wakeup any thread waiting for buffer space.
*/
if (nd->nd_mon_flag & MON_WAIT_SPACE) {
nd->nd_mon_flag &= ~MON_WAIT_SPACE;
wake_up_interruptible(&nd->nd_mon_wqueue);
}
return res;
}
/* ioctl is not valid on monitor device */
static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
return -EINVAL;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +0,0 @@
/*
*
* Copyright 1999-2000 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
*
* Filename:
*
* dgrp_ports_ops.c
*
* Description:
*
* Handle the file operations required for the /proc/dgrp/ports/...
* devices. Basically gathers tty status for the node and returns it.
*
* Author:
*
* James A. Puzzo
*
*/
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include "dgrp_common.h"
/* File operation declarations */
static int dgrp_ports_open(struct inode *, struct file *);
const struct file_operations dgrp_ports_ops = {
.owner = THIS_MODULE,
.open = dgrp_ports_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
{
if (*pos == 0)
seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT IFLAG OFLAG CFLAG BPS DIGIFLAGS\n");
return pos;
}
static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct nd_struct *nd = seq->private;
if (*pos >= nd->nd_chan_count)
return NULL;
*pos += 1;
return pos;
}
static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
{
}
static int dgrp_ports_seq_show(struct seq_file *seq, void *v)
{
loff_t *pos = v;
struct nd_struct *nd;
struct ch_struct *ch;
struct un_struct *tun, *pun;
unsigned int totcnt;
nd = seq->private;
if (!nd)
return 0;
if (*pos >= nd->nd_chan_count)
return 0;
ch = &nd->nd_chan[*pos];
tun = &ch->ch_tun;
pun = &ch->ch_pun;
/*
* If port is not open and no one is waiting to
* open it, the modem signal values can't be
* trusted, and will be zeroed.
*/
totcnt = tun->un_open_count +
pun->un_open_count +
ch->ch_wait_count[0] +
ch->ch_wait_count[1] +
ch->ch_wait_count[2];
seq_printf(seq, "%02d %02d %02d %02d 0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n",
(int) *pos,
tun->un_open_count,
pun->un_open_count,
ch->ch_wait_count[0] +
ch->ch_wait_count[1] +
ch->ch_wait_count[2],
(totcnt ? ch->ch_s_mlast : 0),
ch->ch_s_iflag,
ch->ch_s_oflag,
ch->ch_s_cflag,
(ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0),
ch->ch_digi.digi_flags);
return 0;
}
static const struct seq_operations ports_seq_ops = {
.start = dgrp_ports_seq_start,
.next = dgrp_ports_seq_next,
.stop = dgrp_ports_seq_stop,
.show = dgrp_ports_seq_show,
};
/**
* dgrp_ports_open -- open the /proc/dgrp/ports/... device
* @inode: struct inode *
* @file: struct file *
*
* Open function to open the /proc/dgrp/ports device for a PortServer.
* This is the open function for struct file_operations
*/
static int dgrp_ports_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rtn;
rtn = seq_open(file, &ports_seq_ops);
if (!rtn) {
seq = file->private_data;
seq->private = PDE_DATA(inode);
}
return rtn;
}

View File

@ -1,541 +0,0 @@
/*
*
* Copyright 1999 Digi International (www.digi.com)
* James Puzzo <jamesp at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/*
*
* Filename:
*
* dgrp_specproc.c
*
* Description:
*
* Handle the "config" proc entry for the linux realport device driver
* and provide slots for the "net" and "mon" devices
*
* Author:
*
* James A. Puzzo
*
*/
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/cred.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include "dgrp_common.h"
static struct proc_dir_entry *dgrp_proc_dir_entry;
static int dgrp_add_id(long id);
static int dgrp_remove_nd(struct nd_struct *nd);
static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
struct proc_dir_entry *root,
const struct file_operations *fops);
/* File operation declarations */
static int parse_write_config(char *);
static ssize_t dgrp_config_proc_write(struct file *file,
const char __user *buffer,
size_t count, loff_t *pos);
static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file);
static int dgrp_info_proc_open(struct inode *inode, struct file *file);
static int dgrp_config_proc_open(struct inode *inode, struct file *file);
static const struct file_operations config_proc_file_ops = {
.owner = THIS_MODULE,
.open = dgrp_config_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.write = dgrp_config_proc_write,
};
static const struct file_operations info_proc_file_ops = {
.owner = THIS_MODULE,
.open = dgrp_info_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations nodeinfo_proc_file_ops = {
.owner = THIS_MODULE,
.open = dgrp_nodeinfo_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct proc_dir_entry *net_entry_pointer;
static struct proc_dir_entry *mon_entry_pointer;
static struct proc_dir_entry *dpa_entry_pointer;
static struct proc_dir_entry *ports_entry_pointer;
static void remove_files(struct nd_struct *nd)
{
char buf[3];
ID_TO_CHAR(nd->nd_ID, buf);
dgrp_remove_node_class_sysfs_files(nd);
if (nd->nd_net_de)
remove_proc_entry(buf, net_entry_pointer);
if (nd->nd_mon_de)
remove_proc_entry(buf, mon_entry_pointer);
if (nd->nd_dpa_de)
remove_proc_entry(buf, dpa_entry_pointer);
if (nd->nd_ports_de)
remove_proc_entry(buf, ports_entry_pointer);
}
void dgrp_unregister_proc(void)
{
net_entry_pointer = NULL;
mon_entry_pointer = NULL;
dpa_entry_pointer = NULL;
ports_entry_pointer = NULL;
if (dgrp_proc_dir_entry) {
struct nd_struct *nd;
list_for_each_entry(nd, &nd_struct_list, list)
remove_files(nd);
remove_proc_entry("dgrp/config", NULL);
remove_proc_entry("dgrp/info", NULL);
remove_proc_entry("dgrp/nodeinfo", NULL);
remove_proc_entry("dgrp/net", NULL);
remove_proc_entry("dgrp/mon", NULL);
remove_proc_entry("dgrp/dpa", NULL);
remove_proc_entry("dgrp/ports", NULL);
remove_proc_entry("dgrp", NULL);
dgrp_proc_dir_entry = NULL;
}
}
void dgrp_register_proc(void)
{
/*
* Register /proc/dgrp
*/
dgrp_proc_dir_entry = proc_mkdir("dgrp", NULL);
if (!dgrp_proc_dir_entry)
return;
proc_create("dgrp/config", 0644, NULL, &config_proc_file_ops);
proc_create("dgrp/info", 0644, NULL, &info_proc_file_ops);
proc_create("dgrp/nodeinfo", 0644, NULL, &nodeinfo_proc_file_ops);
net_entry_pointer = proc_mkdir_mode("dgrp/net", 0500, NULL);
mon_entry_pointer = proc_mkdir_mode("dgrp/mon", 0500, NULL);
dpa_entry_pointer = proc_mkdir_mode("dgrp/dpa", 0500, NULL);
ports_entry_pointer = proc_mkdir_mode("dgrp/ports", 0500, NULL);
}
static void *dgrp_config_proc_start(struct seq_file *m, loff_t *pos)
{
return seq_list_start_head(&nd_struct_list, *pos);
}
static void *dgrp_config_proc_next(struct seq_file *p, void *v, loff_t *pos)
{
return seq_list_next(v, &nd_struct_list, pos);
}
static void dgrp_config_proc_stop(struct seq_file *m, void *v)
{
}
static int dgrp_config_proc_show(struct seq_file *m, void *v)
{
struct nd_struct *nd;
char tmp_id[4];
if (v == &nd_struct_list) {
seq_puts(m, "#-----------------------------------------------------------------------------\n");
seq_puts(m, "# Avail\n");
seq_puts(m, "# ID Major State Ports\n");
return 0;
}
nd = list_entry(v, struct nd_struct, list);
ID_TO_CHAR(nd->nd_ID, tmp_id);
seq_printf(m, " %-2.2s %-5ld %-10.10s %-5d\n",
tmp_id,
nd->nd_major,
ND_STATE_STR(nd->nd_state),
nd->nd_chan_count);
return 0;
}
static const struct seq_operations proc_config_ops = {
.start = dgrp_config_proc_start,
.next = dgrp_config_proc_next,
.stop = dgrp_config_proc_stop,
.show = dgrp_config_proc_show,
};
static int dgrp_config_proc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &proc_config_ops);
}
/*
* When writing configuration information, each "record" (i.e. each
* write) is treated as an independent request. See the "parse"
* description for more details.
*/
static ssize_t dgrp_config_proc_write(struct file *file,
const char __user *buffer,
size_t count, loff_t *pos)
{
ssize_t retval;
char *inbuf, *sp;
char *line, *ldelim;
if (count > 32768)
return -EINVAL;
inbuf = sp = vzalloc(count + 1);
if (!inbuf)
return -ENOMEM;
if (copy_from_user(inbuf, buffer, count)) {
retval = -EFAULT;
goto done;
}
inbuf[count] = 0;
ldelim = "\n";
line = strpbrk(sp, ldelim);
while (line) {
*line = 0;
retval = parse_write_config(sp);
if (retval)
goto done;
sp = line + 1;
line = strpbrk(sp, ldelim);
}
retval = count;
done:
vfree(inbuf);
return retval;
}
/*
* ------------------------------------------------------------------------
*
* The following are the functions to parse input
*
* ------------------------------------------------------------------------
*/
static inline char *skip_past_ws(const char *str)
{
while ((*str) && !isspace(*str))
++str;
return skip_spaces(str);
}
static int parse_id(char **c, char *cID)
{
int tmp = **c;
if (isalnum(tmp) || (tmp == '_'))
cID[0] = tmp;
else
return -EINVAL;
(*c)++; tmp = **c;
if (isalnum(tmp) || (tmp == '_')) {
cID[1] = tmp;
(*c)++;
} else
cID[1] = 0;
return 0;
}
static int parse_add_config(char *buf)
{
char *c = buf;
int retval;
char cID[2];
long ID;
c = skip_past_ws(c);
retval = parse_id(&c, cID);
if (retval < 0)
return retval;
ID = CHAR_TO_ID(cID);
c = skip_past_ws(c);
return dgrp_add_id(ID);
}
static int parse_del_config(char *buf)
{
char *c = buf;
int retval;
struct nd_struct *nd;
char cID[2];
long ID;
long major;
c = skip_past_ws(c);
retval = parse_id(&c, cID);
if (retval < 0)
return retval;
ID = CHAR_TO_ID(cID);
c = skip_past_ws(c);
retval = kstrtol(c, 10, &major);
if (retval)
return retval;
nd = nd_struct_get(major);
if (!nd)
return -EINVAL;
if ((nd->nd_major != major) || (nd->nd_ID != ID))
return -EINVAL;
return dgrp_remove_nd(nd);
}
static int parse_chg_config(char *buf)
{
return -EINVAL;
}
/*
* The passed character buffer represents a single configuration request.
* If the first character is a "+", it is parsed as a request to add a
* PortServer
* If the first character is a "-", it is parsed as a request to delete a
* PortServer
* If the first character is a "*", it is parsed as a request to change a
* PortServer
* Any other character (including whitespace) causes the record to be
* ignored.
*/
static int parse_write_config(char *buf)
{
int retval;
switch (buf[0]) {
case '+':
retval = parse_add_config(buf);
break;
case '-':
retval = parse_del_config(buf);
break;
case '*':
retval = parse_chg_config(buf);
break;
default:
retval = -EINVAL;
}
return retval;
}
static int dgrp_info_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "version: %s\n", DIGI_VERSION);
seq_puts(m, "register_with_sysfs: 1\n");
seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
dgrp_poll_tick, dgrp_poll_tick);
return 0;
}
static int dgrp_info_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, dgrp_info_proc_show, NULL);
}
static void *dgrp_nodeinfo_start(struct seq_file *m, loff_t *pos)
{
return seq_list_start_head(&nd_struct_list, *pos);
}
static void *dgrp_nodeinfo_next(struct seq_file *p, void *v, loff_t *pos)
{
return seq_list_next(v, &nd_struct_list, pos);
}
static void dgrp_nodeinfo_stop(struct seq_file *m, void *v)
{
}
static int dgrp_nodeinfo_show(struct seq_file *m, void *v)
{
struct nd_struct *nd;
char hwver[8];
char swver[8];
char tmp_id[4];
if (v == &nd_struct_list) {
seq_puts(m, "#-----------------------------------------------------------------------------\n");
seq_puts(m, "# HW HW SW\n");
seq_puts(m, "# ID State Version ID Version Description\n");
return 0;
}
nd = list_entry(v, struct nd_struct, list);
ID_TO_CHAR(nd->nd_ID, tmp_id);
if (nd->nd_state == NS_READY) {
sprintf(hwver, "%d.%d", (nd->nd_hw_ver >> 8) & 0xff,
nd->nd_hw_ver & 0xff);
sprintf(swver, "%d.%d", (nd->nd_sw_ver >> 8) & 0xff,
nd->nd_sw_ver & 0xff);
seq_printf(m, " %-2.2s %-10.10s %-7.7s %-3d %-7.7s %-35.35s\n",
tmp_id,
ND_STATE_STR(nd->nd_state),
hwver,
nd->nd_hw_id,
swver,
nd->nd_ps_desc);
} else {
seq_printf(m, " %-2.2s %-10.10s\n",
tmp_id,
ND_STATE_STR(nd->nd_state));
}
return 0;
}
static const struct seq_operations nodeinfo_ops = {
.start = dgrp_nodeinfo_start,
.next = dgrp_nodeinfo_next,
.stop = dgrp_nodeinfo_stop,
.show = dgrp_nodeinfo_show,
};
static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &nodeinfo_ops);
}
/**
* dgrp_add_id() -- creates new nd struct and adds it to list
* @id: id of device to add
*/
static int dgrp_add_id(long id)
{
struct nd_struct *nd;
int ret;
int i;
nd = kzalloc(sizeof(struct nd_struct), GFP_KERNEL);
if (!nd)
return -ENOMEM;
nd->nd_major = 0;
nd->nd_ID = id;
spin_lock_init(&nd->nd_lock);
init_waitqueue_head(&nd->nd_tx_waitq);
init_waitqueue_head(&nd->nd_mon_wqueue);
init_waitqueue_head(&nd->nd_dpa_wqueue);
sema_init(&nd->nd_mon_semaphore, 1);
sema_init(&nd->nd_net_semaphore, 1);
spin_lock_init(&nd->nd_dpa_lock);
nd->nd_state = NS_CLOSED;
for (i = 0; i < SEQ_MAX; i++)
init_waitqueue_head(&nd->nd_seq_wque[i]);
/* setup the structures to get the major number */
ret = dgrp_tty_init(nd);
if (ret)
goto error_out;
nd->nd_major = nd->nd_serial_ttdriver->major;
ret = nd_struct_add(nd);
if (ret)
goto error_out;
dgrp_create_node_class_sysfs_files(nd);
nd->nd_net_de = add_proc_file(nd, net_entry_pointer, &dgrp_net_ops);
nd->nd_mon_de = add_proc_file(nd, mon_entry_pointer, &dgrp_mon_ops);
nd->nd_dpa_de = add_proc_file(nd, dpa_entry_pointer, &dgrp_dpa_ops);
nd->nd_ports_de = add_proc_file(nd, ports_entry_pointer,
&dgrp_ports_ops);
return 0;
/* FIXME this guy should free the tty driver stored in nd and destroy
* all channel ports */
error_out:
kfree(nd);
return ret;
}
static int dgrp_remove_nd(struct nd_struct *nd)
{
int ret;
/* Check to see if the selected structure is in use */
if (nd->nd_tty_ref_cnt)
return -EBUSY;
remove_files(nd);
dgrp_tty_uninit(nd);
ret = nd_struct_del(nd);
if (ret)
return ret;
kfree(nd);
return 0;
}
static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
struct proc_dir_entry *root,
const struct file_operations *fops)
{
char buf[3];
ID_TO_CHAR(node->nd_ID, buf);
return proc_create_data(buf, 0600, root, fops, node);
}

View File

@ -1,558 +0,0 @@
/*
* Copyright 2004 Digi International (www.digi.com)
* Scott H Kilau <Scott_Kilau at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
#include "dgrp_common.h"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/serial_reg.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#define PORTSERVER_DIVIDEND 1843200
#define SERIAL_TYPE_NORMAL 1
#define SERIAL_TYPE_CALLOUT 2
#define SERIAL_TYPE_XPRINT 3
static struct class *dgrp_class;
static struct device *dgrp_class_nodes_dev;
static struct device *dgrp_class_global_settings_dev;
static ssize_t dgrp_class_version_show(struct class *class,
struct class_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
}
static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "1\n");
}
static DEVICE_ATTR(register_with_sysfs, 0400,
dgrp_class_register_with_sysfs_show, NULL);
static ssize_t dgrp_class_pollrate_show(struct device *c,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
}
static ssize_t dgrp_class_pollrate_store(struct device *c,
struct device_attribute *attr,
const char *buf, size_t count)
{
if (sscanf(buf, "0x%x\n", &dgrp_poll_tick) != 1)
return -EINVAL;
return count;
}
static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
dgrp_class_pollrate_store);
static struct attribute *dgrp_sysfs_global_settings_entries[] = {
&dev_attr_pollrate.attr,
&dev_attr_register_with_sysfs.attr,
NULL
};
static struct attribute_group dgrp_global_settings_attribute_group = {
.name = NULL,
.attrs = dgrp_sysfs_global_settings_entries,
};
int dgrp_create_class_sysfs_files(void)
{
int ret = 0;
int max_majors = 1U << (32 - MINORBITS);
dgrp_class = class_create(THIS_MODULE, "digi_realport");
if (IS_ERR(dgrp_class))
return PTR_ERR(dgrp_class);
ret = class_create_file(dgrp_class, &class_attr_driver_version);
if (ret)
goto err_class;
dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
MKDEV(0, max_majors + 1), NULL, "driver_settings");
if (IS_ERR(dgrp_class_global_settings_dev)) {
ret = PTR_ERR(dgrp_class_global_settings_dev);
goto err_file;
}
ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
&dgrp_global_settings_attribute_group);
if (ret) {
pr_alert("%s: failed to create sysfs global settings device attributes.\n",
__func__);
goto err_dev1;
}
dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
MKDEV(0, max_majors + 2), NULL, "nodes");
if (IS_ERR(dgrp_class_nodes_dev)) {
ret = PTR_ERR(dgrp_class_nodes_dev);
goto err_group;
}
return 0;
err_group:
sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
&dgrp_global_settings_attribute_group);
err_dev1:
device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
err_file:
class_remove_file(dgrp_class, &class_attr_driver_version);
err_class:
class_destroy(dgrp_class);
return ret;
}
void dgrp_remove_class_sysfs_files(void)
{
struct nd_struct *nd;
int max_majors = 1U << (32 - MINORBITS);
list_for_each_entry(nd, &nd_struct_list, list)
dgrp_remove_node_class_sysfs_files(nd);
sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
&dgrp_global_settings_attribute_group);
class_remove_file(dgrp_class, &class_attr_driver_version);
device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
class_destroy(dgrp_class);
}
static ssize_t dgrp_node_state_show(struct device *c,
struct device_attribute *attr, char *buf)
{
struct nd_struct *nd;
if (!c)
return 0;
nd = dev_get_drvdata(c);
if (!nd)
return 0;
return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
}
static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
static ssize_t dgrp_node_description_show(struct device *c,
struct device_attribute *attr,
char *buf)
{
struct nd_struct *nd;
if (!c)
return 0;
nd = dev_get_drvdata(c);
if (!nd)
return 0;
if (nd->nd_state == NS_READY)
return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
return 0;
}
static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
static ssize_t dgrp_node_hw_version_show(struct device *c,
struct device_attribute *attr,
char *buf)
{
struct nd_struct *nd;
if (!c)
return 0;
nd = dev_get_drvdata(c);
if (!nd)
return 0;
if (nd->nd_state == NS_READY)
return snprintf(buf, PAGE_SIZE, "%d.%d\n",
(nd->nd_hw_ver >> 8) & 0xff,
nd->nd_hw_ver & 0xff);
return 0;
}
static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
static ssize_t dgrp_node_hw_id_show(struct device *c,
struct device_attribute *attr, char *buf)
{
struct nd_struct *nd;
if (!c)
return 0;
nd = dev_get_drvdata(c);
if (!nd)
return 0;
if (nd->nd_state == NS_READY)
return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
return 0;
}
static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
static ssize_t dgrp_node_sw_version_show(struct device *c,
struct device_attribute *attr,
char *buf)
{
struct nd_struct *nd;
if (!c)
return 0;
nd = dev_get_drvdata(c);
if (!nd)
return 0;
if (nd->nd_state == NS_READY)
return snprintf(buf, PAGE_SIZE, "%d.%d\n",
(nd->nd_sw_ver >> 8) & 0xff,
nd->nd_sw_ver & 0xff);
return 0;
}
static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
static struct attribute *dgrp_sysfs_node_entries[] = {
&dev_attr_state.attr,
&dev_attr_description_info.attr,
&dev_attr_hw_version_info.attr,
&dev_attr_hw_id_info.attr,
&dev_attr_sw_version_info.attr,
NULL
};
static struct attribute_group dgrp_node_attribute_group = {
.name = NULL,
.attrs = dgrp_sysfs_node_entries,
};
void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
{
int ret;
char name[10];
if (nd->nd_ID)
ID_TO_CHAR(nd->nd_ID, name);
else
sprintf(name, "node%ld", nd->nd_major);
nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
MKDEV(0, nd->nd_major), NULL, "%s", name);
ret = sysfs_create_group(&nd->nd_class_dev->kobj,
&dgrp_node_attribute_group);
if (ret) {
pr_alert("%s: failed to create sysfs node device attributes.\n",
__func__);
sysfs_remove_group(&nd->nd_class_dev->kobj,
&dgrp_node_attribute_group);
return;
}
dev_set_drvdata(nd->nd_class_dev, nd);
}
void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
{
if (nd->nd_class_dev) {
sysfs_remove_group(&nd->nd_class_dev->kobj,
&dgrp_node_attribute_group);
device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
nd->nd_class_dev = NULL;
}
}
static ssize_t dgrp_tty_state_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
return snprintf(buf, PAGE_SIZE, "%s\n",
un->un_open_count ? "Open" : "Closed");
}
static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
static ssize_t dgrp_tty_baud_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%d\n",
un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
}
static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
static ssize_t dgrp_tty_msignals_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
if (ch->ch_open_count) {
return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
(ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
(ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
(ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
(ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
(ch->ch_s_mlast & DM_CD) ? "DCD" : "",
(ch->ch_s_mlast & DM_RI) ? "RI" : "");
}
return 0;
}
static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
static ssize_t dgrp_tty_iflag_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
}
static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
static ssize_t dgrp_tty_cflag_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
}
static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
static ssize_t dgrp_tty_oflag_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
}
static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
static ssize_t dgrp_tty_digi_flag_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
}
static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
static ssize_t dgrp_tty_rxcount_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
}
static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
static ssize_t dgrp_tty_txcount_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ch_struct *ch;
struct un_struct *un;
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
}
static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
static ssize_t dgrp_tty_name_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct nd_struct *nd;
struct ch_struct *ch;
struct un_struct *un;
char name[10];
if (!d)
return 0;
un = dev_get_drvdata(d);
if (!un)
return 0;
ch = un->un_ch;
if (!ch)
return 0;
nd = ch->ch_nd;
if (!nd)
return 0;
ID_TO_CHAR(nd->nd_ID, name);
return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
name, ch->ch_portnum);
}
static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
static struct attribute *dgrp_sysfs_tty_entries[] = {
&dev_attr_state_info.attr,
&dev_attr_baud_info.attr,
&dev_attr_msignals_info.attr,
&dev_attr_iflag_info.attr,
&dev_attr_cflag_info.attr,
&dev_attr_oflag_info.attr,
&dev_attr_digi_flag_info.attr,
&dev_attr_rxcount_info.attr,
&dev_attr_txcount_info.attr,
&dev_attr_custom_name.attr,
NULL
};
static struct attribute_group dgrp_tty_attribute_group = {
.name = NULL,
.attrs = dgrp_sysfs_tty_entries,
};
void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
{
int ret;
ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
if (ret) {
pr_alert("%s: failed to create sysfs tty device attributes.\n",
__func__);
sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
return;
}
dev_set_drvdata(c, un);
}
void dgrp_remove_tty_sysfs(struct device *c)
{
sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,129 +0,0 @@
/************************************************************************
* HP-UX Realport Daemon interface file.
*
* Copyright (C) 1998, by Digi International. All Rights Reserved.
************************************************************************/
#ifndef _DIGIDRP_H
#define _DIGIDRP_H
/************************************************************************
* This file contains defines for the ioctl() interface to
* the realport driver. This ioctl() interface is used by the
* daemon to set speed setup parameters honored by the driver.
************************************************************************/
struct link_struct {
int lk_fast_rate; /* Fast line rate to be used
when the delay is less-equal
to lk_fast_delay */
int lk_fast_delay; /* Fast line rate delay in
milliseconds */
int lk_slow_rate; /* Slow line rate to be used when
the delay is greater-equal
to lk_slow_delay */
int lk_slow_delay; /* Slow line rate delay in
milliseconds */
int lk_header_size; /* Estimated packet header size
when sent across the slowest
link. */
};
#define DIGI_GETLINK _IOW('e', 103, struct link_struct) /* Get link parameters */
#define DIGI_SETLINK _IOW('e', 104, struct link_struct) /* Set link parameters */
/************************************************************************
* This module provides application access to special Digi
* serial line enhancements which are not standard UNIX(tm) features.
************************************************************************/
struct digiflow_struct {
unsigned char startc; /* flow cntl start char */
unsigned char stopc; /* flow cntl stop char */
};
/************************************************************************
* Values for digi_flags
************************************************************************/
#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
#define DIGI_FAST 0x0002 /* Fast baud rates */
#define RTSPACE 0x0004 /* RTS input flow control */
#define CTSPACE 0x0008 /* CTS output flow control */
#define DSRPACE 0x0010 /* DSR output flow control */
#define DCDPACE 0x0020 /* DCD output flow control */
#define DTRPACE 0x0040 /* DTR input flow control */
#define DIGI_COOK 0x0080 /* Cooked processing done in FEP */
#define DIGI_FORCEDCD 0x0100 /* Force carrier */
#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
#define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl */
#define DIGI_PP_INPUT 0x1000 /* Change parallel port to input */
#define DIGI_422 0x4000 /* Change parallel port to input */
#define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */
/************************************************************************
* Values associated with transparent print
************************************************************************/
#define DIGI_PLEN 8 /* String length */
#define DIGI_TSIZ 10 /* Terminal string len */
/************************************************************************
* Structure used with ioctl commands for DIGI parameters.
************************************************************************/
struct digi_struct {
unsigned short digi_flags; /* Flags (see above) */
unsigned short digi_maxcps; /* Max printer CPS */
unsigned short digi_maxchar; /* Max chars in print queue */
unsigned short digi_bufsize; /* Buffer size */
unsigned char digi_onlen; /* Length of ON string */
unsigned char digi_offlen; /* Length of OFF string */
char digi_onstr[DIGI_PLEN]; /* Printer on string */
char digi_offstr[DIGI_PLEN]; /* Printer off string */
char digi_term[DIGI_TSIZ]; /* terminal string */
};
/************************************************************************
* Ioctl command arguments for DIGI parameters.
************************************************************************/
/* Read params */
#define DIGI_GETA _IOR('e', 94, struct digi_struct)
/* Set params */
#define DIGI_SETA _IOW('e', 95, struct digi_struct)
/* Drain & set params */
#define DIGI_SETAW _IOW('e', 96, struct digi_struct)
/* Drain, flush & set params */
#define DIGI_SETAF _IOW('e', 97, struct digi_struct)
/* Get startc/stopc flow control characters */
#define DIGI_GETFLOW _IOR('e', 99, struct digiflow_struct)
/* Set startc/stopc flow control characters */
#define DIGI_SETFLOW _IOW('e', 100, struct digiflow_struct)
/* Get Aux. startc/stopc flow control chars */
#define DIGI_GETAFLOW _IOR('e', 101, struct digiflow_struct)
/* Set Aux. startc/stopc flow control chars */
#define DIGI_SETAFLOW _IOW('e', 102, struct digiflow_struct)
/* Set integer baud rate */
#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int)
/* Get integer baud rate */
#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int)
#define DIGI_GEDELAY _IOR('d', 246, int) /* Get edelay */
#define DIGI_SEDELAY _IOW('d', 247, int) /* Get edelay */
#endif /* _DIGIDRP_H */

View File

@ -1,693 +0,0 @@
/*
*
* Copyright 1999 Digi International (www.digi.com)
* Gene Olson <gene at digi dot com>
* James Puzzo <jamesp at digi dot com>
* Scott Kilau <scottk at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
*/
/************************************************************************
* Master include file for Linux Realport Driver.
************************************************************************/
#ifndef __DRP_H
#define __DRP_H
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/semaphore.h>
#include <linux/tty.h>
#include "digirp.h"
/************************************************************************
* Tuning parameters.
************************************************************************/
#define CHAN_MAX 64 /* Max # ports per server */
#define SEQ_MAX 128 /* Max # transmit sequences (2^n) */
#define SEQ_MASK (SEQ_MAX-1) /* Sequence buffer modulus mask */
#define TBUF_MAX 4096 /* Size of transmit buffer (2^n) */
#define RBUF_MAX 4096 /* Size of receive buffer (2^n) */
#define TBUF_MASK (TBUF_MAX-1) /* Transmit buffer modulus mask */
#define RBUF_MASK (RBUF_MAX-1) /* Receive buffer modulus mask */
#define TBUF_LOW 1000 /* Transmit low water mark */
#define UIO_BASE 1000 /* Base for write operations */
#define UIO_MIN 2000 /* Minimum size application buffer */
#define UIO_MAX 8100 /* Unix I/O buffer size */
#define MON_MAX 65536 /* Monitor buffer size (2^n) */
#define MON_MASK (MON_MAX-1) /* Monitor wrap mask */
#define DPA_MAX 65536 /* DPA buffer size (2^n) */
#define DPA_MASK (DPA_MAX-1) /* DPA wrap mask */
#define DPA_HIGH_WATER 58000 /* Enforce flow control when
* over this amount
*/
#define IDLE_MAX (20 * HZ) /* Max TCP link idle time */
#define MAX_DESC_LEN 100 /* Maximum length of stored PS
* description
*/
#define WRITEBUFLEN ((4096) + 4) /* 4 extra for alignment play space */
#define VPDSIZE 512
/************************************************************************
* Minor device decoding conventions.
************************************************************************
*
* For Linux, the net and mon devices are handled via "proc", so we
* only have to mux the "tty" devices. Since every PortServer will
* have an individual major number, the PortServer number does not
* need to be encoded, and in fact, does not need to exist.
*
*/
/*
* Port device decoding conventions:
*
* Device 00 - 3f 64 dial-in modem devices. (tty)
* Device 40 - 7f 64 dial-out tty devices. (cu)
* Device 80 - bf 64 dial-out printer devices.
*
* IS_PRINT(dev) This is a printer device.
*
* OPEN_CATEGORY(dev) Specifies the device category. No two
* devices of different categories may be open
* at the same time.
*
* The following require the category returned by OPEN_CATEGORY().
*
* OPEN_WAIT_AVAIL(cat) Waits on open until the device becomes
* available. Fails if NDELAY specified.
*
* OPEN_WAIT_CARRIER(cat) Waits on open if carrier is not present.
* Succeeds if NDELAY is given.
*
* OPEN_FORCES_CARRIER(cat) Carrier is forced high on open.
*
*/
#define PORT_NUM(dev) ((dev) & 0x3f)
#define OPEN_CATEGORY(dev) ((((dev) & 0x80) & 0x40))
#define IS_PRINT(dev) (((dev) & 0xff) >= 0x80)
#define OPEN_WAIT_AVAIL(cat) (((cat) & 0x40) == 0x000)
#define OPEN_WAIT_CARRIER(cat) (((cat) & 0x40) == 0x000)
#define OPEN_FORCES_CARRIER(cat) (((cat) & 0x40) != 0x000)
/************************************************************************
* Modem signal defines for 16450/16550 compatible FEP.
* set in ch_mout, ch_mflow, ch_mlast etc
************************************************************************/
/* TODO : Re-verify that these modem signal definitions are correct */
#define DM_DTR 0x01
#define DM_RTS 0x02
#define DM_RTS_TOGGLE 0x04
#define DM_OUT1 0x04
#define DM_OUT2 0x08
#define DM_CTS 0x10
#define DM_DSR 0x20
#define DM_RI 0x40
#define DM_CD 0x80 /* This is the DCD flag */
/************************************************************************
* Realport Event Flags.
************************************************************************/
#define EV_OPU 0x0001 /* Ouput paused by client */
#define EV_OPS 0x0002 /* Output paused by XOFF */
#define EV_OPX 0x0004 /* Output paused by XXOFF */
#define EV_OPH 0x0008 /* Output paused by MFLOW */
#define EV_IPU 0x0010 /* Input paused by client */
#define EV_IPS 0x0020 /* Input paused by hi/low water */
#define EV_TXB 0x0040 /* Transmit break pending */
#define EV_TXI 0x0080 /* Transmit immediate pending */
#define EV_TXF 0x0100 /* Transmit flow control pending */
#define EV_RXB 0x0200 /* Break received */
/************************************************************************
* Realport CFLAGS.
************************************************************************/
#define CF_CS5 0x0000 /* 5 bit characters */
#define CF_CS6 0x0010 /* 6 bit characters */
#define CF_CS7 0x0020 /* 7 bit characters */
#define CF_CS8 0x0030 /* 8 bit characters */
#define CF_CSIZE 0x0030 /* Character size */
#define CF_CSTOPB 0x0040 /* Two stop bits */
#define CF_CREAD 0x0080 /* Enable receiver */
#define CF_PARENB 0x0100 /* Enable parity */
#define CF_PARODD 0x0200 /* Odd parity */
#define CF_HUPCL 0x0400 /* Drop DTR on close */
/************************************************************************
* Realport XFLAGS.
************************************************************************/
#define XF_XPAR 0x0001 /* Enable Mark/Space Parity */
#define XF_XMODEM 0x0002 /* Enable in-band modem signalling */
#define XF_XCASE 0x0004 /* Convert special characters */
#define XF_XEDATA 0x0008 /* Error data in stream */
#define XF_XTOSS 0x0010 /* Toss IXANY characters */
#define XF_XIXON 0x0020 /* xxon/xxoff enable */
/************************************************************************
* Realport IFLAGS.
************************************************************************/
#define IF_IGNBRK 0x0001 /* Ignore input break */
#define IF_BRKINT 0x0002 /* Break interrupt */
#define IF_IGNPAR 0x0004 /* Ignore error characters */
#define IF_PARMRK 0x0008 /* Error chars marked with 0xff */
#define IF_INPCK 0x0010 /* Input parity checking enabled */
#define IF_ISTRIP 0x0020 /* Input chars masked with 0x7F */
#define IF_IXON 0x0400 /* Output software flow control */
#define IF_IXANY 0x0800 /* Restart output on any char */
#define IF_IXOFF 0x1000 /* Input software flow control */
#define IF_DOSMODE 0x8000 /* 16450-compatible errors */
/************************************************************************
* Realport OFLAGS.
************************************************************************/
#define OF_OLCUC 0x0002 /* Map lower to upper case */
#define OF_ONLCR 0x0004 /* Map NL to CR-NL */
#define OF_OCRNL 0x0008 /* Map CR to NL */
#define OF_ONOCR 0x0010 /* No CR output at column 0 */
#define OF_ONLRET 0x0020 /* Assume NL does NL/CR */
#define OF_TAB3 0x1800 /* Tabs expand to 8 spaces */
#define OF_TABDLY 0x1800 /* Tab delay */
/************************************************************************
* Unit flag definitions for un_flag.
************************************************************************/
/* These are the DIGI unit flags */
#define UN_EXCL 0x00010000 /* Exclusive open */
#define UN_STICKY 0x00020000 /* TTY Settings are now sticky */
#define UN_BUSY 0x00040000 /* Some work this channel */
#define UN_PWAIT 0x00080000 /* Printer waiting for terminal */
#define UN_TIME 0x00100000 /* Waiting on time */
#define UN_EMPTY 0x00200000 /* Waiting output queue empty */
#define UN_LOW 0x00400000 /* Waiting output low water */
#define UN_DIGI_MASK 0x00FF0000 /* Waiting output low water */
/*
* Definitions for async_struct (and serial_struct) flags field
*
* these are the ASYNC flags copied from serial.h
*
*/
#define UN_HUP_NOTIFY 0x0001 /* Notify getty on hangups and
* closes on the callout port
*/
#define UN_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
#define UN_SAK 0x0004 /* Secure Attention Key (Orange book) */
#define UN_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
#define UN_SPD_MASK 0x0030
#define UN_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
#define UN_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
#define UN_SPD_CUST 0x0030 /* Use user-specified divisor */
#define UN_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
#define UN_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
#define UN_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
#define UN_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
#define UN_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
#define UN_FLAGS 0x0FFF /* Possible legal async flags */
#define UN_USR_MASK 0x0430 /* Legal flags that non-privileged
* users can set or reset
*/
#define UN_INITIALIZED 0x80000000 /* Serial port was initialized */
#define UN_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
#define UN_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
#define UN_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
#define UN_CLOSING 0x08000000 /* Serial port is closing */
#define UN_CTS_FLOW 0x04000000 /* Do CTS flow control */
#define UN_CHECK_CD 0x02000000 /* i.e., CLOCAL */
#define UN_SHARE_IRQ 0x01000000 /* for multifunction cards */
/************************************************************************
* Structure for terminal or printer unit. struct un_struct
*
* Note that in some places the code assumes the "tty_t" is placed
* first in the structure.
************************************************************************/
struct un_struct {
struct tty_struct *un_tty; /* System TTY struct */
struct ch_struct *un_ch; /* Associated channel */
ushort un_open_count; /* Successful open count */
int un_flag; /* Unit flags */
ushort un_tbusy; /* Busy transmit count */
wait_queue_head_t un_open_wait;
wait_queue_head_t un_close_wait;
ushort un_type;
struct device *un_sysfs;
};
/************************************************************************
* Channel State Numbers for ch_state.
************************************************************************/
/*
* The ordering is important.
*
* state <= CS_WAIT_CANCEL implies the channel is definitely closed.
*
* state >= CS_WAIT_FAIL implies the channel is definitely open.
*
* state >= CS_READY implies data is allowed on the channel.
*/
enum dgrp_ch_state_t {
CS_IDLE = 0, /* Channel is idle */
CS_WAIT_OPEN = 1, /* Waiting for Immediate Open Resp */
CS_WAIT_CANCEL = 2, /* Waiting for Per/Incom Cancel Resp */
CS_WAIT_FAIL = 3, /* Waiting for Immed Open Failure */
CS_SEND_QUERY = 4, /* Ready to send Port Query */
CS_WAIT_QUERY = 5, /* Waiting for Port Query Response */
CS_READY = 6, /* Ready to accept commands and data */
CS_SEND_CLOSE = 7, /* Ready to send Close Request */
CS_WAIT_CLOSE = 8 /* Waiting for Close Response */
};
/************************************************************************
* Device flag definitions for ch_flag.
************************************************************************/
/*
* Note that the state of the two carrier based flags is key. When
* we check for carrier state transitions, we look at the current
* physical state of the DCD line and compare it with PHYS_CD (which
* was the state the last time we checked), and we also determine
* a new virtual state (composite of the physical state, FORCEDCD,
* CLOCAL, etc.) and compare it with VIRT_CD.
*
* VIRTUAL transitions high will have the side effect of waking blocked
* opens.
*
* PHYSICAL transitions low will cause hangups to occur _IF_ the virtual
* state is also low. We DON'T want to hangup on a PURE virtual drop.
*/
#define CH_HANGUP 0x00002 /* Server port ready to close */
#define CH_VIRT_CD 0x00004 /* Carrier was virtually present */
#define CH_PHYS_CD 0x00008 /* Carrier was physically present */
#define CH_CLOCAL 0x00010 /* CLOCAL set in cflags */
#define CH_BAUD0 0x00020 /* Baud rate zero hangup */
#define CH_FAST_READ 0x00040 /* Fast reads are enabled */
#define CH_FAST_WRITE 0x00080 /* Fast writes are enabled */
#define CH_PRON 0x00100 /* Printer on string active */
#define CH_RX_FLUSH 0x00200 /* Flushing receive data */
#define CH_LOW 0x00400 /* Thread waiting for LOW water */
#define CH_EMPTY 0x00800 /* Thread waiting for EMPTY */
#define CH_DRAIN 0x01000 /* Close is waiting to drain */
#define CH_INPUT 0x02000 /* Thread waiting for INPUT */
#define CH_RXSTOP 0x04000 /* Stop output to ldisc */
#define CH_PARAM 0x08000 /* A parameter was updated */
#define CH_WAITING_SYNC 0x10000 /* A pending sync was assigned
* to this port.
*/
#define CH_PORT_GONE 0x20000 /* Port has disappeared */
#define CH_TX_BREAK 0x40000 /* TX Break to be sent,
* but has not yet.
*/
/************************************************************************
* Types of Open Requests for ch_otype.
************************************************************************/
#define OTYPE_IMMEDIATE 0 /* Immediate Open */
#define OTYPE_PERSISTENT 1 /* Persistent Open */
#define OTYPE_INCOMING 2 /* Incoming Open */
/************************************************************************
* Request/Response flags.
************************************************************************/
#define RR_SEQUENCE 0x0001 /* Get server RLAST, TIN */
#define RR_STATUS 0x0002 /* Get server MINT, EINT */
#define RR_BUFFER 0x0004 /* Get server RSIZE, TSIZE */
#define RR_CAPABILITY 0x0008 /* Get server port capabilities */
#define RR_TX_FLUSH 0x0040 /* Flush output buffers */
#define RR_RX_FLUSH 0x0080 /* Flush input buffers */
#define RR_TX_STOP 0x0100 /* Pause output */
#define RR_RX_STOP 0x0200 /* Pause input */
#define RR_TX_START 0x0400 /* Start output */
#define RR_RX_START 0x0800 /* Start input */
#define RR_TX_BREAK 0x1000 /* Send BREAK */
#define RR_TX_ICHAR 0x2000 /* Send character immediate */
/************************************************************************
* Channel information structure. struct ch_struct
************************************************************************/
struct ch_struct {
struct digi_struct ch_digi; /* Digi variables */
int ch_edelay; /* Digi edelay */
struct tty_port port;
struct un_struct ch_tun; /* Terminal unit info */
struct un_struct ch_pun; /* Printer unit info */
struct nd_struct *ch_nd; /* Node pointer */
u8 *ch_tbuf; /* Local Transmit Buffer */
u8 *ch_rbuf; /* Local Receive Buffer */
ulong ch_cpstime; /* Printer CPS time */
ulong ch_waketime; /* Printer wake time */
ulong ch_flag; /* CH_* flags */
enum dgrp_ch_state_t ch_state; /* CS_* Protocol state */
ushort ch_send; /* Bit vector of RR_* requests */
ushort ch_expect; /* Bit vector of RR_* responses */
ushort ch_wait_carrier; /* Thread count waiting for carrier */
ushort ch_wait_count[3]; /* Thread count waiting by otype */
ushort ch_portnum; /* Port number */
ushort ch_open_count; /* Successful open count */
ushort ch_category; /* Device category */
ushort ch_open_error; /* Last open error number */
ushort ch_break_time; /* Pending break request time */
ushort ch_cpsrem; /* Printer CPS remainder */
ushort ch_ocook; /* Realport fastcook oflags */
ushort ch_inwait; /* Thread count in CLIST input */
ushort ch_tin; /* Local transmit buffer in ptr */
ushort ch_tout; /* Local transmit buffer out ptr */
ushort ch_s_tin; /* Realport TIN */
ushort ch_s_tpos; /* Realport TPOS */
ushort ch_s_tsize; /* Realport TSIZE */
ushort ch_s_treq; /* Realport TREQ */
ushort ch_s_elast; /* Realport ELAST */
ushort ch_rin; /* Local receive buffer in ptr */
ushort ch_rout; /* Local receive buffer out ptr */
ushort ch_s_rin; /* Realport RIN */
/* David Fries 7-13-2001, ch_s_rin should be renamed ch_s_rout because
* the variable we want to represent is the PortServer's ROUT, which is
* the sequence number for the next byte the PortServer will send us.
* RIN is the sequence number for the next byte the PortServer will
* receive from the uart. The port server will send data as long as
* ROUT is less than RWIN. What would happen is the port is opened, it
* receives data, it gives the value of RIN, we set the RWIN to
* RIN+RBUF_MAX-1, it sends us RWIN-ROUT bytes which overflows. ROUT
* is set to zero when the port is opened, so we start at zero and
* count up as data is received.
*/
ushort ch_s_rwin; /* Realport RWIN */
ushort ch_s_rsize; /* Realport RSIZE */
ushort ch_tmax; /* Local TMAX */
ushort ch_ttime; /* Local TTIME */
ushort ch_rmax; /* Local RMAX */
ushort ch_rtime; /* Local RTIME */
ushort ch_rlow; /* Local RLOW */
ushort ch_rhigh; /* Local RHIGH */
ushort ch_s_tmax; /* Realport TMAX */
ushort ch_s_ttime; /* Realport TTIME */
ushort ch_s_rmax; /* Realport RMAX */
ushort ch_s_rtime; /* Realport RTIME */
ushort ch_s_rlow; /* Realport RLOW */
ushort ch_s_rhigh; /* Realport RHIGH */
ushort ch_brate; /* Local baud rate */
ushort ch_cflag; /* Local tty cflags */
ushort ch_iflag; /* Local tty iflags */
ushort ch_oflag; /* Local tty oflags */
ushort ch_xflag; /* Local tty xflags */
ushort ch_s_brate; /* Realport BRATE */
ushort ch_s_cflag; /* Realport CFLAG */
ushort ch_s_iflag; /* Realport IFLAG */
ushort ch_s_oflag; /* Realport OFLAG */
ushort ch_s_xflag; /* Realport XFLAG */
u8 ch_otype; /* Open request type */
u8 ch_pscan_savechar; /* Last character read by parity scan */
u8 ch_pscan_state; /* PScan State based on last 2 chars */
u8 ch_otype_waiting; /* Type of open pending in server */
u8 ch_flush_seq; /* Receive flush end sequence */
u8 ch_s_mlast; /* Realport MLAST */
u8 ch_mout; /* Local MOUT */
u8 ch_mflow; /* Local MFLOW */
u8 ch_mctrl; /* Local MCTRL */
u8 ch_xon; /* Local XON */
u8 ch_xoff; /* Local XOFF */
u8 ch_lnext; /* Local LNEXT */
u8 ch_xxon; /* Local XXON */
u8 ch_xxoff; /* Local XXOFF */
u8 ch_s_mout; /* Realport MOUT */
u8 ch_s_mflow; /* Realport MFLOW */
u8 ch_s_mctrl; /* Realport MCTRL */
u8 ch_s_xon; /* Realport XON */
u8 ch_s_xoff; /* Realport XOFF */
u8 ch_s_lnext; /* Realport LNEXT */
u8 ch_s_xxon; /* Realport XXON */
u8 ch_s_xxoff; /* Realport XXOFF */
wait_queue_head_t ch_flag_wait; /* Wait queue for ch_flag changes */
wait_queue_head_t ch_sleep; /* Wait queue for my_sleep() */
int ch_custom_speed; /* Realport custom speed */
int ch_txcount; /* Running TX count */
int ch_rxcount; /* Running RX count */
};
/************************************************************************
* Node State definitions.
************************************************************************/
enum dgrp_nd_state_t {
NS_CLOSED = 0, /* Network device is closed */
NS_IDLE = 1, /* Network connection inactive */
NS_SEND_QUERY = 2, /* Send server query */
NS_WAIT_QUERY = 3, /* Wait for query response */
NS_READY = 4, /* Network ready */
NS_SEND_ERROR = 5 /* Must send error hangup */
};
#define ND_STATE_STR(x) \
((x) == NS_CLOSED ? "CLOSED" : \
((x) == NS_IDLE ? "IDLE" : \
((x) == NS_SEND_QUERY ? "SEND_QUERY" : \
((x) == NS_WAIT_QUERY ? "WAIT_QUERY" : \
((x) == NS_READY ? "READY" : \
((x) == NS_SEND_ERROR ? "SEND_ERROR" : "UNKNOWN"))))))
/************************************************************************
* Node Flag definitions.
************************************************************************/
#define ND_SELECT 0x0001 /* Multiple net read selects */
#define ND_DEB_WAIT 0x0002 /* Debug Device waiting */
/************************************************************************
* Monitoring flag definitions.
************************************************************************/
#define MON_WAIT_DATA 0x0001 /* Waiting for buffer data */
#define MON_WAIT_SPACE 0x0002 /* Waiting for buffer space */
/************************************************************************
* DPA flag definitions.
************************************************************************/
#define DPA_WAIT_DATA 0x0001 /* Waiting for buffer data */
#define DPA_WAIT_SPACE 0x0002 /* Waiting for buffer space */
/************************************************************************
* Definitions taken from Realport Dump.
************************************************************************/
#define RPDUMP_MAGIC "Digi-RealPort-1.0"
#define RPDUMP_MESSAGE 0xE2 /* Descriptive message */
#define RPDUMP_RESET 0xE7 /* Connection reset */
#define RPDUMP_CLIENT 0xE8 /* Client data */
#define RPDUMP_SERVER 0xE9 /* Server data */
/************************************************************************
* Node request/response definitions.
************************************************************************/
#define NR_ECHO 0x0001 /* Server echo packet */
#define NR_IDENT 0x0002 /* Server Product ID */
#define NR_CAPABILITY 0x0004 /* Server Capabilties */
#define NR_VPD 0x0008 /* Server VPD, if any */
#define NR_PASSWORD 0x0010 /* Server Password */
/************************************************************************
* Registration status of the node's Linux struct tty_driver structures.
************************************************************************/
#define SERIAL_TTDRV_REG 0x0001 /* nd_serial_ttdriver registered */
#define CALLOUT_TTDRV_REG 0x0002 /* nd_callout_ttdriver registered */
#define XPRINT_TTDRV_REG 0x0004 /* nd_xprint_ttdriver registered */
/************************************************************************
* Node structure. There exists one of these for each associated
* realport server.
************************************************************************/
struct nd_struct {
struct list_head list;
long nd_major; /* Node's major number */
long nd_ID; /* Node's ID code */
char nd_serial_name[50]; /* "tty_dgrp_<id>_" + null */
char nd_callout_name[50]; /* "cu_dgrp_<id>_" + null */
char nd_xprint_name[50]; /* "pr_dgrp_<id>_" + null */
char password[16]; /* Password for server, if needed */
int nd_tty_ref_cnt; /* Linux tty reference count */
struct proc_dir_entry *nd_net_de; /* Dir entry for /proc/dgrp/net */
struct proc_dir_entry *nd_mon_de; /* Dir entry for /proc/dgrp/mon */
struct proc_dir_entry *nd_ports_de; /* Dir entry for /proc/dgrp/ports*/
struct proc_dir_entry *nd_dpa_de; /* Dir entry for /proc/dgrp/dpa */
spinlock_t nd_lock; /* General node lock */
struct semaphore nd_net_semaphore; /* Net read/write lock */
struct semaphore nd_mon_semaphore; /* Monitor buffer lock */
spinlock_t nd_dpa_lock; /* DPA buffer lock */
enum dgrp_nd_state_t nd_state; /* NS_* network state */
int nd_chan_count; /* # active channels */
int nd_flag; /* Node flags */
int nd_send; /* Responses to send */
int nd_expect; /* Responses we expect */
u8 *nd_iobuf; /* Network R/W Buffer */
wait_queue_head_t nd_tx_waitq; /* Network select wait queue */
u8 *nd_inputbuf; /* Input Buffer */
u8 *nd_inputflagbuf; /* Input Flags Buffer */
int nd_tx_deposit; /* Accumulated transmit deposits */
int nd_tx_charge; /* Accumulated transmit charges */
int nd_tx_credit; /* Current TX credit */
int nd_tx_ready; /* Ready to transmit */
int nd_tx_work; /* TX work waiting */
ulong nd_tx_time; /* Last transmit time */
ulong nd_poll_time; /* Next scheduled poll time */
int nd_delay; /* Current TX delay */
int nd_rate; /* Current TX rate */
struct link_struct nd_link; /* Link speed params. */
int nd_seq_in; /* TX seq in ptr */
int nd_seq_out; /* TX seq out ptr */
int nd_unack; /* Unacknowledged byte count */
int nd_remain; /* Remaining receive bytes */
int nd_tx_module; /* Current TX module # */
int nd_rx_module; /* Current RX module # */
char *nd_error; /* Protocol error message */
int nd_write_count; /* drp_write() call count */
int nd_read_count; /* drp_read() count */
int nd_send_count; /* TCP message sent */
int nd_tx_byte; /* Transmit byte count */
int nd_rx_byte; /* Receive byte count */
ulong nd_mon_lbolt; /* Monitor start time */
int nd_mon_flag; /* Monitor flags */
int nd_mon_in; /* Monitor in pointer */
int nd_mon_out; /* Monitor out pointer */
wait_queue_head_t nd_mon_wqueue; /* Monitor wait queue (on flags) */
u8 *nd_mon_buf; /* Monitor buffer */
ulong nd_dpa_lbolt; /* DPA start time */
int nd_dpa_flag; /* DPA flags */
int nd_dpa_in; /* DPA in pointer */
int nd_dpa_out; /* DPA out pointer */
wait_queue_head_t nd_dpa_wqueue; /* DPA wait queue (on flags) */
u8 *nd_dpa_buf; /* DPA buffer */
uint nd_dpa_debug;
uint nd_dpa_port;
wait_queue_head_t nd_seq_wque[SEQ_MAX]; /* TX thread wait queues */
u8 nd_seq_wait[SEQ_MAX]; /* Transmit thread wait count */
ushort nd_seq_size[SEQ_MAX]; /* Transmit seq packet size */
ulong nd_seq_time[SEQ_MAX]; /* Transmit seq packet time */
ushort nd_hw_ver; /* HW version returned from PS */
ushort nd_sw_ver; /* SW version returned from PS */
uint nd_hw_id; /* HW ID returned from PS */
u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
uint nd_vpd_len; /* VPD len, if any */
u8 nd_vpd[VPDSIZE]; /* VPD, if any */
ulong nd_ttdriver_flags; /* Registration status */
struct tty_driver *nd_serial_ttdriver; /* Linux TTYDRIVER structure */
struct tty_driver *nd_callout_ttdriver; /* Linux TTYDRIVER structure */
struct tty_driver *nd_xprint_ttdriver; /* Linux TTYDRIVER structure */
u8 *nd_writebuf; /* Used to cache data read
* from user
*/
struct ch_struct nd_chan[CHAN_MAX]; /* Channel array */
struct device *nd_class_dev; /* Hang our sysfs stuff off of here */
};
#endif /* __DRP_H */