/*
- * $Id: ctcmain.c,v 1.59 2004/04/21 17:10:13 ptiedem Exp $
+ * $Id: ctcmain.c,v 1.63 2004/07/28 12:27:54 ptiedem Exp $
*
* CTC / ESCON network driver
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.59 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.63 $
*
*/
\f
#include "ctctty.h"
#include "fsm.h"
#include "cu3088.h"
+#include "ctcdbug.h"
MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
print_banner(void)
{
static int printed = 0;
- char vbuf[] = "$Revision: 1.59 $";
+ char vbuf[] = "$Revision: 1.63 $";
char *version = vbuf;
if (printed)
{
struct net_device *dev = ch->netdev;
struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
-
__u16 len = *((__u16 *) pskb->data);
+
+ DBF_TEXT(trace, 4, __FUNCTION__);
skb_put(pskb, 2 + LL_HEADER_LENGTH);
skb_pull(pskb, 2);
pskb->dev = dev;
if (ch->protocol == CTC_PROTO_LINUX_TTY)
ctc_tty_netif_rx(skb);
else
- netif_rx(skb);
+ netif_rx_ni(skb);
/**
* Successful rx; reset logflags
*/
static void inline
ccw_check_return_code(struct channel *ch, int return_code, char *msg)
{
+ DBF_TEXT(trace, 5, __FUNCTION__);
switch (return_code) {
case 0:
fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);
static void inline
ccw_unit_check(struct channel *ch, unsigned char sense)
{
+ DBF_TEXT(trace, 5, __FUNCTION__);
if (sense & SNS0_INTERVENTION_REQ) {
if (sense & 0x01) {
if (ch->protocol != CTC_PROTO_LINUX_TTY)
{
struct sk_buff *skb;
+ DBF_TEXT(trace, 5, __FUNCTION__);
+
while ((skb = skb_dequeue(q))) {
atomic_dec(&skb->users);
dev_kfree_skb_irq(skb);
static __inline__ int
ctc_checkalloc_buffer(struct channel *ch, int warn)
{
+ DBF_TEXT(trace, 5, __FUNCTION__);
if ((ch->trans_skb == NULL) ||
(ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) {
if (ch->trans_skb != NULL)
struct sk_buff *skb;
int first = 1;
int i;
-
+ unsigned long duration;
struct timespec done_stamp = xtime;
- unsigned long duration =
+
+ DBF_TEXT(trace, 4, __FUNCTION__);
+
+ duration =
(done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
(done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
if (duration > ch->prof.tx_time)
{
struct channel *ch = (struct channel *) arg;
+ DBF_TEXT(trace, 4, __FUNCTION__);
fsm_deltimer(&ch->timer);
fsm_newstate(fi, CH_STATE_TXIDLE);
fsm_event(((struct ctc_priv *) ch->netdev->priv)->fsm, DEV_EVENT_TXUP,
int check_len;
int rc;
+ DBF_TEXT(trace, 4, __FUNCTION__);
fsm_deltimer(&ch->timer);
if (len < 8) {
ctc_pr_debug("%s: got packet with length %d < 8\n",
struct channel *ch = (struct channel *) arg;
int rc;
+ DBF_TEXT(trace, 4, __FUNCTION__);
+
if (fsm_getstate(fi) == CH_STATE_TXIDLE)
ctc_pr_debug("%s: remote side issued READ?, init ...\n", ch->id);
fsm_deltimer(&ch->timer);
__u16 buflen;
int rc;
+ DBF_TEXT(trace, 4, __FUNCTION__);
fsm_deltimer(&ch->timer);
buflen = *((__u16 *) ch->trans_skb->data);
#ifdef DEBUG
int rc;
unsigned long saveflags;
+ DBF_TEXT(trace, 4, __FUNCTION__);
fsm_deltimer(&ch->timer);
fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
fsm_newstate(fi, CH_STATE_SETUPWAIT);
int rc;
struct net_device *dev;
+ DBF_TEXT(trace, 4, __FUNCTION__);
if (ch == NULL) {
ctc_pr_warn("ch_action_start ch=NULL\n");
return;
int rc;
int oldstate;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
if (event == CH_EVENT_STOP)
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
fsm_newstate(fi, CH_STATE_STOPPED);
if (ch->trans_skb != NULL) {
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
fsm_newstate(fi, CH_STATE_NOTOP);
if (CHANNEL_DIRECTION(ch->flags) == READ) {
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(setup, 3, __FUNCTION__);
/**
* Special case: Got UC_RCRESET on setmode.
* This means that remote side isn't setup. In this case
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
ctc_pr_debug("%s: %s channel restart\n", dev->name,
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(setup, 3, __FUNCTION__);
if (event == CH_EVENT_TIMER) {
fsm_deltimer(&ch->timer);
ctc_pr_debug("%s: Timeout during RX init handshake\n", dev->name);
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(setup, 3, __FUNCTION__);
fsm_newstate(fi, CH_STATE_RXERR);
ctc_pr_warn("%s: RX initialization failed\n", dev->name);
ctc_pr_warn("%s: RX <-> RX connection detected\n", dev->name);
struct channel *ch2;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
ctc_pr_debug("%s: Got remote disconnect, re-initializing ...\n",
dev->name);
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(setup, 2, __FUNCTION__);
if (event == CH_EVENT_TIMER) {
fsm_deltimer(&ch->timer);
ctc_pr_debug("%s: Timeout during TX init handshake\n", dev->name);
struct net_device *dev = ch->netdev;
unsigned long saveflags;
+ DBF_TEXT(trace, 4, __FUNCTION__);
fsm_deltimer(&ch->timer);
if (ch->retry++ > 3) {
ctc_pr_debug("%s: TX retry failed, restarting channel\n",
struct channel *ch = (struct channel *) arg;
struct net_device *dev = ch->netdev;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_deltimer(&ch->timer);
if (CHANNEL_DIRECTION(ch->flags) == READ) {
ctc_pr_debug("%s: RX I/O error\n", dev->name);
struct net_device *dev = ch->netdev;
struct ctc_priv *privptr = dev->priv;
+ DBF_TEXT(trace, 4, __FUNCTION__);
ch_action_iofatal(fi, event, arg);
fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
}
struct channel **c = &channels;
struct channel *ch;
+ DBF_TEXT(trace, 2, __FUNCTION__);
if ((ch =
(struct channel *) kmalloc(sizeof (struct channel),
GFP_KERNEL)) == NULL) {
{
struct channel **c = &channels;
+ DBF_TEXT(trace, 2, __FUNCTION__);
if (ch == NULL)
return;
{
struct channel *ch = channels;
+ DBF_TEXT(trace, 3, __FUNCTION__);
#ifdef DEBUG
ctc_pr_debug("ctc: %s(): searching for ch with id %s and type %d\n",
__func__, id, type);
struct net_device *dev;
struct ctc_priv *priv;
+ DBF_TEXT(trace, 5, __FUNCTION__);
if (__ctc_check_irb_error(cdev, irb))
return;
struct ctc_priv *privptr = dev->priv;
int direction;
+ DBF_TEXT(setup, 3, __FUNCTION__);
fsm_deltimer(&privptr->restart_timer);
fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
for (direction = READ; direction <= WRITE; direction++) {
struct ctc_priv *privptr = dev->priv;
int direction;
+ DBF_TEXT(trace, 3, __FUNCTION__);
fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
for (direction = READ; direction <= WRITE; direction++) {
struct channel *ch = privptr->channel[direction];
struct net_device *dev = (struct net_device *)arg;
struct ctc_priv *privptr = dev->priv;
+ DBF_TEXT(trace, 3, __FUNCTION__);
ctc_pr_debug("%s: Restarting\n", dev->name);
dev_action_stop(fi, event, arg);
fsm_event(privptr->fsm, DEV_EVENT_STOP, dev);
struct net_device *dev = (struct net_device *) arg;
struct ctc_priv *privptr = dev->priv;
+ DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_STARTWAIT_RXTX:
if (event == DEV_EVENT_RXUP)
struct net_device *dev = (struct net_device *) arg;
struct ctc_priv *privptr = dev->priv;
+ DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_RUNNING:
if (privptr->protocol == CTC_PROTO_LINUX_TTY)
struct ll_header header;
int rc = 0;
+ DBF_TEXT(trace, 5, __FUNCTION__);
if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
int l = skb->len + LL_HEADER_LENGTH;
static int
ctc_open(struct net_device * dev)
{
+ DBF_TEXT(trace, 5, __FUNCTION__);
fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_START, dev);
return 0;
}
static int
ctc_close(struct net_device * dev)
{
+ DBF_TEXT(trace, 5, __FUNCTION__);
fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_STOP, dev);
return 0;
}
int rc = 0;
struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
+ DBF_TEXT(trace, 5, __FUNCTION__);
/**
* Some sanity checks ...
*/
{
struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
+ DBF_TEXT(trace, 3, __FUNCTION__);
if ((new_mtu < 576) || (new_mtu > 65527) ||
(new_mtu > (privptr->channel[READ]->max_bufsize -
LL_HEADER_LENGTH - 2)))
struct net_device *ndev;
int bs1;
+ DBF_TEXT(trace, 5, __FUNCTION__);
priv = dev->driver_data;
if (!priv)
return -ENODEV;
struct ctc_priv *priv;
int ll1;
+ DBF_TEXT(trace, 5, __FUNCTION__);
priv = dev->driver_data;
if (!priv)
return -ENODEV;
char *sbuf;
char *p;
+ DBF_TEXT(trace, 4, __FUNCTION__);
if (!priv)
return;
sbuf = (char *)kmalloc(2048, GFP_KERNEL);
if (!privptr)
return NULL;
+ DBF_TEXT(setup, 3, __FUNCTION__);
if (alloc_device) {
dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
if (!dev)
struct ctc_priv *priv;
int value;
+ DBF_TEXT(trace, 3, __FUNCTION__);
pr_debug("%s() called\n", __FUNCTION__);
priv = dev->driver_data;
int rc;
pr_debug("%s() called\n", __FUNCTION__);
+ DBF_TEXT(trace, 3, __FUNCTION__);
if (!get_device(&cgdev->dev))
return -ENODEV;
int ret;
pr_debug("%s() called\n", __FUNCTION__);
+ DBF_TEXT(setup, 3, __FUNCTION__);
privptr = cgdev->dev.driver_data;
if (!privptr)
}
if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- snprintf(dev->name, 8, "ctctty%%d");
+ strlcpy(dev->name, "ctctty%d", IFNAMSIZ);
else
- snprintf(dev->name, 8, "ctc%%d");
+ strlcpy(dev->name, "ctc%d", IFNAMSIZ);
for (direction = READ; direction <= WRITE; direction++) {
privptr->channel[direction] =
struct ctc_priv *priv;
struct net_device *ndev;
-
+ DBF_TEXT(trace, 3, __FUNCTION__);
pr_debug("%s() called\n", __FUNCTION__);
priv = cgdev->dev.driver_data;
struct ctc_priv *priv;
pr_debug("%s() called\n", __FUNCTION__);
+ DBF_TEXT(trace, 3, __FUNCTION__);
priv = cgdev->dev.driver_data;
if (!priv)
{
unregister_cu3088_discipline(&ctc_group_driver);
ctc_tty_cleanup();
+ ctc_unregister_dbf_views();
ctc_pr_info("CTC driver unloaded\n");
}
print_banner();
+ ret = ctc_register_dbf_views();
+ if (ret){
+ ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
+ return ret;
+ }
ctc_tty_init();
ret = register_cu3088_discipline(&ctc_group_driver);
- if (ret)
+ if (ret) {
ctc_tty_cleanup();
+ ctc_unregister_dbf_views();
+ }
return ret;
}