123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <linux/slab.h>
- #include <linux/kernel.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/debugfs.h>
- #include <linux/crc-ccitt.h>
- #include <mach/diag_bridge.h>
- #define DRIVER_DESC "USB host diag bridge driver test"
- #define DRIVER_VERSION "1.0"
- #define RD_BUF_SIZE 2048
- #define DIAG_TEST_CONNECTED 0
- struct diag_test_dev {
- char *read_buf;
- struct work_struct read_w;
- unsigned long flags;
- struct diag_bridge_ops ops;
- };
- static struct diag_test_dev *__dev;
- static struct dentry *dent;
- static void
- diag_test_read_complete_cb(void *d, char *buf, size_t size, size_t actual)
- {
- if (actual < 0) {
- pr_err("%s: read complete err\n", __func__);
- return;
- }
- print_hex_dump(KERN_INFO, "to_host:", 0, 1, 1, buf, actual, false);
- }
- static void diag_test_read_work(struct work_struct *w)
- {
- struct diag_test_dev *dev =
- container_of(w, struct diag_test_dev, read_w);
- memset(dev->read_buf, 0, RD_BUF_SIZE);
- diag_bridge_read(dev->read_buf, RD_BUF_SIZE);
- }
- static void
- diag_test_write_complete_cb(void *d, char *buf, size_t size, size_t actual)
- {
- struct diag_test_dev *dev = d;
- if (actual > 0)
- schedule_work(&dev->read_w);
- }
- #if defined(CONFIG_DEBUG_FS)
- #define DEBUG_BUF_SIZE 1024
- static ssize_t send_ping_cmd(struct file *file, const char __user *ubuf,
- size_t count, loff_t *ppos)
- {
- struct diag_test_dev *dev = __dev;
- unsigned char *buf;
- int temp = sizeof(unsigned char) * 4;
- if (!dev)
- return -ENODEV;
- buf = kmalloc(temp, GFP_KERNEL);
- if (!buf) {
- pr_err("%s: unable to allocate mem for ping cmd\n",
- __func__);
- return -ENOMEM;
- }
- /* hdlc encoded ping command */
- buf[0] = 0x0C;
- buf[1] = 0x14;
- buf[2] = 0x3A;
- buf[3] = 0x7E;
- diag_bridge_write(buf, temp);
- return count;
- }
- const struct file_operations diag_test_ping_ops = {
- .write = send_ping_cmd,
- };
- static void diag_test_debug_init(void)
- {
- struct dentry *dfile;
- dent = debugfs_create_dir("diag_test", 0);
- if (IS_ERR(dent))
- return;
- dfile = debugfs_create_file("send_ping", 0444, dent,
- 0, &diag_test_ping_ops);
- if (!dfile || IS_ERR(dfile))
- debugfs_remove(dent);
- }
- #else
- static void diag_test_debug_init(void) { }
- #endif
- static int diag_test_remove(struct platform_device *pdev)
- {
- diag_bridge_close();
- if (dent) {
- debugfs_remove_recursive(dent);
- dent = NULL;
- }
- return 0;
- }
- static int diag_test_probe(struct platform_device *pdev)
- {
- struct diag_test_dev *dev = __dev;
- int ret = 0;
- pr_info("%s:\n", __func__);
- ret = diag_bridge_open(&dev->ops);
- if (ret)
- pr_err("diag open failed: %d", ret);
- diag_test_debug_init();
- return ret;
- }
- static struct platform_driver diag_test = {
- .remove = diag_test_remove,
- .probe = diag_test_probe,
- .driver = {
- .name = "diag_bridge",
- .owner = THIS_MODULE,
- },
- };
- static int __init diag_test_init(void)
- {
- struct diag_test_dev *dev;
- int ret = 0;
- pr_info("%s\n", __func__);
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
- __dev = dev;
- dev->ops.read_complete_cb = diag_test_read_complete_cb;
- dev->ops.write_complete_cb = diag_test_write_complete_cb;
- dev->read_buf = kmalloc(RD_BUF_SIZE, GFP_KERNEL);
- if (!dev->read_buf) {
- pr_err("%s: unable to allocate read buffer\n", __func__);
- kfree(dev);
- return -ENOMEM;
- }
- dev->ops.ctxt = dev;
- INIT_WORK(&dev->read_w, diag_test_read_work);
- ret = platform_driver_register(&diag_test);
- if (ret)
- pr_err("%s: platform driver %s register failed %d\n",
- __func__, diag_test.driver.name, ret);
- return ret;
- }
- static void __exit diag_test_exit(void)
- {
- struct diag_test_dev *dev = __dev;
- pr_info("%s:\n", __func__);
- if (test_bit(DIAG_TEST_CONNECTED, &dev->flags))
- diag_bridge_close();
- kfree(dev->read_buf);
- kfree(dev);
- }
- module_init(diag_test_init);
- module_exit(diag_test_exit);
- MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_VERSION(DRIVER_VERSION);
- MODULE_LICENSE("GPL v2");
|