s390/net/ctcm: message cleanup
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Peter Tiedemann <ptiedem@de.ibm.com> Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
b805da74de
commit
aa3f2cb630
7 changed files with 888 additions and 1251 deletions
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -22,15 +23,13 @@
|
|||
* Debug Facility Stuff
|
||||
*/
|
||||
|
||||
DEFINE_PER_CPU(char[256], ctcm_dbf_txt_buf);
|
||||
|
||||
struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS] = {
|
||||
[CTCM_DBF_SETUP] = {"ctc_setup", 8, 1, 64, 5, NULL},
|
||||
[CTCM_DBF_ERROR] = {"ctc_error", 8, 1, 64, 3, NULL},
|
||||
[CTCM_DBF_TRACE] = {"ctc_trace", 8, 1, 64, 3, NULL},
|
||||
[CTCM_DBF_MPC_SETUP] = {"mpc_setup", 8, 1, 64, 5, NULL},
|
||||
[CTCM_DBF_MPC_ERROR] = {"mpc_error", 8, 1, 64, 3, NULL},
|
||||
[CTCM_DBF_MPC_TRACE] = {"mpc_trace", 8, 1, 64, 3, NULL},
|
||||
[CTCM_DBF_SETUP] = {"ctc_setup", 8, 1, 64, CTC_DBF_INFO, NULL},
|
||||
[CTCM_DBF_ERROR] = {"ctc_error", 8, 1, 64, CTC_DBF_ERROR, NULL},
|
||||
[CTCM_DBF_TRACE] = {"ctc_trace", 8, 1, 64, CTC_DBF_ERROR, NULL},
|
||||
[CTCM_DBF_MPC_SETUP] = {"mpc_setup", 8, 1, 80, CTC_DBF_INFO, NULL},
|
||||
[CTCM_DBF_MPC_ERROR] = {"mpc_error", 8, 1, 80, CTC_DBF_ERROR, NULL},
|
||||
[CTCM_DBF_MPC_TRACE] = {"mpc_trace", 8, 1, 80, CTC_DBF_ERROR, NULL},
|
||||
};
|
||||
|
||||
void ctcm_unregister_dbf_views(void)
|
||||
|
@ -65,3 +64,17 @@ int ctcm_register_dbf_views(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...)
|
||||
{
|
||||
char dbf_txt_buf[64];
|
||||
va_list args;
|
||||
|
||||
if (level > (ctcm_dbf[dbf_nix].id)->level)
|
||||
return;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
debug_text_event(ctcm_dbf[dbf_nix].id, level, dbf_txt_buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,17 @@
|
|||
#else
|
||||
#define do_debug 0
|
||||
#endif
|
||||
#ifdef DEBUGCCW
|
||||
#define do_debug_ccw 1
|
||||
#define DEBUGDATA 1
|
||||
#else
|
||||
#define do_debug_ccw 0
|
||||
#endif
|
||||
#ifdef DEBUGDATA
|
||||
#define do_debug_data 1
|
||||
#else
|
||||
#define do_debug_data 0
|
||||
#endif
|
||||
#ifdef DEBUGCCW
|
||||
#define do_debug_ccw 1
|
||||
#else
|
||||
#define do_debug_ccw 0
|
||||
#endif
|
||||
|
||||
/* define dbf debug levels similar to kernel msg levels */
|
||||
#define CTC_DBF_ALWAYS 0 /* always print this */
|
||||
|
@ -42,8 +43,6 @@
|
|||
#define CTC_DBF_INFO 5 /* informational */
|
||||
#define CTC_DBF_DEBUG 6 /* debug-level messages */
|
||||
|
||||
DECLARE_PER_CPU(char[256], ctcm_dbf_txt_buf);
|
||||
|
||||
enum ctcm_dbf_names {
|
||||
CTCM_DBF_SETUP,
|
||||
CTCM_DBF_ERROR,
|
||||
|
@ -67,6 +66,7 @@ extern struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS];
|
|||
|
||||
int ctcm_register_dbf_views(void);
|
||||
void ctcm_unregister_dbf_views(void);
|
||||
void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *text, ...);
|
||||
|
||||
static inline const char *strtail(const char *s, int n)
|
||||
{
|
||||
|
@ -74,12 +74,6 @@ static inline const char *strtail(const char *s, int n)
|
|||
return (l > n) ? s + (l - n) : s;
|
||||
}
|
||||
|
||||
/* sort out levels early to avoid unnecessary sprintfs */
|
||||
static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
|
||||
{
|
||||
return (dbf_grp->level >= level);
|
||||
}
|
||||
|
||||
#define CTCM_FUNTAIL strtail((char *)__func__, 16)
|
||||
|
||||
#define CTCM_DBF_TEXT(name, level, text) \
|
||||
|
@ -94,16 +88,7 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
|
|||
} while (0)
|
||||
|
||||
#define CTCM_DBF_TEXT_(name, level, text...) \
|
||||
do { \
|
||||
if (ctcm_dbf_passes(ctcm_dbf[CTCM_DBF_##name].id, level)) { \
|
||||
char *ctcm_dbf_txt_buf = \
|
||||
get_cpu_var(ctcm_dbf_txt_buf); \
|
||||
sprintf(ctcm_dbf_txt_buf, text); \
|
||||
debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, \
|
||||
level, ctcm_dbf_txt_buf); \
|
||||
put_cpu_var(ctcm_dbf_txt_buf); \
|
||||
} \
|
||||
} while (0)
|
||||
ctcm_dbf_longtext(CTCM_DBF_##name, level, text)
|
||||
|
||||
/*
|
||||
* cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}.
|
||||
|
@ -112,13 +97,13 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
|
|||
*/
|
||||
#define CTCM_DBF_DEV_NAME(cat, dev, text) \
|
||||
do { \
|
||||
CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) : %s", \
|
||||
CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) :- %s", \
|
||||
CTCM_FUNTAIL, dev->name, text); \
|
||||
} while (0)
|
||||
|
||||
#define MPC_DBF_DEV_NAME(cat, dev, text) \
|
||||
do { \
|
||||
CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) : %s", \
|
||||
CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) := %s", \
|
||||
CTCM_FUNTAIL, dev->name, text); \
|
||||
} while (0)
|
||||
|
||||
|
@ -137,13 +122,13 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
|
|||
*/
|
||||
#define CTCM_DBF_DEV(cat, dev, text) \
|
||||
do { \
|
||||
CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) : %s", \
|
||||
CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) :-: %s", \
|
||||
CTCM_FUNTAIL, dev, text); \
|
||||
} while (0)
|
||||
|
||||
#define MPC_DBF_DEV(cat, dev, text) \
|
||||
do { \
|
||||
CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) : %s", \
|
||||
CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) :=: %s", \
|
||||
CTCM_FUNTAIL, dev, text); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -190,7 +190,8 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg);
|
|||
void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg)
|
||||
{
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"ccw error %s (%s): %04x\n", ch->id, msg, rc);
|
||||
"%s(%s): %s: %04x\n",
|
||||
CTCM_FUNTAIL, ch->id, msg, rc);
|
||||
switch (rc) {
|
||||
case -EBUSY:
|
||||
ctcm_pr_warn("%s (%s): Busy !\n", ch->id, msg);
|
||||
|
@ -212,7 +213,7 @@ void ctcm_purge_skb_queue(struct sk_buff_head *q)
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
|
||||
CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __func__);
|
||||
|
||||
while ((skb = skb_dequeue(q))) {
|
||||
atomic_dec(&skb->users);
|
||||
|
@ -251,6 +252,8 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
unsigned long duration;
|
||||
struct timespec done_stamp = current_kernel_time(); /* xtime */
|
||||
|
||||
CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);
|
||||
|
||||
duration =
|
||||
(done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
|
||||
(done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
|
||||
|
@ -258,8 +261,9 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
ch->prof.tx_time = duration;
|
||||
|
||||
if (ch->irb->scsw.cmd.count != 0)
|
||||
ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
|
||||
dev->name, ch->irb->scsw.cmd.count);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): TX not complete, remaining %d bytes",
|
||||
CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);
|
||||
fsm_deltimer(&ch->timer);
|
||||
while ((skb = skb_dequeue(&ch->io_queue))) {
|
||||
priv->stats.tx_packets++;
|
||||
|
@ -334,7 +338,8 @@ void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg)
|
|||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
|
||||
CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
fsm_newstate(fi, CTC_STATE_TXIDLE);
|
||||
fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev);
|
||||
|
@ -361,15 +366,17 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (len < 8) {
|
||||
ctcm_pr_debug("%s: got packet with length %d < 8\n",
|
||||
dev->name, len);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s): got packet with length %d < 8\n",
|
||||
CTCM_FUNTAIL, dev->name, len);
|
||||
priv->stats.rx_dropped++;
|
||||
priv->stats.rx_length_errors++;
|
||||
goto again;
|
||||
}
|
||||
if (len > ch->max_bufsize) {
|
||||
ctcm_pr_debug("%s: got packet with length %d > %d\n",
|
||||
dev->name, len, ch->max_bufsize);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s): got packet with length %d > %d\n",
|
||||
CTCM_FUNTAIL, dev->name, len, ch->max_bufsize);
|
||||
priv->stats.rx_dropped++;
|
||||
priv->stats.rx_length_errors++;
|
||||
goto again;
|
||||
|
@ -388,8 +395,9 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
break;
|
||||
}
|
||||
if ((len < block_len) || (len > check_len)) {
|
||||
ctcm_pr_debug("%s: got block length %d != rx length %d\n",
|
||||
dev->name, block_len, len);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s): got block length %d != rx length %d\n",
|
||||
CTCM_FUNTAIL, dev->name, block_len, len);
|
||||
if (do_debug)
|
||||
ctcmpc_dump_skb(skb, 0);
|
||||
|
||||
|
@ -425,17 +433,23 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
*/
|
||||
static void chx_firstio(fsm_instance *fi, int event, void *arg)
|
||||
{
|
||||
struct channel *ch = arg;
|
||||
int rc;
|
||||
struct channel *ch = arg;
|
||||
int fsmstate = fsm_getstate(fi);
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s) : %02x",
|
||||
CTCM_FUNTAIL, ch->id, fsmstate);
|
||||
|
||||
if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
|
||||
ctcm_pr_debug("%s: remote side issued READ?, init.\n", ch->id);
|
||||
ch->sense_rc = 0; /* reset unit check report control */
|
||||
if (fsmstate == CTC_STATE_TXIDLE)
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): remote side issued READ?, init.\n",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (ctcm_checkalloc_buffer(ch))
|
||||
return;
|
||||
if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) &&
|
||||
if ((fsmstate == CTC_STATE_SETUPWAIT) &&
|
||||
(ch->protocol == CTCM_PROTO_OS390)) {
|
||||
/* OS/390 resp. z/OS */
|
||||
if (CHANNEL_DIRECTION(ch->flags) == READ) {
|
||||
|
@ -451,7 +465,6 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't setup a timer for receiving the initial RX frame
|
||||
* if in compatibility mode, since VM TCP delays the initial
|
||||
|
@ -505,11 +518,10 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
|
|||
__u16 buflen;
|
||||
int rc;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
|
||||
fsm_deltimer(&ch->timer);
|
||||
buflen = *((__u16 *)ch->trans_skb->data);
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s: Initial RX count %d\n", dev->name, buflen);
|
||||
CTCM_PR_DEBUG("%s: %s: Initial RX count = %d\n",
|
||||
__func__, dev->name, buflen);
|
||||
|
||||
if (buflen >= CTCM_INITIAL_BLOCKLEN) {
|
||||
if (ctcm_checkalloc_buffer(ch))
|
||||
|
@ -524,9 +536,9 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
|
|||
} else
|
||||
fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
|
||||
} else {
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s: Initial RX count %d not %d\n",
|
||||
dev->name, buflen, CTCM_INITIAL_BLOCKLEN);
|
||||
CTCM_PR_DEBUG("%s: %s: Initial RX count %d not %d\n",
|
||||
__func__, dev->name,
|
||||
buflen, CTCM_INITIAL_BLOCKLEN);
|
||||
chx_firstio(fi, event, arg);
|
||||
}
|
||||
}
|
||||
|
@ -548,14 +560,12 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
|
|||
fsm_deltimer(&ch->timer);
|
||||
if (IS_MPC(ch)) {
|
||||
timeout = 1500;
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcm enter: %s(): cp=%i ch=0x%p id=%s\n",
|
||||
__FUNCTION__, smp_processor_id(), ch, ch->id);
|
||||
CTCM_PR_DEBUG("enter %s: cp=%i ch=0x%p id=%s\n",
|
||||
__func__, smp_processor_id(), ch, ch->id);
|
||||
}
|
||||
fsm_addtimer(&ch->timer, timeout, CTC_EVENT_TIMER, ch);
|
||||
fsm_newstate(fi, CTC_STATE_SETUPWAIT);
|
||||
if (do_debug_ccw && IS_MPC(ch))
|
||||
ctcmpc_dumpit((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);
|
||||
CTCM_CCW_DUMP((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);
|
||||
|
||||
if (event == CTC_EVENT_TIMER) /* only for timer not yet locked */
|
||||
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
|
||||
|
@ -583,24 +593,12 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
|
|||
*/
|
||||
static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
|
||||
{
|
||||
struct channel *ch = arg;
|
||||
int rc;
|
||||
struct net_device *dev;
|
||||
struct channel *ch = arg;
|
||||
unsigned long saveflags;
|
||||
int rc;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
|
||||
if (ch == NULL) {
|
||||
ctcm_pr_warn("chx_start ch=NULL\n");
|
||||
return;
|
||||
}
|
||||
if (ch->netdev == NULL) {
|
||||
ctcm_pr_warn("chx_start dev=NULL, id=%s\n", ch->id);
|
||||
return;
|
||||
}
|
||||
dev = ch->netdev;
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s: %s channel start\n", dev->name,
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s): %s",
|
||||
CTCM_FUNTAIL, ch->id,
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
|
||||
|
||||
if (ch->trans_skb != NULL) {
|
||||
|
@ -618,11 +616,12 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
|
|||
ch->ccw[1].count = 0;
|
||||
}
|
||||
if (ctcm_checkalloc_buffer(ch)) {
|
||||
ctcm_pr_notice("%s: %s trans_skb allocation delayed "
|
||||
"until first transfer\n", dev->name,
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): %s trans_skb alloc delayed "
|
||||
"until first transfer",
|
||||
CTCM_FUNTAIL, ch->id,
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
|
||||
}
|
||||
|
||||
ch->ccw[0].cmd_code = CCW_CMD_PREPARE;
|
||||
ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
|
||||
ch->ccw[0].count = 0;
|
||||
|
@ -661,7 +660,6 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
|
|||
int rc;
|
||||
int oldstate;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (IS_MPC(ch))
|
||||
fsm_deltimer(&ch->sweep_timer);
|
||||
|
@ -684,7 +682,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
|
|||
fsm_deltimer(&ch->timer);
|
||||
if (event != CTC_EVENT_STOP) {
|
||||
fsm_newstate(fi, oldstate);
|
||||
ctcm_ccw_check_rc(ch, rc, (char *)__FUNCTION__);
|
||||
ctcm_ccw_check_rc(ch, rc, (char *)__func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -703,7 +701,9 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state,
|
|||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
|
||||
"%s(%s): %s[%d]\n",
|
||||
CTCM_FUNTAIL, dev->name, ch->id, state);
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (IS_MPC(ch))
|
||||
|
@ -743,7 +743,6 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state,
|
|||
*/
|
||||
static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg)
|
||||
{
|
||||
CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
|
||||
ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg);
|
||||
}
|
||||
|
||||
|
@ -771,7 +770,6 @@ static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg)
|
|||
*/
|
||||
static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg)
|
||||
{
|
||||
CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
|
||||
ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg);
|
||||
}
|
||||
|
||||
|
@ -809,8 +807,8 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
|
|||
}
|
||||
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
|
||||
"%s : %s error during %s channel setup state=%s\n",
|
||||
dev->name, ctc_ch_event_names[event],
|
||||
"%s(%s) : %s error during %s channel setup state=%s\n",
|
||||
CTCM_FUNTAIL, dev->name, ctc_ch_event_names[event],
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
|
||||
fsm_getstate_str(fi));
|
||||
|
||||
|
@ -838,10 +836,12 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)
|
|||
int oldstate;
|
||||
int rc;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, CTC_DBF_NOTICE, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s: %s[%d] of %s\n",
|
||||
CTCM_FUNTAIL, ch->id, event, dev->name);
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
ctcm_pr_debug("%s: %s channel restart\n", dev->name,
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
|
||||
|
||||
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
|
||||
oldstate = fsm_getstate(fi);
|
||||
fsm_newstate(fi, CTC_STATE_STARTWAIT);
|
||||
|
@ -876,13 +876,10 @@ static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg)
|
|||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
|
||||
if (event == CTC_EVENT_TIMER) {
|
||||
if (!IS_MPCDEV(dev))
|
||||
/* TODO : check if MPC deletes timer somewhere */
|
||||
fsm_deltimer(&ch->timer);
|
||||
ctcm_pr_debug("%s: Timeout during RX init handshake\n",
|
||||
dev->name);
|
||||
if (ch->retry++ < 3)
|
||||
ctcm_chx_restart(fi, event, arg);
|
||||
else {
|
||||
|
@ -907,9 +904,10 @@ static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg)
|
|||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): RX %s busy, init. fail",
|
||||
CTCM_FUNTAIL, dev->name, ch->id);
|
||||
fsm_newstate(fi, CTC_STATE_RXERR);
|
||||
ctcm_pr_warn("%s: RX busy. Initialization failed\n", dev->name);
|
||||
fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
|
||||
}
|
||||
|
||||
|
@ -927,11 +925,10 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
|
|||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
CTCM_DBF_DEV_NAME(TRACE, dev, "Got remote disconnect, re-initializing");
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s: %s: remote disconnect - re-init ...",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s: Got remote disconnect, "
|
||||
"re-initializing ...\n", dev->name);
|
||||
/*
|
||||
* Notify device statemachine
|
||||
*/
|
||||
|
@ -961,8 +958,6 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
|
|||
|
||||
if (event == CTC_EVENT_TIMER) {
|
||||
fsm_deltimer(&ch->timer);
|
||||
CTCM_DBF_DEV_NAME(ERROR, dev,
|
||||
"Timeout during TX init handshake");
|
||||
if (ch->retry++ < 3)
|
||||
ctcm_chx_restart(fi, event, arg);
|
||||
else {
|
||||
|
@ -971,9 +966,8 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
|
|||
}
|
||||
} else {
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s : %s error during channel setup state=%s",
|
||||
dev->name, ctc_ch_event_names[event],
|
||||
fsm_getstate_str(fi));
|
||||
"%s(%s): %s in %s", CTCM_FUNTAIL, ch->id,
|
||||
ctc_ch_event_names[event], fsm_getstate_str(fi));
|
||||
|
||||
ctcm_pr_warn("%s: Error during TX init handshake\n", dev->name);
|
||||
}
|
||||
|
@ -993,15 +987,15 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
|
|||
struct ctcm_priv *priv = dev->priv;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
|
||||
__FUNCTION__, smp_processor_id(), ch, ch->id);
|
||||
CTCM_PR_DEBUG("Enter: %s: cp=%i ch=0x%p id=%s\n",
|
||||
__func__, smp_processor_id(), ch, ch->id);
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
if (ch->retry++ > 3) {
|
||||
struct mpc_group *gptr = priv->mpcg;
|
||||
ctcm_pr_debug("%s: TX retry failed, restarting channel\n",
|
||||
dev->name);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
|
||||
"%s: %s: retries exceeded",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
|
||||
/* call restart if not MPC or if MPC and mpcg fsm is ready.
|
||||
use gptr as mpc indicator */
|
||||
|
@ -1010,7 +1004,9 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
|
|||
goto done;
|
||||
}
|
||||
|
||||
ctcm_pr_debug("%s: TX retry %d\n", dev->name, ch->retry);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s : %s: retry %d",
|
||||
CTCM_FUNTAIL, ch->id, ch->retry);
|
||||
skb = skb_peek(&ch->io_queue);
|
||||
if (skb) {
|
||||
int rc = 0;
|
||||
|
@ -1018,8 +1014,9 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
|
|||
clear_normalized_cda(&ch->ccw[4]);
|
||||
ch->ccw[4].count = skb->len;
|
||||
if (set_normalized_cda(&ch->ccw[4], skb->data)) {
|
||||
ctcm_pr_debug("%s: IDAL alloc failed, chan restart\n",
|
||||
dev->name);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
|
||||
"%s: %s: IDAL alloc failed",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
|
||||
ctcm_chx_restart(fi, event, arg);
|
||||
goto done;
|
||||
|
@ -1061,22 +1058,21 @@ static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg)
|
|||
struct channel *ch = arg;
|
||||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
int rd = CHANNEL_DIRECTION(ch->flags);
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
|
||||
fsm_deltimer(&ch->timer);
|
||||
ctcm_pr_warn("%s %s : unrecoverable channel error\n",
|
||||
CTC_DRIVER_NAME, dev->name);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s: %s: %s unrecoverable channel error",
|
||||
CTCM_FUNTAIL, ch->id, rd == READ ? "RX" : "TX");
|
||||
|
||||
if (IS_MPC(ch)) {
|
||||
priv->stats.tx_dropped++;
|
||||
priv->stats.tx_errors++;
|
||||
}
|
||||
|
||||
if (CHANNEL_DIRECTION(ch->flags) == READ) {
|
||||
ctcm_pr_debug("%s: RX I/O error\n", dev->name);
|
||||
if (rd == READ) {
|
||||
fsm_newstate(fi, CTC_STATE_RXERR);
|
||||
fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
|
||||
} else {
|
||||
ctcm_pr_debug("%s: TX I/O error\n", dev->name);
|
||||
fsm_newstate(fi, CTC_STATE_TXERR);
|
||||
fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
|
||||
}
|
||||
|
@ -1216,27 +1212,27 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
struct sk_buff *skb;
|
||||
int first = 1;
|
||||
int i;
|
||||
struct timespec done_stamp;
|
||||
__u32 data_space;
|
||||
unsigned long duration;
|
||||
struct sk_buff *peekskb;
|
||||
int rc;
|
||||
struct th_header *header;
|
||||
struct pdu *p_header;
|
||||
struct timespec done_stamp = current_kernel_time(); /* xtime */
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s cp:%i enter: %s()\n",
|
||||
dev->name, smp_processor_id(), __FUNCTION__);
|
||||
CTCM_PR_DEBUG("Enter %s: %s cp:%i\n",
|
||||
__func__, dev->name, smp_processor_id());
|
||||
|
||||
done_stamp = current_kernel_time(); /* xtime */
|
||||
duration = (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000
|
||||
+ (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
|
||||
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)
|
||||
ch->prof.tx_time = duration;
|
||||
|
||||
if (ch->irb->scsw.cmd.count != 0)
|
||||
ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
|
||||
dev->name, ch->irb->scsw.cmd.count);
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): TX not complete, remaining %d bytes",
|
||||
CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);
|
||||
fsm_deltimer(&ch->timer);
|
||||
while ((skb = skb_dequeue(&ch->io_queue))) {
|
||||
priv->stats.tx_packets++;
|
||||
|
@ -1250,7 +1246,6 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
}
|
||||
spin_lock(&ch->collect_lock);
|
||||
clear_normalized_cda(&ch->ccw[4]);
|
||||
|
||||
if ((ch->collect_len <= 0) || (grp->in_sweep != 0)) {
|
||||
spin_unlock(&ch->collect_lock);
|
||||
fsm_newstate(fi, CTC_STATE_TXIDLE);
|
||||
|
@ -1269,17 +1264,13 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
|
||||
ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
|
||||
i = 0;
|
||||
|
||||
if (do_debug_data)
|
||||
ctcm_pr_debug("ctcmpc: %s() building "
|
||||
"trans_skb from collect_q \n", __FUNCTION__);
|
||||
|
||||
p_header = NULL;
|
||||
data_space = grp->group_max_buflen - TH_HEADER_LENGTH;
|
||||
|
||||
if (do_debug_data)
|
||||
ctcm_pr_debug("ctcmpc: %s() building trans_skb from collect_q"
|
||||
" data_space:%04x\n", __FUNCTION__, data_space);
|
||||
p_header = NULL;
|
||||
CTCM_PR_DBGDATA("%s: building trans_skb from collect_q"
|
||||
" data_space:%04x\n",
|
||||
__func__, data_space);
|
||||
|
||||
while ((skb = skb_dequeue(&ch->collect_queue))) {
|
||||
memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len);
|
||||
p_header = (struct pdu *)
|
||||
|
@ -1290,15 +1281,12 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
else
|
||||
p_header->pdu_flag |= 0x20;
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
|
||||
__FUNCTION__, ch->trans_skb->len);
|
||||
ctcm_pr_debug("ctcmpc: %s() pdu header and data"
|
||||
" for up to 32 bytes sent to vtam\n",
|
||||
__FUNCTION__);
|
||||
ctcmpc_dumpit((char *)p_header,
|
||||
min_t(int, skb->len, 32));
|
||||
}
|
||||
CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",
|
||||
__func__, ch->trans_skb->len);
|
||||
CTCM_PR_DBGDATA("%s: pdu header and data for up"
|
||||
" to 32 bytes sent to vtam\n", __func__);
|
||||
CTCM_D3_DUMP((char *)p_header, min_t(int, skb->len, 32));
|
||||
|
||||
ch->collect_len -= skb->len;
|
||||
data_space -= skb->len;
|
||||
priv->stats.tx_packets++;
|
||||
|
@ -1314,46 +1302,38 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
if (p_header)
|
||||
p_header->pdu_flag |= PDU_LAST; /*Say it's the last one*/
|
||||
header = kzalloc(TH_HEADER_LENGTH, gfp_type());
|
||||
|
||||
if (!header) {
|
||||
printk(KERN_WARNING "ctcmpc: OUT OF MEMORY IN %s()"
|
||||
": Data Lost \n", __FUNCTION__);
|
||||
spin_unlock(&ch->collect_lock);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
|
||||
header->th_ch_flag = TH_HAS_PDU; /* Normal data */
|
||||
ch->th_seq_num++;
|
||||
header->th_seq_num = ch->th_seq_num;
|
||||
|
||||
if (do_debug_data)
|
||||
ctcm_pr_debug("%s: ToVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, ch->th_seq_num);
|
||||
CTCM_PR_DBGDATA("%s: ToVTAM_th_seq= %08x\n" ,
|
||||
__func__, ch->th_seq_num);
|
||||
|
||||
memcpy(skb_push(ch->trans_skb, TH_HEADER_LENGTH), header,
|
||||
TH_HEADER_LENGTH); /* put the TH on the packet */
|
||||
|
||||
kfree(header);
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
|
||||
__FUNCTION__, ch->trans_skb->len);
|
||||
|
||||
ctcm_pr_debug("ctcmpc: %s() up-to-50 bytes of trans_skb "
|
||||
"data to vtam from collect_q\n", __FUNCTION__);
|
||||
ctcmpc_dumpit((char *)ch->trans_skb->data,
|
||||
CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",
|
||||
__func__, ch->trans_skb->len);
|
||||
CTCM_PR_DBGDATA("%s: up-to-50 bytes of trans_skb "
|
||||
"data to vtam from collect_q\n", __func__);
|
||||
CTCM_D3_DUMP((char *)ch->trans_skb->data,
|
||||
min_t(int, ch->trans_skb->len, 50));
|
||||
}
|
||||
|
||||
spin_unlock(&ch->collect_lock);
|
||||
clear_normalized_cda(&ch->ccw[1]);
|
||||
if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
|
||||
dev_kfree_skb_any(ch->trans_skb);
|
||||
ch->trans_skb = NULL;
|
||||
printk(KERN_WARNING
|
||||
"ctcmpc: %s()CCW failure - data lost\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
|
||||
"%s: %s: IDAL alloc failed",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
return;
|
||||
}
|
||||
|
@ -1373,7 +1353,6 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
|
|||
}
|
||||
done:
|
||||
ctcm_clear_busy(dev);
|
||||
ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1393,26 +1372,25 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
struct mpc_group *grp = priv->mpcg;
|
||||
struct sk_buff *skb = ch->trans_skb;
|
||||
struct sk_buff *new_skb;
|
||||
unsigned long saveflags = 0; /* avoids compiler warning */
|
||||
unsigned long saveflags = 0; /* avoids compiler warning */
|
||||
int len = ch->max_bufsize - ch->irb->scsw.cmd.count;
|
||||
|
||||
if (do_debug_data) {
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx %s cp:%i %s\n",
|
||||
dev->name, smp_processor_id(), ch->id);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx: maxbuf: %04x "
|
||||
"len: %04x\n", ch->max_bufsize, len);
|
||||
}
|
||||
CTCM_PR_DEBUG("%s: %s: cp:%i %s maxbuf : %04x, len: %04x\n",
|
||||
CTCM_FUNTAIL, dev->name, smp_processor_id(),
|
||||
ch->id, ch->max_bufsize, len);
|
||||
fsm_deltimer(&ch->timer);
|
||||
|
||||
if (skb == NULL) {
|
||||
ctcm_pr_debug("ctcmpc exit: %s() TRANS_SKB = NULL \n",
|
||||
__FUNCTION__);
|
||||
goto again;
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): TRANS_SKB = NULL",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (len < TH_HEADER_LENGTH) {
|
||||
ctcm_pr_info("%s: got packet with invalid length %d\n",
|
||||
dev->name, len);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): packet length %d to short",
|
||||
CTCM_FUNTAIL, dev->name, len);
|
||||
priv->stats.rx_dropped++;
|
||||
priv->stats.rx_length_errors++;
|
||||
} else {
|
||||
|
@ -1422,11 +1400,9 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
new_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC);
|
||||
|
||||
if (new_skb == NULL) {
|
||||
printk(KERN_INFO "ctcmpc:%s() NEW_SKB = NULL\n",
|
||||
__FUNCTION__);
|
||||
printk(KERN_WARNING "ctcmpc: %s() MEMORY ALLOC FAILED"
|
||||
" - DATA LOST - MPC FAILED\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%d): skb allocation failed",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto again;
|
||||
}
|
||||
|
@ -1479,9 +1455,8 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
|
||||
dev->name, __FUNCTION__, ch, ch->id);
|
||||
CTCM_PR_DEBUG("Exit %s: %s, ch=0x%p, id=%s\n",
|
||||
__func__, dev->name, ch, ch->id);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1497,15 +1472,16 @@ static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
|
|||
struct channel *ch = arg;
|
||||
struct net_device *dev = ch->netdev;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
struct mpc_group *gptr = priv->mpcg;
|
||||
|
||||
CTCM_PR_DEBUG("Enter %s: id=%s, ch=0x%p\n",
|
||||
__func__, ch->id, ch);
|
||||
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_INFO,
|
||||
"%s: %s: chstate:%i, grpstate:%i, prot:%i\n",
|
||||
CTCM_FUNTAIL, ch->id, fsm_getstate(fi),
|
||||
fsm_getstate(gptr->fsm), ch->protocol);
|
||||
|
||||
if (do_debug) {
|
||||
struct mpc_group *gptr = priv->mpcg;
|
||||
ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
|
||||
__FUNCTION__, ch, ch->id);
|
||||
ctcm_pr_debug("%s() %s chstate:%i grpstate:%i chprotocol:%i\n",
|
||||
__FUNCTION__, ch->id, fsm_getstate(fi),
|
||||
fsm_getstate(gptr->fsm), ch->protocol);
|
||||
}
|
||||
if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
|
||||
MPC_DBF_DEV_NAME(TRACE, dev, "remote side issued READ? ");
|
||||
|
||||
|
@ -1531,9 +1507,8 @@ static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
|
|||
? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
|
||||
|
||||
done:
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
|
||||
__FUNCTION__, ch, ch->id);
|
||||
CTCM_PR_DEBUG("Exit %s: id=%s, ch=0x%p\n",
|
||||
__func__, ch->id, ch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1556,12 +1531,9 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
|
|||
unsigned long saveflags = 0; /* avoids compiler warning */
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
ctcm_pr_debug("%s cp:%i enter: %s()\n",
|
||||
dev->name, smp_processor_id(), __FUNCTION__);
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s() %s chstate:%i grpstate:%i\n",
|
||||
__FUNCTION__, ch->id,
|
||||
fsm_getstate(fi), fsm_getstate(grp->fsm));
|
||||
CTCM_PR_DEBUG("%s: %s: %s: cp:%i, chstate:%i grpstate:%i\n",
|
||||
__func__, ch->id, dev->name, smp_processor_id(),
|
||||
fsm_getstate(fi), fsm_getstate(grp->fsm));
|
||||
|
||||
fsm_newstate(fi, CTC_STATE_RXIDLE);
|
||||
/* XID processing complete */
|
||||
|
@ -1575,9 +1547,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
|
|||
skb_reset_tail_pointer(ch->trans_skb);
|
||||
ch->trans_skb->len = 0;
|
||||
ch->ccw[1].count = ch->max_bufsize;
|
||||
if (do_debug_ccw)
|
||||
ctcmpc_dumpit((char *)&ch->ccw[0],
|
||||
sizeof(struct ccw1) * 3);
|
||||
CTCM_CCW_DUMP((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);
|
||||
if (event == CTC_EVENT_START)
|
||||
/* see remark about conditional locking */
|
||||
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
|
||||
|
@ -1598,9 +1568,6 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
|
|||
|
||||
fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
|
||||
done:
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit: %s %s()\n",
|
||||
dev->name, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1616,13 +1583,9 @@ static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
|
|||
struct ctcm_priv *priv = dev->priv;
|
||||
struct mpc_group *grp = priv->mpcg;
|
||||
|
||||
if (do_debug) {
|
||||
ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s"
|
||||
"GrpState:%s ChState:%s\n",
|
||||
__FUNCTION__, smp_processor_id(), ch, ch->id,
|
||||
fsm_getstate_str(grp->fsm),
|
||||
fsm_getstate_str(ch->fsm));
|
||||
}
|
||||
CTCM_PR_DEBUG("%s(%s): %s(ch=0x%p), cp=%i, ChStat:%s, GrpStat:%s\n",
|
||||
__func__, dev->name, ch->id, ch, smp_processor_id(),
|
||||
fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));
|
||||
|
||||
switch (fsm_getstate(grp->fsm)) {
|
||||
case MPCG_STATE_XID2INITW:
|
||||
|
@ -1664,11 +1627,7 @@ static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit : %s(): cp=%i ch=0x%p id=%s\n",
|
||||
__FUNCTION__, smp_processor_id(), ch, ch->id);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1683,11 +1642,9 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
|
|||
struct ctcm_priv *priv = dev->priv;
|
||||
struct mpc_group *grp = priv->mpcg;
|
||||
|
||||
ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n",
|
||||
dev->name,
|
||||
__FUNCTION__, ch->id,
|
||||
fsm_getstate_str(grp->fsm),
|
||||
fsm_getstate_str(ch->fsm));
|
||||
CTCM_PR_DEBUG("%s(%s): %s\n ChState:%s GrpState:%s\n",
|
||||
__func__, dev->name, ch->id,
|
||||
fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));
|
||||
|
||||
fsm_deltimer(&ch->timer);
|
||||
|
||||
|
@ -1750,16 +1707,12 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
|
|||
if (ch->in_mpcgroup)
|
||||
fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
|
||||
else
|
||||
printk(KERN_WARNING "ctcmpc: %s() Not all channels have"
|
||||
" been added to group\n", __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): channel %s not added to group",
|
||||
CTCM_FUNTAIL, dev->name, ch->id);
|
||||
|
||||
done:
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit : %s()%s ch=0x%p id=%s\n",
|
||||
__FUNCTION__, dev->name, ch, ch->id);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1774,13 +1727,7 @@ static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg)
|
|||
struct ctcm_priv *priv = dev->priv;
|
||||
struct mpc_group *grp = priv->mpcg;
|
||||
|
||||
ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n",
|
||||
dev->name, __FUNCTION__, ch->id,
|
||||
fsm_getstate_str(grp->fsm),
|
||||
fsm_getstate_str(ch->fsm));
|
||||
|
||||
fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1802,19 +1749,16 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
|
|||
int rc = 0;
|
||||
unsigned long saveflags = 0;
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
|
||||
__FUNCTION__, smp_processor_id(), ach, ach->id);
|
||||
CTCM_PR_DEBUG("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
|
||||
__func__, smp_processor_id(), ach, ach->id);
|
||||
|
||||
if (grp->in_sweep == 0)
|
||||
goto done;
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcmpc: %s() 1: ToVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, wch->th_seq_num);
|
||||
ctcm_pr_debug("ctcmpc: %s() 1: FromVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, rch->th_seq_num);
|
||||
}
|
||||
CTCM_PR_DBGDATA("%s: 1: ToVTAM_th_seq= %08x\n" ,
|
||||
__func__, wch->th_seq_num);
|
||||
CTCM_PR_DBGDATA("%s: 1: FromVTAM_th_seq= %08x\n" ,
|
||||
__func__, rch->th_seq_num);
|
||||
|
||||
if (fsm_getstate(wch->fsm) != CTC_STATE_TXIDLE) {
|
||||
/* give the previous IO time to complete */
|
||||
|
@ -1853,11 +1797,9 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
|
|||
|
||||
header->sw.th_last_seq = wch->th_seq_num;
|
||||
|
||||
if (do_debug_ccw)
|
||||
ctcmpc_dumpit((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);
|
||||
|
||||
ctcm_pr_debug("ctcmpc: %s() sweep packet\n", __FUNCTION__);
|
||||
ctcmpc_dumpit((char *)header, TH_SWEEP_LENGTH);
|
||||
CTCM_CCW_DUMP((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);
|
||||
CTCM_PR_DBGDATA("%s: sweep packet\n", __func__);
|
||||
CTCM_D3_DUMP((char *)header, TH_SWEEP_LENGTH);
|
||||
|
||||
fsm_addtimer(&wch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, wch);
|
||||
fsm_newstate(wch->fsm, CTC_STATE_TX);
|
||||
|
@ -1876,19 +1818,13 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
|
|||
ctcm_clear_busy_do(dev);
|
||||
}
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcmpc: %s()2: ToVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, wch->th_seq_num);
|
||||
ctcm_pr_debug("ctcmpc: %s()2: FromVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, rch->th_seq_num);
|
||||
}
|
||||
CTCM_PR_DBGDATA("%s: To-/From-VTAM_th_seq = %08x/%08x\n" ,
|
||||
__func__, wch->th_seq_num, rch->th_seq_num);
|
||||
|
||||
if (rc != 0)
|
||||
ctcm_ccw_check_rc(wch, rc, "send sweep");
|
||||
|
||||
done:
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc exit: %s() %s\n", __FUNCTION__, ach->id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2149,9 +2085,8 @@ static void dev_action_stop(fsm_instance *fi, int event, void *arg)
|
|||
struct channel *ch = priv->channel[direction];
|
||||
fsm_event(ch->fsm, CTC_EVENT_STOP, ch);
|
||||
ch->th_seq_num = 0x00;
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcm: %s() CH_th_seq= %08x\n",
|
||||
__FUNCTION__, ch->th_seq_num);
|
||||
CTCM_PR_DEBUG("%s: CH_th_seq= %08x\n",
|
||||
__func__, ch->th_seq_num);
|
||||
}
|
||||
if (IS_MPC(priv))
|
||||
fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);
|
||||
|
@ -2199,8 +2134,11 @@ static void dev_action_chup(fsm_instance *fi, int event, void *arg)
|
|||
{
|
||||
struct net_device *dev = arg;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
int dev_stat = fsm_getstate(fi);
|
||||
|
||||
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
|
||||
"%s(%s): priv = %p [%d,%d]\n ", CTCM_FUNTAIL,
|
||||
dev->name, dev->priv, dev_stat, event);
|
||||
|
||||
switch (fsm_getstate(fi)) {
|
||||
case DEV_STATE_STARTWAIT_RXTX:
|
||||
|
|
|
@ -84,20 +84,19 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
|
|||
skb_pull(pskb, LL_HEADER_LENGTH);
|
||||
if ((ch->protocol == CTCM_PROTO_S390) &&
|
||||
(header->type != ETH_P_IP)) {
|
||||
|
||||
if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
|
||||
ch->logflags |= LOG_FLAG_ILLEGALPKT;
|
||||
/*
|
||||
* Check packet type only if we stick strictly
|
||||
* to S/390's protocol of OS390. This only
|
||||
* supports IP. Otherwise allow any packet
|
||||
* type.
|
||||
*/
|
||||
ctcm_pr_warn("%s Illegal packet type 0x%04x "
|
||||
"received, dropping\n",
|
||||
dev->name, header->type);
|
||||
ch->logflags |= LOG_FLAG_ILLEGALPKT;
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): Illegal packet type 0x%04x"
|
||||
" - dropping",
|
||||
CTCM_FUNTAIL, dev->name, header->type);
|
||||
}
|
||||
|
||||
priv->stats.rx_dropped++;
|
||||
priv->stats.rx_frame_errors++;
|
||||
return;
|
||||
|
@ -105,11 +104,11 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
|
|||
pskb->protocol = ntohs(header->type);
|
||||
if (header->length <= LL_HEADER_LENGTH) {
|
||||
if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
|
||||
ctcm_pr_warn(
|
||||
"%s Illegal packet size %d "
|
||||
"received (MTU=%d blocklen=%d), "
|
||||
"dropping\n", dev->name, header->length,
|
||||
dev->mtu, len);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): Illegal packet size %d(%d,%d)"
|
||||
"- dropping",
|
||||
CTCM_FUNTAIL, dev->name,
|
||||
header->length, dev->mtu, len);
|
||||
ch->logflags |= LOG_FLAG_ILLEGALSIZE;
|
||||
}
|
||||
|
||||
|
@ -122,10 +121,10 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
|
|||
if ((header->length > skb_tailroom(pskb)) ||
|
||||
(header->length > len)) {
|
||||
if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
|
||||
ctcm_pr_warn(
|
||||
"%s Illegal packet size %d (beyond the"
|
||||
" end of received data), dropping\n",
|
||||
dev->name, header->length);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): Packet size %d (overrun)"
|
||||
" - dropping", CTCM_FUNTAIL,
|
||||
dev->name, header->length);
|
||||
ch->logflags |= LOG_FLAG_OVERRUN;
|
||||
}
|
||||
|
||||
|
@ -139,9 +138,9 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
|
|||
skb = dev_alloc_skb(pskb->len);
|
||||
if (!skb) {
|
||||
if (!(ch->logflags & LOG_FLAG_NOMEM)) {
|
||||
ctcm_pr_warn(
|
||||
"%s Out of memory in ctcm_unpack_skb\n",
|
||||
dev->name);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): MEMORY allocation error",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
ch->logflags |= LOG_FLAG_NOMEM;
|
||||
}
|
||||
priv->stats.rx_dropped++;
|
||||
|
@ -184,7 +183,7 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
|
|||
*/
|
||||
static void channel_free(struct channel *ch)
|
||||
{
|
||||
CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s)", CTCM_FUNTAIL, ch->id);
|
||||
ch->flags &= ~CHANNEL_FLAGS_INUSE;
|
||||
fsm_newstate(ch->fsm, CTC_STATE_IDLE);
|
||||
}
|
||||
|
@ -251,19 +250,12 @@ static struct channel *channel_get(enum channel_types type,
|
|||
{
|
||||
struct channel *ch = channels;
|
||||
|
||||
if (do_debug) {
|
||||
char buf[64];
|
||||
sprintf(buf, "%s(%d, %s, %d)\n",
|
||||
CTCM_FUNTAIL, type, id, direction);
|
||||
CTCM_DBF_TEXT(TRACE, CTC_DBF_INFO, buf);
|
||||
}
|
||||
while (ch && (strncmp(ch->id, id, CTCM_ID_SIZE) || (ch->type != type)))
|
||||
ch = ch->next;
|
||||
if (!ch) {
|
||||
char buf[64];
|
||||
sprintf(buf, "%s(%d, %s, %d) not found in channel list\n",
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%d, %s, %d) not found in channel list\n",
|
||||
CTCM_FUNTAIL, type, id, direction);
|
||||
CTCM_DBF_TEXT(ERROR, CTC_DBF_ERROR, buf);
|
||||
} else {
|
||||
if (ch->flags & CHANNEL_FLAGS_INUSE)
|
||||
ch = NULL;
|
||||
|
@ -283,8 +275,9 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
|
|||
if (!IS_ERR(irb))
|
||||
return 0;
|
||||
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN, "irb error %ld on device %s\n",
|
||||
PTR_ERR(irb), cdev->dev.bus_id);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN,
|
||||
"irb error %ld on device %s\n",
|
||||
PTR_ERR(irb), cdev->dev.bus_id);
|
||||
|
||||
switch (PTR_ERR(irb)) {
|
||||
case -EIO:
|
||||
|
@ -307,58 +300,85 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
|
|||
* ch The channel, the sense code belongs to.
|
||||
* sense The sense code to inspect.
|
||||
*/
|
||||
static inline void ccw_unit_check(struct channel *ch, unsigned char sense)
|
||||
static inline void ccw_unit_check(struct channel *ch, __u8 sense)
|
||||
{
|
||||
CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): %02x",
|
||||
CTCM_FUNTAIL, ch->id, sense);
|
||||
|
||||
if (sense & SNS0_INTERVENTION_REQ) {
|
||||
if (sense & 0x01) {
|
||||
ctcm_pr_debug("%s: Interface disc. or Sel. reset "
|
||||
"(remote)\n", ch->id);
|
||||
if (ch->sense_rc != 0x01) {
|
||||
ctcm_pr_debug("%s: Interface disc. or Sel. "
|
||||
"reset (remote)\n", ch->id);
|
||||
ch->sense_rc = 0x01;
|
||||
}
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_RCRESET, ch);
|
||||
} else {
|
||||
ctcm_pr_debug("%s: System reset (remote)\n", ch->id);
|
||||
if (ch->sense_rc != SNS0_INTERVENTION_REQ) {
|
||||
ctcm_pr_debug("%s: System reset (remote)\n",
|
||||
ch->id);
|
||||
ch->sense_rc = SNS0_INTERVENTION_REQ;
|
||||
}
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_RSRESET, ch);
|
||||
}
|
||||
} else if (sense & SNS0_EQUIPMENT_CHECK) {
|
||||
if (sense & SNS0_BUS_OUT_CHECK) {
|
||||
ctcm_pr_warn("%s: Hardware malfunction (remote)\n",
|
||||
ch->id);
|
||||
if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): remote HW error %02x",
|
||||
CTCM_FUNTAIL, ch->id, sense);
|
||||
ch->sense_rc = SNS0_BUS_OUT_CHECK;
|
||||
}
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_HWFAIL, ch);
|
||||
} else {
|
||||
ctcm_pr_warn("%s: Read-data parity error (remote)\n",
|
||||
ch->id);
|
||||
if (ch->sense_rc != SNS0_EQUIPMENT_CHECK) {
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): remote read parity error %02x",
|
||||
CTCM_FUNTAIL, ch->id, sense);
|
||||
ch->sense_rc = SNS0_EQUIPMENT_CHECK;
|
||||
}
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_RXPARITY, ch);
|
||||
}
|
||||
} else if (sense & SNS0_BUS_OUT_CHECK) {
|
||||
if (sense & 0x04) {
|
||||
ctcm_pr_warn("%s: Data-streaming timeout)\n", ch->id);
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch);
|
||||
} else {
|
||||
ctcm_pr_warn("%s: Data-transfer parity error\n",
|
||||
ch->id);
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch);
|
||||
if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): BUS OUT error %02x",
|
||||
CTCM_FUNTAIL, ch->id, sense);
|
||||
ch->sense_rc = SNS0_BUS_OUT_CHECK;
|
||||
}
|
||||
if (sense & 0x04) /* data-streaming timeout */
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch);
|
||||
else /* Data-transfer parity error */
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch);
|
||||
} else if (sense & SNS0_CMD_REJECT) {
|
||||
ctcm_pr_warn("%s: Command reject\n", ch->id);
|
||||
if (ch->sense_rc != SNS0_CMD_REJECT) {
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): Command rejected",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
ch->sense_rc = SNS0_CMD_REJECT;
|
||||
}
|
||||
} else if (sense == 0) {
|
||||
ctcm_pr_debug("%s: Unit check ZERO\n", ch->id);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): Unit check ZERO",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_ZERO, ch);
|
||||
} else {
|
||||
ctcm_pr_warn("%s: Unit Check with sense code: %02x\n",
|
||||
ch->id, sense);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
|
||||
"%s(%s): Unit check code %02x unknown",
|
||||
CTCM_FUNTAIL, ch->id, sense);
|
||||
fsm_event(ch->fsm, CTC_EVENT_UC_UNKNOWN, ch);
|
||||
}
|
||||
}
|
||||
|
||||
int ctcm_ch_alloc_buffer(struct channel *ch)
|
||||
{
|
||||
CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
|
||||
|
||||
clear_normalized_cda(&ch->ccw[1]);
|
||||
ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC | GFP_DMA);
|
||||
if (ch->trans_skb == NULL) {
|
||||
ctcm_pr_warn("%s: Couldn't alloc %s trans_skb\n",
|
||||
ch->id,
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): %s trans_skb allocation error",
|
||||
CTCM_FUNTAIL, ch->id,
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -367,9 +387,9 @@ int ctcm_ch_alloc_buffer(struct channel *ch)
|
|||
if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
|
||||
dev_kfree_skb(ch->trans_skb);
|
||||
ch->trans_skb = NULL;
|
||||
ctcm_pr_warn("%s: set_normalized_cda for %s "
|
||||
"trans_skb failed, dropping packets\n",
|
||||
ch->id,
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): %s set norm_cda failed",
|
||||
CTCM_FUNTAIL, ch->id,
|
||||
(CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -516,7 +536,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
atomic_dec(&skb->users);
|
||||
skb_pull(skb, LL_HEADER_LENGTH + 2);
|
||||
ctcm_clear_busy(ch->netdev);
|
||||
return -EBUSY;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_reset_tail_pointer(ch->trans_skb);
|
||||
|
@ -570,15 +590,12 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
|
|||
struct th_sweep *header;
|
||||
struct sk_buff *sweep_skb;
|
||||
struct channel *ch;
|
||||
int rc = 0;
|
||||
/* int rc = 0; */
|
||||
|
||||
priv = dev->priv;
|
||||
grp = priv->mpcg;
|
||||
ch = priv->channel[WRITE];
|
||||
|
||||
if (do_debug)
|
||||
MPC_DBF_DEV_NAME(TRACE, dev, ch->id);
|
||||
|
||||
/* sweep processing is not complete until response and request */
|
||||
/* has completed for all read channels in group */
|
||||
if (grp->in_sweep == 0) {
|
||||
|
@ -590,17 +607,16 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
|
|||
sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
|
||||
|
||||
if (sweep_skb == NULL) {
|
||||
printk(KERN_INFO "Couldn't alloc sweep_skb\n");
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
/* rc = -ENOMEM; */
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
header = kmalloc(TH_SWEEP_LENGTH, gfp_type());
|
||||
|
||||
if (!header) {
|
||||
dev_kfree_skb_any(sweep_skb);
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
/* rc = -ENOMEM; */
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
header->th.th_seg = 0x00 ;
|
||||
|
@ -621,12 +637,10 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
|
|||
|
||||
return;
|
||||
|
||||
done:
|
||||
if (rc != 0) {
|
||||
grp->in_sweep = 0;
|
||||
ctcm_clear_busy(dev);
|
||||
fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
|
||||
}
|
||||
nomem:
|
||||
grp->in_sweep = 0;
|
||||
ctcm_clear_busy(dev);
|
||||
fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -648,11 +662,9 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
unsigned long saveflags = 0; /* avoids compiler warning */
|
||||
__u16 block_len;
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug(
|
||||
"ctcm enter: %s(): %s cp=%i ch=0x%p id=%s state=%s\n",
|
||||
__FUNCTION__, dev->name, smp_processor_id(), ch,
|
||||
ch->id, fsm_getstate_str(ch->fsm));
|
||||
CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
|
||||
__func__, dev->name, smp_processor_id(), ch,
|
||||
ch->id, fsm_getstate_str(ch->fsm));
|
||||
|
||||
if ((fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) || grp->in_sweep) {
|
||||
spin_lock_irqsave(&ch->collect_lock, saveflags);
|
||||
|
@ -660,14 +672,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
|
||||
|
||||
if (!p_header) {
|
||||
printk(KERN_WARNING "ctcm: OUT OF MEMORY IN %s():"
|
||||
" Data Lost \n", __FUNCTION__);
|
||||
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
goto nomem_exit;
|
||||
}
|
||||
|
||||
p_header->pdu_offset = skb->len;
|
||||
|
@ -682,13 +688,10 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header,
|
||||
PDU_HEADER_LENGTH);
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcm: %s() Putting on collect_q"
|
||||
" - skb len: %04x \n", __FUNCTION__, skb->len);
|
||||
ctcm_pr_debug("ctcm: %s() pdu header and data"
|
||||
" for up to 32 bytes\n", __FUNCTION__);
|
||||
ctcmpc_dump32((char *)skb->data, skb->len);
|
||||
}
|
||||
CTCM_PR_DEBUG("%s(%s): Put on collect_q - skb len: %04x \n"
|
||||
"pdu header and data for up to 32 bytes:\n",
|
||||
__func__, dev->name, skb->len);
|
||||
CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
|
||||
|
||||
skb_queue_tail(&ch->collect_queue, skb);
|
||||
ch->collect_len += skb->len;
|
||||
|
@ -713,12 +716,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
if (hi) {
|
||||
nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
|
||||
if (!nskb) {
|
||||
printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
|
||||
"- Data Lost \n", __FUNCTION__);
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
goto nomem_exit;
|
||||
} else {
|
||||
memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
|
||||
atomic_inc(&nskb->users);
|
||||
|
@ -730,15 +728,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
|
||||
p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
|
||||
|
||||
if (!p_header) {
|
||||
printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
|
||||
": Data Lost \n", __FUNCTION__);
|
||||
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
}
|
||||
if (!p_header)
|
||||
goto nomem_exit;
|
||||
|
||||
p_header->pdu_offset = skb->len;
|
||||
p_header->pdu_proto = 0x01;
|
||||
|
@ -768,15 +759,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
ch->prof.txlen += skb->len - PDU_HEADER_LENGTH;
|
||||
|
||||
header = kmalloc(TH_HEADER_LENGTH, gfp_type());
|
||||
|
||||
if (!header) {
|
||||
printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY: Data Lost \n",
|
||||
__FUNCTION__);
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
}
|
||||
if (!header)
|
||||
goto nomem_exit;
|
||||
|
||||
header->th_seg = 0x00;
|
||||
header->th_ch_flag = TH_HAS_PDU; /* Normal data */
|
||||
|
@ -785,41 +769,31 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
ch->th_seq_num++;
|
||||
header->th_seq_num = ch->th_seq_num;
|
||||
|
||||
if (do_debug_data)
|
||||
ctcm_pr_debug("ctcm: %s() ToVTAM_th_seq= %08x\n" ,
|
||||
__FUNCTION__, ch->th_seq_num);
|
||||
CTCM_PR_DBGDATA("%s(%s) ToVTAM_th_seq= %08x\n" ,
|
||||
__func__, dev->name, ch->th_seq_num);
|
||||
|
||||
/* put the TH on the packet */
|
||||
memcpy(skb_push(skb, TH_HEADER_LENGTH), header, TH_HEADER_LENGTH);
|
||||
|
||||
kfree(header);
|
||||
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcm: %s(): skb len: %04x \n",
|
||||
__FUNCTION__, skb->len);
|
||||
ctcm_pr_debug("ctcm: %s(): pdu header and data for up to 32 "
|
||||
"bytes sent to vtam\n", __FUNCTION__);
|
||||
ctcmpc_dump32((char *)skb->data, skb->len);
|
||||
}
|
||||
CTCM_PR_DBGDATA("%s(%s): skb len: %04x\n - pdu header and data for "
|
||||
"up to 32 bytes sent to vtam:\n",
|
||||
__func__, dev->name, skb->len);
|
||||
CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
|
||||
|
||||
ch->ccw[4].count = skb->len;
|
||||
if (set_normalized_cda(&ch->ccw[4], skb->data)) {
|
||||
/*
|
||||
* idal allocation failed, try via copying to
|
||||
* trans_skb. trans_skb usually has a pre-allocated
|
||||
* idal.
|
||||
* idal allocation failed, try via copying to trans_skb.
|
||||
* trans_skb usually has a pre-allocated idal.
|
||||
*/
|
||||
if (ctcm_checkalloc_buffer(ch)) {
|
||||
/*
|
||||
* Remove our header. It gets added
|
||||
* again on retransmit.
|
||||
* Remove our header.
|
||||
* It gets added again on retransmit.
|
||||
*/
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
printk(KERN_WARNING "ctcm: %s()OUT OF MEMORY:"
|
||||
" Data Lost \n", __FUNCTION__);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
goto done;
|
||||
goto nomem_exit;
|
||||
}
|
||||
|
||||
skb_reset_tail_pointer(ch->trans_skb);
|
||||
|
@ -829,14 +803,11 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_irq(skb);
|
||||
ccw_idx = 0;
|
||||
if (do_debug_data) {
|
||||
ctcm_pr_debug("ctcm: %s() TRANS skb len: %d \n",
|
||||
__FUNCTION__, ch->trans_skb->len);
|
||||
ctcm_pr_debug("ctcm: %s up to 32 bytes of data"
|
||||
" sent to vtam\n", __FUNCTION__);
|
||||
ctcmpc_dump32((char *)ch->trans_skb->data,
|
||||
ch->trans_skb->len);
|
||||
}
|
||||
CTCM_PR_DBGDATA("%s(%s): trans_skb len: %04x\n"
|
||||
"up to 32 bytes sent to vtam:\n",
|
||||
__func__, dev->name, ch->trans_skb->len);
|
||||
CTCM_D3_DUMP((char *)ch->trans_skb->data,
|
||||
min_t(int, 32, ch->trans_skb->len));
|
||||
} else {
|
||||
skb_queue_tail(&ch->io_queue, skb);
|
||||
ccw_idx = 3;
|
||||
|
@ -865,13 +836,21 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
priv->stats.tx_packets++;
|
||||
priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;
|
||||
}
|
||||
if (ch->th_seq_num > 0xf0000000) /* Chose 4Billion at random. */
|
||||
if (ch->th_seq_num > 0xf0000000) /* Chose at random. */
|
||||
ctcmpc_send_sweep_req(ch);
|
||||
|
||||
goto done;
|
||||
nomem_exit:
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_CRIT,
|
||||
"%s(%s): MEMORY allocation ERROR\n",
|
||||
CTCM_FUNTAIL, ch->id);
|
||||
rc = -ENOMEM;
|
||||
atomic_dec(&skb->users);
|
||||
dev_kfree_skb_any(skb);
|
||||
fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
|
||||
done:
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcm exit: %s %s()\n", dev->name, __FUNCTION__);
|
||||
return 0;
|
||||
CTCM_PR_DEBUG("Exit %s(%s)\n", __func__, dev->name);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -888,20 +867,19 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
|
|||
/* first merge version - leaving both functions separated */
|
||||
static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct ctcm_priv *priv;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
|
||||
priv = dev->priv;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
|
||||
if (skb == NULL) {
|
||||
ctcm_pr_warn("%s: NULL sk_buff passed\n", dev->name);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): NULL sk_buff passed",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
priv->stats.tx_dropped++;
|
||||
return 0;
|
||||
}
|
||||
if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
|
||||
ctcm_pr_warn("%s: Got sk_buff with head room < %ld bytes\n",
|
||||
dev->name, LL_HEADER_LENGTH + 2);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): Got sk_buff with head room < %ld bytes",
|
||||
CTCM_FUNTAIL, dev->name, LL_HEADER_LENGTH + 2);
|
||||
dev_kfree_skb(skb);
|
||||
priv->stats.tx_dropped++;
|
||||
return 0;
|
||||
|
@ -925,51 +903,43 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
dev->trans_start = jiffies;
|
||||
if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
|
||||
rc = 1;
|
||||
return rc;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unmerged MPC variant of ctcm_tx */
|
||||
static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
int len = 0;
|
||||
struct ctcm_priv *priv = NULL;
|
||||
struct mpc_group *grp = NULL;
|
||||
struct ctcm_priv *priv = dev->priv;
|
||||
struct mpc_group *grp = priv->mpcg;
|
||||
struct sk_buff *newskb = NULL;
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("ctcmpc enter: %s(): skb:%0lx\n",
|
||||
__FUNCTION__, (unsigned long)skb);
|
||||
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
|
||||
"ctcmpc enter: %s(): skb:%0lx\n",
|
||||
__FUNCTION__, (unsigned long)skb);
|
||||
|
||||
priv = dev->priv;
|
||||
grp = priv->mpcg;
|
||||
/*
|
||||
* Some sanity checks ...
|
||||
*/
|
||||
if (skb == NULL) {
|
||||
ctcm_pr_warn("ctcmpc: %s: NULL sk_buff passed\n", dev->name);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): NULL sk_buff passed",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
priv->stats.tx_dropped++;
|
||||
goto done;
|
||||
}
|
||||
if (skb_headroom(skb) < (TH_HEADER_LENGTH + PDU_HEADER_LENGTH)) {
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_WARN,
|
||||
"%s: Got sk_buff with head room < %ld bytes\n",
|
||||
dev->name, TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
|
||||
"%s(%s): Got sk_buff with head room < %ld bytes",
|
||||
CTCM_FUNTAIL, dev->name,
|
||||
TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
|
||||
|
||||
if (do_debug_data)
|
||||
ctcmpc_dump32((char *)skb->data, skb->len);
|
||||
CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
|
||||
|
||||
len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
|
||||
newskb = __dev_alloc_skb(len, gfp_type() | GFP_DMA);
|
||||
|
||||
if (!newskb) {
|
||||
printk(KERN_WARNING "ctcmpc: %s() OUT OF MEMORY-"
|
||||
"Data Lost\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
|
||||
"%s: %s: __dev_alloc_skb failed",
|
||||
__func__, dev->name);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
priv->stats.tx_dropped++;
|
||||
|
@ -993,9 +963,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
if ((fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) ||
|
||||
(fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
printk(KERN_INFO "ctcmpc: %s() DATA RCVD - MPC GROUP "
|
||||
"NOT ACTIVE - DROPPED\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): inactive MPCGROUP - dropped",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
priv->stats.tx_dropped++;
|
||||
priv->stats.tx_errors++;
|
||||
priv->stats.tx_carrier_errors++;
|
||||
|
@ -1003,8 +973,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
if (ctcm_test_and_set_busy(dev)) {
|
||||
printk(KERN_WARNING "%s:DEVICE ERR - UNRECOVERABLE DATA LOSS\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): device busy - dropped",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
dev_kfree_skb_any(skb);
|
||||
priv->stats.tx_dropped++;
|
||||
priv->stats.tx_errors++;
|
||||
|
@ -1015,12 +986,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
dev->trans_start = jiffies;
|
||||
if (ctcmpc_transmit_skb(priv->channel[WRITE], skb) != 0) {
|
||||
printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
|
||||
": Data Lost \n",
|
||||
__FUNCTION__);
|
||||
printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
|
||||
" - UNRECOVERABLE DATA LOSS\n",
|
||||
__FUNCTION__);
|
||||
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
|
||||
"%s(%s): device error - dropped",
|
||||
CTCM_FUNTAIL, dev->name);
|
||||
dev_kfree_skb_any(skb);
|
||||
priv->stats.tx_dropped++;
|
||||
priv->stats.tx_errors++;
|
||||
|
@ -1054,8 +1022,6 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
|
|||
struct ctcm_priv *priv;
|
||||
int max_bufsize;
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
|
||||
|
||||
if (new_mtu < 576 || new_mtu > 65527)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1087,30 +1053,13 @@ static struct net_device_stats *ctcm_stats(struct net_device *dev)
|
|||
return &((struct ctcm_priv *)dev->priv)->stats;
|
||||
}
|
||||
|
||||
|
||||
static void ctcm_netdev_unregister(struct net_device *dev)
|
||||
{
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
|
||||
if (!dev)
|
||||
return;
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
|
||||
static int ctcm_netdev_register(struct net_device *dev)
|
||||
{
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
|
||||
return register_netdev(dev);
|
||||
}
|
||||
|
||||
static void ctcm_free_netdevice(struct net_device *dev)
|
||||
{
|
||||
struct ctcm_priv *priv;
|
||||
struct mpc_group *grp;
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"%s(%s)", CTCM_FUNTAIL, dev->name);
|
||||
priv = dev->priv;
|
||||
if (priv) {
|
||||
grp = priv->mpcg;
|
||||
|
@ -1171,7 +1120,9 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
|
|||
dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup);
|
||||
|
||||
if (!dev) {
|
||||
ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
|
||||
"%s: MEMORY allocation ERROR",
|
||||
CTCM_FUNTAIL);
|
||||
return NULL;
|
||||
}
|
||||
dev->priv = priv;
|
||||
|
@ -1209,6 +1160,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
|
|||
}
|
||||
|
||||
CTCMY_DBF_DEV(SETUP, dev, "finished");
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
@ -1226,18 +1178,24 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
|
|||
struct net_device *dev;
|
||||
struct ctcm_priv *priv;
|
||||
struct ccwgroup_device *cgdev;
|
||||
int cstat;
|
||||
int dstat;
|
||||
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"Enter %s(%s)", CTCM_FUNTAIL, &cdev->dev.bus_id);
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __FUNCTION__);
|
||||
if (ctcm_check_irb_error(cdev, irb))
|
||||
return;
|
||||
|
||||
cgdev = dev_get_drvdata(&cdev->dev);
|
||||
|
||||
cstat = irb->scsw.cmd.cstat;
|
||||
dstat = irb->scsw.cmd.dstat;
|
||||
|
||||
/* Check for unsolicited interrupts. */
|
||||
if (cgdev == NULL) {
|
||||
ctcm_pr_warn("ctcm: Got unsolicited irq: %s c-%02x d-%02x\n",
|
||||
cdev->dev.bus_id, irb->scsw.cmd.cstat,
|
||||
irb->scsw.cmd.dstat);
|
||||
ctcm_pr_warn("ctcm: Got unsolicited irq: c-%02x d-%02x\n",
|
||||
cstat, dstat);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1254,26 +1212,22 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
|
|||
return;
|
||||
}
|
||||
|
||||
dev = (struct net_device *)(ch->netdev);
|
||||
dev = ch->netdev;
|
||||
if (dev == NULL) {
|
||||
ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n",
|
||||
__FUNCTION__, cdev->dev.bus_id, ch);
|
||||
__func__, cdev->dev.bus_id, ch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (do_debug)
|
||||
ctcm_pr_debug("%s: interrupt for device: %s "
|
||||
"received c-%02x d-%02x\n",
|
||||
dev->name,
|
||||
ch->id,
|
||||
irb->scsw.cmd.cstat,
|
||||
irb->scsw.cmd.dstat);
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
|
||||
"%s(%s): int. for %s: cstat=%02x dstat=%02x",
|
||||
CTCM_FUNTAIL, dev->name, ch->id, cstat, dstat);
|
||||
|
||||
/* Copy interruption response block. */
|
||||
memcpy(ch->irb, irb, sizeof(struct irb));
|
||||
|
||||
/* Check for good subchannel return code, otherwise error message */
|
||||
if (irb->scsw.cmd.cstat) {
|
||||
/* Check for good subchannel return code, otherwise error message */
|
||||
fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch);
|
||||
ctcm_pr_warn("%s: subchannel check for dev: %s - %02x %02x\n",
|
||||
dev->name, ch->id, irb->scsw.cmd.cstat,
|
||||
|
@ -1283,6 +1237,11 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
|
|||
|
||||
/* Check the reason-code of a unit check */
|
||||
if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
|
||||
if ((irb->ecw[0] & ch->sense_rc) == 0)
|
||||
/* print it only once */
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
|
||||
"%s(%s): sense=%02x, ds=%02x",
|
||||
CTCM_FUNTAIL, ch->id, irb->ecw[0], dstat);
|
||||
ccw_unit_check(ch, irb->ecw[0]);
|
||||
return;
|
||||
}
|
||||
|
@ -1320,14 +1279,18 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev)
|
|||
struct ctcm_priv *priv;
|
||||
int rc;
|
||||
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", __FUNCTION__, cgdev);
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"%s %p",
|
||||
__func__, cgdev);
|
||||
|
||||
if (!get_device(&cgdev->dev))
|
||||
return -ENODEV;
|
||||
|
||||
priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
|
||||
"%s: memory allocation failure",
|
||||
CTCM_FUNTAIL);
|
||||
put_device(&cgdev->dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -1364,10 +1327,13 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
|
|||
int ccw_num;
|
||||
int rc = 0;
|
||||
|
||||
CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"%s(%s), type %d, proto %d",
|
||||
__func__, cdev->dev.bus_id, type, priv->protocol);
|
||||
|
||||
ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
|
||||
if (ch == NULL)
|
||||
goto nomem_return;
|
||||
return -ENOMEM;
|
||||
|
||||
ch->protocol = priv->protocol;
|
||||
if (IS_MPC(priv)) {
|
||||
|
@ -1478,7 +1444,7 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
|
|||
if (*c && (!strncmp((*c)->id, ch->id, CTCM_ID_SIZE))) {
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"%s (%s) already in list, using old entry",
|
||||
__FUNCTION__, (*c)->id);
|
||||
__func__, (*c)->id);
|
||||
|
||||
goto free_return;
|
||||
}
|
||||
|
@ -1498,11 +1464,10 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
|
|||
return 0;
|
||||
|
||||
nomem_return:
|
||||
ctcm_pr_warn("ctcm: Out of memory in %s\n", __FUNCTION__);
|
||||
rc = -ENOMEM;
|
||||
|
||||
free_return: /* note that all channel pointers are 0 or valid */
|
||||
kfree(ch->ccw); /* TODO: check that again */
|
||||
kfree(ch->ccw);
|
||||
kfree(ch->discontact_th);
|
||||
kfree_fsm(ch->fsm);
|
||||
kfree(ch->irb);
|
||||
|
@ -1540,48 +1505,48 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
|
|||
enum channel_types type;
|
||||
struct ctcm_priv *priv;
|
||||
struct net_device *dev;
|
||||
struct ccw_device *cdev0;
|
||||
struct ccw_device *cdev1;
|
||||
int ret;
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
|
||||
|
||||
priv = dev_get_drvdata(&cgdev->dev);
|
||||
if (!priv)
|
||||
return -ENODEV;
|
||||
|
||||
type = get_channel_type(&cgdev->cdev[0]->id);
|
||||
cdev0 = cgdev->cdev[0];
|
||||
cdev1 = cgdev->cdev[1];
|
||||
|
||||
snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
|
||||
snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
|
||||
type = get_channel_type(&cdev0->id);
|
||||
|
||||
ret = add_channel(cgdev->cdev[0], type, priv);
|
||||
snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cdev0->dev.bus_id);
|
||||
snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cdev1->dev.bus_id);
|
||||
|
||||
ret = add_channel(cdev0, type, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = add_channel(cgdev->cdev[1], type, priv);
|
||||
ret = add_channel(cdev1, type, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ccw_device_set_online(cgdev->cdev[0]);
|
||||
ret = ccw_device_set_online(cdev0);
|
||||
if (ret != 0) {
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
|
||||
"ccw_device_set_online (cdev[0]) failed ");
|
||||
ctcm_pr_warn("ccw_device_set_online (cdev[0]) failed "
|
||||
"with ret = %d\n", ret);
|
||||
/* may be ok to fail now - can be done later */
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s) set_online rc=%d",
|
||||
CTCM_FUNTAIL, read_id, ret);
|
||||
}
|
||||
|
||||
ret = ccw_device_set_online(cgdev->cdev[1]);
|
||||
ret = ccw_device_set_online(cdev1);
|
||||
if (ret != 0) {
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
|
||||
"ccw_device_set_online (cdev[1]) failed ");
|
||||
ctcm_pr_warn("ccw_device_set_online (cdev[1]) failed "
|
||||
"with ret = %d\n", ret);
|
||||
/* may be ok to fail now - can be done later */
|
||||
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
|
||||
"%s(%s) set_online rc=%d",
|
||||
CTCM_FUNTAIL, write_id, ret);
|
||||
}
|
||||
|
||||
dev = ctcm_init_netdevice(priv);
|
||||
|
||||
if (dev == NULL) {
|
||||
ctcm_pr_warn("ctcm_init_netdevice failed\n");
|
||||
goto out;
|
||||
}
|
||||
if (dev == NULL)
|
||||
goto out;
|
||||
|
||||
for (direction = READ; direction <= WRITE; direction++) {
|
||||
priv->channel[direction] =
|
||||
|
@ -1590,8 +1555,7 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
|
|||
if (priv->channel[direction] == NULL) {
|
||||
if (direction == WRITE)
|
||||
channel_free(priv->channel[READ]);
|
||||
ctcm_free_netdevice(dev);
|
||||
goto out;
|
||||
goto out_dev;
|
||||
}
|
||||
priv->channel[direction]->netdev = dev;
|
||||
priv->channel[direction]->protocol = priv->protocol;
|
||||
|
@ -1600,26 +1564,24 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
|
|||
/* sysfs magic */
|
||||
SET_NETDEV_DEV(dev, &cgdev->dev);
|
||||
|
||||
if (ctcm_netdev_register(dev) != 0) {
|
||||
ctcm_free_netdevice(dev);
|
||||
goto out;
|
||||
}
|
||||
if (register_netdev(dev))
|
||||
goto out_dev;
|
||||
|
||||
if (ctcm_add_attributes(&cgdev->dev)) {
|
||||
ctcm_netdev_unregister(dev);
|
||||
/* dev->priv = NULL; why that ???? */
|
||||
ctcm_free_netdevice(dev);
|
||||
goto out;
|
||||
unregister_netdev(dev);
|
||||
goto out_dev;
|
||||
}
|
||||
|
||||
strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
|
||||
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"setup(%s) ok : r/w = %s / %s, proto : %d",
|
||||
dev->name, priv->channel[READ]->id,
|
||||
"setup(%s) OK : r/w = %s/%s, protocol : %d", dev->name,
|
||||
priv->channel[READ]->id,
|
||||
priv->channel[WRITE]->id, priv->protocol);
|
||||
|
||||
return 0;
|
||||
out_dev:
|
||||
ctcm_free_netdevice(dev);
|
||||
out:
|
||||
ccw_device_set_offline(cgdev->cdev[1]);
|
||||
ccw_device_set_offline(cgdev->cdev[0]);
|
||||
|
@ -1658,8 +1620,7 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
|
|||
channel_free(priv->channel[WRITE]);
|
||||
|
||||
if (dev) {
|
||||
ctcm_netdev_unregister(dev);
|
||||
/* dev->priv = NULL; why that ??? */
|
||||
unregister_netdev(dev);
|
||||
ctcm_free_netdevice(dev);
|
||||
}
|
||||
|
||||
|
@ -1682,13 +1643,16 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
|
|||
|
||||
static void ctcm_remove_device(struct ccwgroup_device *cgdev)
|
||||
{
|
||||
struct ctcm_priv *priv;
|
||||
struct ctcm_priv *priv = dev_get_drvdata(&cgdev->dev);
|
||||
|
||||
CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, __FUNCTION__);
|
||||
BUG_ON(priv == NULL);
|
||||
|
||||
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
|
||||
"removing device %s, r/w = %s/%s, proto : %d",
|
||||
priv->channel[READ]->netdev->name,
|
||||
priv->channel[READ]->id, priv->channel[WRITE]->id,
|
||||
priv->protocol);
|
||||
|
||||
priv = dev_get_drvdata(&cgdev->dev);
|
||||
if (!priv)
|
||||
return;
|
||||
if (cgdev->state == CCWGROUP_ONLINE)
|
||||
ctcm_shutdown_device(cgdev);
|
||||
ctcm_remove_files(&cgdev->dev);
|
||||
|
@ -1748,8 +1712,6 @@ static int __init ctcm_init(void)
|
|||
|
||||
ret = ctcm_register_dbf_views();
|
||||
if (ret) {
|
||||
ctcm_pr_crit("ctcm_init failed with ctcm_register_dbf_views "
|
||||
"rc = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = register_cu3088_discipline(&ctcm_group_driver);
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
|
||||
#define CTC_DRIVER_NAME "ctcm"
|
||||
#define CTC_DEVICE_NAME "ctc"
|
||||
#define CTC_DEVICE_GENE "ctc%d"
|
||||
#define MPC_DEVICE_NAME "mpc"
|
||||
#define MPC_DEVICE_GENE "mpc%d"
|
||||
#define CTC_DEVICE_GENE CTC_DEVICE_NAME "%d"
|
||||
#define MPC_DEVICE_GENE MPC_DEVICE_NAME "%d"
|
||||
|
||||
#define CHANNEL_FLAGS_READ 0
|
||||
#define CHANNEL_FLAGS_WRITE 1
|
||||
|
@ -48,6 +48,30 @@
|
|||
#define ctcm_pr_err(fmt, arg...) printk(KERN_ERR fmt, ##arg)
|
||||
#define ctcm_pr_crit(fmt, arg...) printk(KERN_CRIT fmt, ##arg)
|
||||
|
||||
#define CTCM_PR_DEBUG(fmt, arg...) \
|
||||
do { \
|
||||
if (do_debug) \
|
||||
printk(KERN_DEBUG fmt, ##arg); \
|
||||
} while (0)
|
||||
|
||||
#define CTCM_PR_DBGDATA(fmt, arg...) \
|
||||
do { \
|
||||
if (do_debug_data) \
|
||||
printk(KERN_DEBUG fmt, ##arg); \
|
||||
} while (0)
|
||||
|
||||
#define CTCM_D3_DUMP(buf, len) \
|
||||
do { \
|
||||
if (do_debug_data) \
|
||||
ctcmpc_dumpit(buf, len); \
|
||||
} while (0)
|
||||
|
||||
#define CTCM_CCW_DUMP(buf, len) \
|
||||
do { \
|
||||
if (do_debug_ccw) \
|
||||
ctcmpc_dumpit(buf, len); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* CCW commands, used in this driver.
|
||||
*/
|
||||
|
@ -161,8 +185,9 @@ struct channel {
|
|||
fsm_instance *fsm; /* finite state machine of this channel */
|
||||
struct net_device *netdev; /* corresponding net_device */
|
||||
struct ctcm_profile prof;
|
||||
unsigned char *trans_skb_data;
|
||||
__u8 *trans_skb_data;
|
||||
__u16 logflags;
|
||||
__u8 sense_rc; /* last unit check sense code report control */
|
||||
};
|
||||
|
||||
struct ctcm_priv {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -231,7 +231,7 @@ static inline void ctcmpc_dump32(char *buf, int len)
|
|||
int ctcmpc_open(struct net_device *);
|
||||
void ctcm_ccw_check_rc(struct channel *, int, char *);
|
||||
void mpc_group_ready(unsigned long adev);
|
||||
int mpc_channel_action(struct channel *ch, int direction, int action);
|
||||
void mpc_channel_action(struct channel *ch, int direction, int action);
|
||||
void mpc_action_send_discontact(unsigned long thischan);
|
||||
void mpc_action_discontact(fsm_instance *fi, int event, void *arg);
|
||||
void ctcmpc_bh(unsigned long thischan);
|
||||
|
|
Loading…
Reference in a new issue