diff options
Diffstat (limited to 'xpp/xbus-core.c')
-rw-r--r-- | xpp/xbus-core.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c index 5e96147..f7b0a70 100644 --- a/xpp/xbus-core.c +++ b/xpp/xbus-core.c @@ -29,6 +29,9 @@ #include <linux/module.h> #include <linux/errno.h> #include <linux/proc_fs.h> +#ifdef PROTOCOL_DEBUG +#include <linux/ctype.h> +#endif #include <linux/device.h> #include <linux/delay.h> /* for mdelay() to debug */ #include "xpd.h" @@ -44,6 +47,11 @@ static const char rcsid[] = "$Id$"; #define PROC_XBUS_SUMMARY "summary" #define PROC_XBUS_WAITFOR_XPDS "waitfor_xpds" +#ifdef PROTOCOL_DEBUG +#define PROC_XBUS_COMMAND "command" +static int proc_xbus_command_write(struct file *file, const char __user *buffer, unsigned long count, void *data); +#endif + /* Command line parameters */ extern int print_dbg; extern int max_queue_len; @@ -504,6 +512,13 @@ static void xbus_free(xbus_t *xbus) remove_proc_entry(PROC_XBUS_WAITFOR_XPDS, xbus->proc_xbus_dir); xbus->proc_xbus_waitfor_xpds = NULL; } +#ifdef PROTOCOL_DEBUG + if(xbus->proc_xbus_command) { + DBG("Removing proc '%s' for %s\n", PROC_XBUS_COMMAND, xbus->busname); + remove_proc_entry(PROC_XBUS_COMMAND, xbus->proc_xbus_dir); + xbus->proc_xbus_command = NULL; + } +#endif DBG("Removing proc directory %s\n", xbus->busname); remove_proc_entry(xbus->busname, xpp_proc_toplevel); xbus->proc_xbus_dir = NULL; @@ -594,6 +609,17 @@ xbus_t *xbus_new(xbus_ops_t *ops) goto nobus; } xbus->proc_xbus_waitfor_xpds->owner = THIS_MODULE; +#ifdef PROTOCOL_DEBUG + xbus->proc_xbus_command = create_proc_entry(PROC_XBUS_COMMAND, 0200, xbus->proc_xbus_dir); + if (!xbus->proc_xbus_command) { + ERR("Failed to create '%s' proc file for xbus %s\n", PROC_XBUS_COMMAND, xbus->busname); + err = -EIO; + goto nobus; + } + xbus->proc_xbus_command->write_proc = proc_xbus_command_write; + xbus->proc_xbus_command->data = xbus; + xbus->proc_xbus_command->owner = THIS_MODULE; +#endif #endif /* Sanity checks */ if(!ops->packet_send) { @@ -733,6 +759,65 @@ out: } +#ifdef PROTOCOL_DEBUG +static int proc_xbus_command_write(struct file *file, const char __user *buffer, unsigned long count, void *data) +{ + const int NUM_SIZE = 100; + char buf[NUM_SIZE]; + xbus_t *xbus = data; + xpacket_t *pack; + char *p; + byte *pack_contents; + byte *q; + + if(count >= NUM_SIZE) { + ERR("%s: line too long\n", __FUNCTION__); + return -EFBIG; + } + if(copy_from_user(buf, buffer, count)) + return -EINVAL; + buf[count] = '\0'; + pack = xbus->ops->packet_new(xbus, GFP_KERNEL); + if(!pack) + return -ENOMEM; + q = pack_contents = (byte *)&pack->content; + for(p = buf; *p;) { + int val; + char hexdigit[3]; + + while(*p && isspace(*p)) // skip whitespace + p++; + if(!(*p)) + break; + if(!isxdigit(*p)) { + ERR("%s: %s: bad hex value ASCII='0x%X' at position %d\n", + __FUNCTION__, xbus->busname, *p, p - buf); + goto err; + } + hexdigit[0] = *p++; + hexdigit[1] = '\0'; + hexdigit[2] = '\0'; + if(isxdigit(*p)) + hexdigit[1] = *p++; + if(sscanf(hexdigit, "%2X", &val) != 1) { + ERR("%s: %s: bad hex value '%s' at position %d\n", + __FUNCTION__, xbus->busname, hexdigit, p - buf); + goto err; + } + *q++ = val; + // DBG("%s: %s: '%s' val=%d\n", __FUNCTION__, xbus->busname, hexdigit, val); + } + pack->datalen = q - pack_contents - + sizeof(pack->content.opcode) - sizeof(pack->content.addr); + packet_send(xbus, pack); + return count; +err: + xbus->ops->packet_free(xbus, pack); + return -EINVAL; +} +#endif + + static int read_proc_xbuses(char *page, char **start, off_t off, int count, int *eof, void *data) { int len = 0; @@ -840,6 +925,9 @@ int __init xbus_core_init(void) { int ret; +#ifdef PROTOCOL_DEBUG + INFO("FEATURE: %s with PROTOCOL_DEBUG\n", THIS_MODULE->name); +#endif packet_cache = kmem_cache_create("xpp_packets", sizeof(xpacket_t), 0, 0, |