From: Tim Sell <[email protected]>
Add error message to genuine rare error paths, and debug messages
to enable relatively non-verbose tracing of code paths
You can enable debug messages by including this on the kernel command line:
visornic.dyndbg=+p
or by this from the command line:
echo "module visornic +p" > <debugfs>/dynamic_debug/control
Refer to Documentation/dynamic-debug-howto.txt for more details.
In addition to the new debug and error messages, a message like the
following will be logged every time a visornic device is probed, which
will enable you to map back-and-forth between visorbus device names
(e.g., "vbus2:dev0") and netdev names (e.g., "eth0"):
visornic vbus2:dev0: visornic_probe success netdev=eth0
With this patch and visornic debugging enabled, you should expect to see
messages like the following in the most-common scenarios:
* driver loaded:
visornic_init
* device probed:
visornic vbus2:dev0: visornic_probe
visor_thread_start
visor_thread_start success
* network interface configured (ifconfig):
net eth0: visornic_open
net eth0: visornic_enable_with_timeout
net eth0: visornic_enable_with_timeout success
net eth0: visornic_open success
staging: unisys: More comments from Jes
Signed-off-by: Tim Sell <[email protected]>
Signed-off-by: David Kershner <[email protected]>
Signed-off-by: Benjamin Romer <[email protected]>
---
drivers/staging/unisys/visornic/visornic_main.c | 127 ++++++++++++++++++++++--
1 file changed, 116 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/unisys/visornic/visornic_main.c
b/drivers/staging/unisys/visornic/visornic_main.c
index 7100744..7b9821c 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -294,14 +294,18 @@ static int visor_thread_start(struct visor_thread_info
*thrinfo,
int (*threadfn)(void *),
void *thrcontext, char *name)
{
+ pr_debug("%s\n", __func__);
/* used to stop the thread */
init_completion(&thrinfo->has_stopped);
thrinfo->task = kthread_run(threadfn, thrcontext, name);
if (IS_ERR(thrinfo->task)) {
+ pr_debug("%s failed (%ld)\n",
+ __func__, PTR_ERR(thrinfo->task));
thrinfo->id = 0;
return -EINVAL;
}
thrinfo->id = thrinfo->task->pid;
+ pr_debug("%s success\n", __func__);
return 0;
}
@@ -317,10 +321,12 @@ static void visor_thread_stop(struct visor_thread_info
*thrinfo)
if (!thrinfo->id)
return; /* thread not running */
+ pr_debug("%s\n", __func__);
kthread_stop(thrinfo->task);
/* give up if the thread has NOT died in 1 minute */
if (wait_for_completion_timeout(&thrinfo->has_stopped, 60 * HZ))
thrinfo->id = 0;
+ pr_debug("%s success\n", __func__);
}
/* DebugFS code */
@@ -333,6 +339,7 @@ static ssize_t info_debugfs_read(struct file *file, char
__user *buf,
struct visornic_devdata *devdata;
char *vbuf;
+ pr_debug("%s\n", __func__);
if (len > MAX_BUF)
len = MAX_BUF;
vbuf = kzalloc(len, GFP_KERNEL);
@@ -465,6 +472,8 @@ static ssize_t info_debugfs_read(struct file *file, char
__user *buf,
}
bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
kfree(vbuf);
+ pr_debug("%s success %ld\n",
+ __func__, (long)bytes_read);
return bytes_read;
}
@@ -520,6 +529,8 @@ visornic_serverdown_complete(struct work_struct *work)
serverdown_completion);
netdev = devdata->netdev;
+ dev_dbg(&netdev->dev, "%s\n", __func__);
+
/* Stop using datachan */
visor_thread_stop(&devdata->threadinfo);
@@ -547,6 +558,7 @@ visornic_serverdown_complete(struct work_struct *work)
devdata->server_down = true;
devdata->server_change_state = false;
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
}
/**
@@ -560,13 +572,17 @@ visornic_serverdown_complete(struct work_struct *work)
static int
visornic_serverdown(struct visornic_devdata *devdata)
{
+ dev_dbg(&devdata->dev->device, "%s\n", __func__);
if (!devdata->server_down && !devdata->server_change_state) {
devdata->server_change_state = true;
queue_work(visornic_serverdown_workqueue,
&devdata->serverdown_completion);
} else if (devdata->server_change_state) {
+ dev_dbg(&devdata->dev->device, "%s changing state\n",
+ __func__);
return -EINVAL;
}
+ dev_dbg(&devdata->dev->device, "%s success\n", __func__);
return 0;
}
@@ -676,6 +692,8 @@ visornic_disable_with_timeout(struct net_device *netdev,
const int timeout)
unsigned long flags;
int wait = 0;
+ dev_dbg(&netdev->dev, "%s\n", __func__);
+
/* stop the transmit queue so nothing more can be transmitted */
netif_stop_queue(netdev);
@@ -701,6 +719,8 @@ visornic_disable_with_timeout(struct net_device *netdev,
const int timeout)
break;
if (devdata->server_down || devdata->server_change_state) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
+ dev_dbg(&netdev->dev, "%s server went away\n",
+ __func__);
return -EIO;
}
set_current_state(TASK_INTERRUPTIBLE);
@@ -743,6 +763,7 @@ visornic_disable_with_timeout(struct net_device *netdev,
const int timeout)
break;
}
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
return 0;
}
@@ -810,12 +831,17 @@ visornic_enable_with_timeout(struct net_device *netdev,
const int timeout)
unsigned long flags;
int wait = 0;
+ dev_dbg(&netdev->dev, "%s\n", __func__);
+
/* NOTE: the other end automatically unposts the rcv buffers when it
* gets a disable.
*/
i = init_rcv_bufs(netdev, devdata);
- if (i < 0)
+ if (i < 0) {
+ dev_err(&netdev->dev,
+ "%s failed to init rcv bufs (%d)\n", __func__, i);
return i;
+ }
spin_lock_irqsave(&devdata->priv_lock, flags);
devdata->enabled = 1;
@@ -838,6 +864,8 @@ visornic_enable_with_timeout(struct net_device *netdev,
const int timeout)
break;
if (devdata->server_down || devdata->server_change_state) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
+ dev_dbg(&netdev->dev, "%s server went away\n",
+ __func__);
return -EIO;
}
set_current_state(TASK_INTERRUPTIBLE);
@@ -848,8 +876,10 @@ visornic_enable_with_timeout(struct net_device *netdev,
const int timeout)
spin_unlock_irqrestore(&devdata->priv_lock, flags);
- if (!devdata->enab_dis_acked)
+ if (!devdata->enab_dis_acked) {
+ dev_err(&netdev->dev, "%s missing ACK\n", __func__);
return -EIO;
+ }
/* find an open slot in the array to save off VisorNic references
* for debug
@@ -861,6 +891,7 @@ visornic_enable_with_timeout(struct net_device *netdev,
const int timeout)
}
}
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
return 0;
}
@@ -882,6 +913,7 @@ visornic_timeout_reset(struct work_struct *work)
devdata = container_of(work, struct visornic_devdata, timeout_reset);
netdev = devdata->netdev;
+ dev_dbg(&netdev->dev, "%s\n", __func__);
netif_stop_queue(netdev);
response = visornic_disable_with_timeout(netdev, 100);
if (response)
@@ -896,6 +928,7 @@ visornic_timeout_reset(struct work_struct *work)
call_serverdown:
visornic_serverdown(devdata);
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
}
/**
@@ -908,6 +941,7 @@ call_serverdown:
static int
visornic_open(struct net_device *netdev)
{
+ dev_dbg(&netdev->dev, "%s\n", __func__);
visornic_enable_with_timeout(netdev, VISORNIC_INFINITE_RESPONSE_WAIT);
/* start the interface's transmit queue, allowing it to accept
@@ -915,6 +949,7 @@ visornic_open(struct net_device *netdev)
*/
netif_start_queue(netdev);
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
return 0;
}
@@ -928,9 +963,11 @@ visornic_open(struct net_device *netdev)
static int
visornic_close(struct net_device *netdev)
{
+ dev_dbg(&netdev->dev, "%s\n", __func__);
netif_stop_queue(netdev);
visornic_disable_with_timeout(netdev, VISORNIC_INFINITE_RESPONSE_WAIT);
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
return 0;
}
@@ -961,6 +998,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
devdata->server_change_state) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
+ dev_dbg(&netdev->dev,
+ "%s busy - queue stopped\n", __func__);
return NETDEV_TX_BUSY;
}
@@ -979,6 +1018,9 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
if (firstfraglen < ETH_HEADER_SIZE) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
+ dev_err(&netdev->dev,
+ "%s busy - first frag too small (%d)\n",
+ __func__, firstfraglen);
return NETDEV_TX_BUSY;
}
@@ -1018,6 +1060,9 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
netif_stop_queue(netdev);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
+ dev_dbg(&netdev->dev,
+ "%s busy - waiting for iovm to catch up\n",
+ __func__);
return NETDEV_TX_BUSY;
}
if (devdata->queuefullmsg_logged)
@@ -1058,6 +1103,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
if (cmdrsp->net.xmt.num_frags == -1) {
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
+ dev_err(&netdev->dev,
+ "%s busy - copy frags failed\n", __func__);
return NETDEV_TX_BUSY;
}
@@ -1066,6 +1113,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
netif_stop_queue(netdev);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
+ dev_dbg(&netdev->dev,
+ "%s busy - signalinsert failed\n", __func__);
return NETDEV_TX_BUSY;
}
@@ -1098,6 +1147,9 @@ visornic_xmit(struct sk_buff *skb, struct net_device
*netdev)
* netif_wake_queue() after lower
* threshold
*/
+ dev_dbg(&netdev->dev,
+ "%s busy - invoking iovm flow control\n",
+ __func__);
devdata->flow_control_upper_hits++;
}
spin_unlock_irqrestore(&devdata->priv_lock, flags);
@@ -1200,16 +1252,20 @@ visornic_xmit_timeout(struct net_device *netdev)
struct visornic_devdata *devdata = netdev_priv(netdev);
unsigned long flags;
+ dev_dbg(&netdev->dev, "%s\n", __func__);
spin_lock_irqsave(&devdata->priv_lock, flags);
/* Ensure that a ServerDown message hasn't been received */
if (!devdata->enabled ||
(devdata->server_down && !devdata->server_change_state)) {
+ dev_dbg(&netdev->dev, "%s no processing\n",
+ __func__);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
return;
}
spin_unlock_irqrestore(&devdata->priv_lock, flags);
queue_work(visornic_timeout_reset_workqueue, &devdata->timeout_reset);
+ dev_dbg(&netdev->dev, "%s success\n", __func__);
}
/**
@@ -1800,9 +1856,13 @@ static int visornic_probe(struct visor_device *dev)
int channel_offset = 0;
u64 features;
+ dev_dbg(&dev->device, "%s\n", __func__);
netdev = alloc_etherdev(sizeof(struct visornic_devdata));
- if (!netdev)
+ if (!netdev) {
+ dev_err(&dev->device,
+ "%s alloc_etherdev failed\n", __func__);
return -ENOMEM;
+ }
netdev->netdev_ops = &visornic_dev_ops;
netdev->watchdog_timeo = (5 * HZ);
@@ -1814,11 +1874,17 @@ static int visornic_probe(struct visor_device *dev)
vnic.macaddr);
err = visorbus_read_channel(dev, channel_offset, netdev->dev_addr,
ETH_ALEN);
- if (err < 0)
+ if (err < 0) {
+ dev_err(&dev->device,
+ "%s failed to get mac addr from chan (%d)\n",
+ __func__, err);
goto cleanup_netdev;
+ }
devdata = devdata_initialize(netdev_priv(netdev), dev);
if (!devdata) {
+ dev_err(&dev->device,
+ "%s devdata_initialize failed\n", __func__);
err = -ENOMEM;
goto cleanup_netdev;
}
@@ -1834,8 +1900,12 @@ static int visornic_probe(struct visor_device *dev)
vnic.num_rcv_bufs);
err = visorbus_read_channel(dev, channel_offset,
&devdata->num_rcv_bufs, 4);
- if (err)
+ if (err) {
+ dev_err(&dev->device,
+ "%s failed to get #rcv bufs from chan (%d)\n",
+ __func__, err);
goto cleanup_netdev;
+ }
devdata->rcvbuf = kmalloc(sizeof(struct sk_buff *) *
devdata->num_rcv_bufs, GFP_KERNEL);
@@ -1876,38 +1946,58 @@ static int visornic_probe(struct visor_device *dev)
channel_offset = offsetof(struct spar_io_channel_protocol,
vnic.mtu);
err = visorbus_read_channel(dev, channel_offset, &netdev->mtu, 4);
- if (err)
+ if (err) {
+ dev_err(&dev->device,
+ "%s failed to get mtu from chan (%d)\n",
+ __func__, err);
goto cleanup_xmit_cmdrsp;
+ }
/* TODO: Setup Interrupt information */
/* Let's start our threads to get responses */
channel_offset = offsetof(struct spar_io_channel_protocol,
channel_header.features);
err = visorbus_read_channel(dev, channel_offset, &features, 8);
- if (err)
+ if (err) {
+ dev_err(&dev->device,
+ "%s failed to get features from chan (%d)\n",
+ __func__, err);
goto cleanup_xmit_cmdrsp;
+ }
features |= ULTRA_IO_CHANNEL_IS_POLLING;
err = visorbus_write_channel(dev, channel_offset, &features, 8);
- if (err)
+ if (err) {
+ dev_err(&dev->device,
+ "%s failed to set features in chan (%d)\n",
+ __func__, err);
goto cleanup_xmit_cmdrsp;
+ }
devdata->thread_wait_ms = 2;
visor_thread_start(&devdata->threadinfo, process_incoming_rsps,
devdata, "vnic_incoming");
err = register_netdev(netdev);
- if (err)
+ if (err) {
+ dev_err(&dev->device,
+ "%s register_netdev failed (%d)\n", __func__, err);
goto cleanup_thread_stop;
+ }
/* create debgug/sysfs directories */
devdata->eth_debugfs_dir = debugfs_create_dir(netdev->name,
visornic_debugfs_dir);
if (!devdata->eth_debugfs_dir) {
+ dev_err(&dev->device,
+ "%s debugfs_create_dir %s failed\n",
+ __func__, netdev->name);
err = -ENOMEM;
goto cleanup_thread_stop;
}
+ dev_info(&dev->device, "%s success netdev=%s\n",
+ __func__, netdev->name);
return 0;
cleanup_thread_stop:
@@ -1955,8 +2045,11 @@ static void visornic_remove(struct visor_device *dev)
{
struct visornic_devdata *devdata = dev_get_drvdata(&dev->device);
- if (!devdata)
+ if (!devdata) {
+ dev_err(&dev->device, "%s no devdata\n", __func__);
return;
+ }
+ dev_dbg(&dev->device, "%s\n", __func__);
dev_set_drvdata(&dev->device, NULL);
host_side_disappeared(devdata);
kref_put(&devdata->kref, devdata_release);
@@ -1980,8 +2073,10 @@ static int visornic_pause(struct visor_device *dev,
{
struct visornic_devdata *devdata = dev_get_drvdata(&dev->device);
+ dev_dbg(&dev->device, "%s\n", __func__);
visornic_serverdown(devdata);
complete_func(dev, 0);
+ dev_dbg(&dev->device, "%s success\n", __func__);
return 0;
}
@@ -2003,10 +2098,13 @@ static int visornic_resume(struct visor_device *dev,
unsigned long flags;
devdata = dev_get_drvdata(&dev->device);
- if (!devdata)
+ if (!devdata) {
+ dev_err(&dev->device, "%s no devdata\n", __func__);
return -EINVAL;
+ }
netdev = devdata->netdev;
+ dev_dbg(&dev->device, "%s\n", __func__);
if (devdata->server_down && !devdata->server_change_state) {
devdata->server_change_state = true;
@@ -2032,10 +2130,13 @@ static int visornic_resume(struct visor_device *dev,
*/
send_enbdis(netdev, 1, devdata);
} else if (devdata->server_change_state) {
+ dev_err(&dev->device, "%s server_change_state\n",
+ __func__);
return -EIO;
}
complete_func(dev, 0);
+ dev_dbg(&dev->device, "%s success\n", __func__);
return 0;
}
@@ -2051,6 +2152,8 @@ static int visornic_init(void)
struct dentry *ret;
int err = -ENOMEM;
+ pr_debug("%s\n", __func__);
+
/* create workqueue for serverdown completion */
visornic_serverdown_workqueue =
create_singlethread_workqueue("visornic_serverdown");
@@ -2116,6 +2219,8 @@ cleanup_debugfs:
*/
static void visornic_cleanup(void)
{
+ pr_debug("%s\n", __func__);
+
if (visornic_serverdown_workqueue) {
flush_workqueue(visornic_serverdown_workqueue);
destroy_workqueue(visornic_serverdown_workqueue);
--
2.1.4
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel