aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb/uwb-debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/uwb/uwb-debug.c')
-rw-r--r--drivers/uwb/uwb-debug.c151
1 files changed, 95 insertions, 56 deletions
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 6d232c35d07d..4a42993700c1 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (C) 2005-2006 Intel Corporation 5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 10 * modify it under the terms of the GNU General Public License version
@@ -33,31 +34,9 @@
33#include <linux/seq_file.h> 34#include <linux/seq_file.h>
34 35
35#include <linux/uwb/debug-cmd.h> 36#include <linux/uwb/debug-cmd.h>
36#define D_LOCAL 0
37#include <linux/uwb/debug.h>
38 37
39#include "uwb-internal.h" 38#include "uwb-internal.h"
40 39
41void dump_bytes(struct device *dev, const void *_buf, size_t rsize)
42{
43 const char *buf = _buf;
44 char line[32];
45 size_t offset = 0;
46 int cnt, cnt2;
47 for (cnt = 0; cnt < rsize; cnt += 8) {
48 size_t rtop = rsize - cnt < 8 ? rsize - cnt : 8;
49 for (offset = cnt2 = 0; cnt2 < rtop; cnt2++) {
50 offset += scnprintf(line + offset, sizeof(line) - offset,
51 "%02x ", buf[cnt + cnt2] & 0xff);
52 }
53 if (dev)
54 dev_info(dev, "%s\n", line);
55 else
56 printk(KERN_INFO "%s\n", line);
57 }
58}
59EXPORT_SYMBOL_GPL(dump_bytes);
60
61/* 40/*
62 * Debug interface 41 * Debug interface
63 * 42 *
@@ -84,26 +63,23 @@ struct uwb_dbg {
84 struct dentry *reservations_f; 63 struct dentry *reservations_f;
85 struct dentry *accept_f; 64 struct dentry *accept_f;
86 struct dentry *drp_avail_f; 65 struct dentry *drp_avail_f;
66 spinlock_t list_lock;
87}; 67};
88 68
89static struct dentry *root_dir; 69static struct dentry *root_dir;
90 70
91static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv) 71static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv)
92{ 72{
93 struct uwb_rc *rc = rsv->rc; 73 struct uwb_dbg *dbg = rsv->pal_priv;
94 struct device *dev = &rc->uwb_dev.dev;
95 struct uwb_dev_addr devaddr;
96 char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
97
98 uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
99 if (rsv->target.type == UWB_RSV_TARGET_DEV)
100 devaddr = rsv->target.dev->dev_addr;
101 else
102 devaddr = rsv->target.devaddr;
103 uwb_dev_addr_print(target, sizeof(target), &devaddr);
104 74
105 dev_dbg(dev, "debug: rsv %s -> %s: %s\n", 75 uwb_rsv_dump("debug", rsv);
106 owner, target, uwb_rsv_state_str(rsv->state)); 76
77 if (rsv->state == UWB_RSV_STATE_NONE) {
78 spin_lock(&dbg->list_lock);
79 list_del(&rsv->pal_node);
80 spin_unlock(&dbg->list_lock);
81 uwb_rsv_destroy(rsv);
82 }
107} 83}
108 84
109static int cmd_rsv_establish(struct uwb_rc *rc, 85static int cmd_rsv_establish(struct uwb_rc *rc,
@@ -119,26 +95,27 @@ static int cmd_rsv_establish(struct uwb_rc *rc,
119 if (target == NULL) 95 if (target == NULL)
120 return -ENODEV; 96 return -ENODEV;
121 97
122 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, NULL); 98 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, rc->dbg);
123 if (rsv == NULL) { 99 if (rsv == NULL) {
124 uwb_dev_put(target); 100 uwb_dev_put(target);
125 return -ENOMEM; 101 return -ENOMEM;
126 } 102 }
127 103
128 rsv->owner = &rc->uwb_dev; 104 rsv->target.type = UWB_RSV_TARGET_DEV;
129 rsv->target.type = UWB_RSV_TARGET_DEV; 105 rsv->target.dev = target;
130 rsv->target.dev = target; 106 rsv->type = cmd->type;
131 rsv->type = cmd->type; 107 rsv->max_mas = cmd->max_mas;
132 rsv->max_mas = cmd->max_mas; 108 rsv->min_mas = cmd->min_mas;
133 rsv->min_mas = cmd->min_mas; 109 rsv->max_interval = cmd->max_interval;
134 rsv->sparsity = cmd->sparsity;
135 110
136 ret = uwb_rsv_establish(rsv); 111 ret = uwb_rsv_establish(rsv);
137 if (ret) 112 if (ret)
138 uwb_rsv_destroy(rsv); 113 uwb_rsv_destroy(rsv);
139 else 114 else {
115 spin_lock(&(rc->dbg)->list_lock);
140 list_add_tail(&rsv->pal_node, &rc->dbg->rsvs); 116 list_add_tail(&rsv->pal_node, &rc->dbg->rsvs);
141 117 spin_unlock(&(rc->dbg)->list_lock);
118 }
142 return ret; 119 return ret;
143} 120}
144 121
@@ -148,21 +125,40 @@ static int cmd_rsv_terminate(struct uwb_rc *rc,
148 struct uwb_rsv *rsv, *found = NULL; 125 struct uwb_rsv *rsv, *found = NULL;
149 int i = 0; 126 int i = 0;
150 127
128 spin_lock(&(rc->dbg)->list_lock);
129
151 list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) { 130 list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) {
152 if (i == cmd->index) { 131 if (i == cmd->index) {
153 found = rsv; 132 found = rsv;
133 uwb_rsv_get(found);
154 break; 134 break;
155 } 135 }
136 i++;
156 } 137 }
138
139 spin_unlock(&(rc->dbg)->list_lock);
140
157 if (!found) 141 if (!found)
158 return -EINVAL; 142 return -EINVAL;
159 143
160 list_del(&found->pal_node);
161 uwb_rsv_terminate(found); 144 uwb_rsv_terminate(found);
145 uwb_rsv_put(found);
162 146
163 return 0; 147 return 0;
164} 148}
165 149
150static int cmd_ie_add(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_add)
151{
152 return uwb_rc_ie_add(rc,
153 (const struct uwb_ie_hdr *) ie_to_add->data,
154 ie_to_add->len);
155}
156
157static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm)
158{
159 return uwb_rc_ie_rm(rc, ie_to_rm->data[0]);
160}
161
166static int command_open(struct inode *inode, struct file *file) 162static int command_open(struct inode *inode, struct file *file)
167{ 163{
168 file->private_data = inode->i_private; 164 file->private_data = inode->i_private;
@@ -175,8 +171,8 @@ static ssize_t command_write(struct file *file, const char __user *buf,
175{ 171{
176 struct uwb_rc *rc = file->private_data; 172 struct uwb_rc *rc = file->private_data;
177 struct uwb_dbg_cmd cmd; 173 struct uwb_dbg_cmd cmd;
178 int ret; 174 int ret = 0;
179 175
180 if (len != sizeof(struct uwb_dbg_cmd)) 176 if (len != sizeof(struct uwb_dbg_cmd))
181 return -EINVAL; 177 return -EINVAL;
182 178
@@ -190,6 +186,18 @@ static ssize_t command_write(struct file *file, const char __user *buf,
190 case UWB_DBG_CMD_RSV_TERMINATE: 186 case UWB_DBG_CMD_RSV_TERMINATE:
191 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate); 187 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate);
192 break; 188 break;
189 case UWB_DBG_CMD_IE_ADD:
190 ret = cmd_ie_add(rc, &cmd.ie_add);
191 break;
192 case UWB_DBG_CMD_IE_RM:
193 ret = cmd_ie_rm(rc, &cmd.ie_rm);
194 break;
195 case UWB_DBG_CMD_RADIO_START:
196 ret = uwb_radio_start(&rc->dbg->pal);
197 break;
198 case UWB_DBG_CMD_RADIO_STOP:
199 uwb_radio_stop(&rc->dbg->pal);
200 break;
193 default: 201 default:
194 return -EINVAL; 202 return -EINVAL;
195 } 203 }
@@ -283,12 +291,26 @@ static struct file_operations drp_avail_fops = {
283 .owner = THIS_MODULE, 291 .owner = THIS_MODULE,
284}; 292};
285 293
286static void uwb_dbg_new_rsv(struct uwb_rsv *rsv) 294static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel)
295{
296 struct device *dev = &pal->rc->uwb_dev.dev;
297
298 if (channel > 0)
299 dev_info(dev, "debug: channel %d started\n", channel);
300 else
301 dev_info(dev, "debug: channel stopped\n");
302}
303
304static void uwb_dbg_new_rsv(struct uwb_pal *pal, struct uwb_rsv *rsv)
287{ 305{
288 struct uwb_rc *rc = rsv->rc; 306 struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal);
289 307
290 if (rc->dbg->accept) 308 if (dbg->accept) {
291 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, NULL); 309 spin_lock(&dbg->list_lock);
310 list_add_tail(&rsv->pal_node, &dbg->rsvs);
311 spin_unlock(&dbg->list_lock);
312 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, dbg);
313 }
292} 314}
293 315
294/** 316/**
@@ -302,10 +324,14 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
302 return; 324 return;
303 325
304 INIT_LIST_HEAD(&rc->dbg->rsvs); 326 INIT_LIST_HEAD(&rc->dbg->rsvs);
327 spin_lock_init(&(rc->dbg)->list_lock);
305 328
306 uwb_pal_init(&rc->dbg->pal); 329 uwb_pal_init(&rc->dbg->pal);
330 rc->dbg->pal.rc = rc;
331 rc->dbg->pal.channel_changed = uwb_dbg_channel_changed;
307 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; 332 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv;
308 uwb_pal_register(rc, &rc->dbg->pal); 333 uwb_pal_register(&rc->dbg->pal);
334
309 if (root_dir) { 335 if (root_dir) {
310 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), 336 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev),
311 root_dir); 337 root_dir);
@@ -325,7 +351,7 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
325} 351}
326 352
327/** 353/**
328 * uwb_dbg_add_rc - remove a radio controller's debug interface 354 * uwb_dbg_del_rc - remove a radio controller's debug interface
329 * @rc: the radio controller 355 * @rc: the radio controller
330 */ 356 */
331void uwb_dbg_del_rc(struct uwb_rc *rc) 357void uwb_dbg_del_rc(struct uwb_rc *rc)
@@ -336,10 +362,10 @@ void uwb_dbg_del_rc(struct uwb_rc *rc)
336 return; 362 return;
337 363
338 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) { 364 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) {
339 uwb_rsv_destroy(rsv); 365 uwb_rsv_terminate(rsv);
340 } 366 }
341 367
342 uwb_pal_unregister(rc, &rc->dbg->pal); 368 uwb_pal_unregister(&rc->dbg->pal);
343 369
344 if (root_dir) { 370 if (root_dir) {
345 debugfs_remove(rc->dbg->drp_avail_f); 371 debugfs_remove(rc->dbg->drp_avail_f);
@@ -365,3 +391,16 @@ void uwb_dbg_exit(void)
365{ 391{
366 debugfs_remove(root_dir); 392 debugfs_remove(root_dir);
367} 393}
394
395/**
396 * uwb_dbg_create_pal_dir - create a debugfs directory for a PAL
397 * @pal: The PAL.
398 */
399struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal)
400{
401 struct uwb_rc *rc = pal->rc;
402
403 if (root_dir && rc->dbg && rc->dbg->root_d && pal->name)
404 return debugfs_create_dir(pal->name, rc->dbg->root_d);
405 return NULL;
406}