From 5608b8b00fc85c4ad05a57aad46127bf67187dc6 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Mon, 30 Nov 2015 11:51:39 +0100 Subject: [PATCH] facetimehd: add sysfs functions Introduce a new debug sysfs file, which accepts the following commands: ps - show task running in firmware banner - show startup banner get_root - get ROOT object heap - show heap statistics irq - show irq statistics semaphore - show semaphore status wiring - show wiring status get_object_by_name %s - get address for object get_fsm_by_name %s - get address for FSM dump_object %p - show information about object dump_objects - dump all objects (NOTE: will crash firmware) show_objects - show graph about all objects known get_debug_level - get debug level for object set_debug_level - set debug level for object set_debug_level_rec - set debug level recursive for all objects get_fsm_count - get count of FSM's get_fsm_by_index - get fsm address for index get_fsm_debug_level - get debug level for fsm set_fsm_debug_level - set debug level for fsm --- Makefile | 2 +- fthd_drv.c | 13 +++++- fthd_sysfs.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ fthd_sysfs.h | 27 +++++++++++ 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 fthd_sysfs.c create mode 100644 fthd_sysfs.h diff --git a/Makefile b/Makefile index 150a31f..e3d7b86 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -facetimehd-objs := fthd_ddr.o fthd_hw.o fthd_drv.o fthd_ringbuf.o fthd_isp.o fthd_v4l2.o fthd_buffer.o +facetimehd-objs := fthd_ddr.o fthd_hw.o fthd_drv.o fthd_ringbuf.o fthd_isp.o fthd_v4l2.o fthd_buffer.o fthd_sysfs.o obj-m := facetimehd.o KVERSION := $(shell uname -r) diff --git a/fthd_drv.c b/fthd_drv.c index 1bc9ee0..331b6e4 100644 --- a/fthd_drv.c +++ b/fthd_drv.c @@ -34,6 +34,7 @@ #include "fthd_ringbuf.h" #include "fthd_buffer.h" #include "fthd_v4l2.h" +#include "fthd_sysfs.h" static int fthd_pci_reserve_mem(struct fthd_private *dev_priv) { @@ -207,8 +208,11 @@ static void fthd_handle_irq(struct fthd_private *dev_priv, struct fw_channel *ch return; } - if (chan == dev_priv->channel_debug) + if (chan == dev_priv->channel_debug) { + pr_debug("DEBUG channel ready\n"); + wake_up_interruptible(&chan->wq); return; + } while((entry = fthd_channel_ringbuf_receive(dev_priv, chan)) != (u32)-1) { pr_debug("channel %s: message available, address %08x\n", chan->name, FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS)); @@ -330,6 +334,8 @@ static void fthd_pci_remove(struct pci_dev *pdev) if (!dev_priv) goto out; + fthd_sysfs_exit(dev_priv); + fthd_v4l2_unregister(dev_priv); fthd_stop_firmware(dev_priv); @@ -485,7 +491,12 @@ static int fthd_pci_probe(struct pci_dev *pdev, if (ret) goto fail_firmware; + ret = fthd_sysfs_init(dev_priv); + if (ret) + goto fail_v4l2; return 0; +fail_v4l2: + fthd_v4l2_unregister(dev_priv); fail_firmware: fthd_stop_firmware(dev_priv); fail_hw: diff --git a/fthd_sysfs.c b/fthd_sysfs.c new file mode 100644 index 0000000..e73375b --- /dev/null +++ b/fthd_sysfs.c @@ -0,0 +1,125 @@ +/* + * FacetimeHD camera driver + * + * Copyright (C) 2015 Sven Schnelle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fthd_drv.h" +#include "fthd_sysfs.h" +#include "fthd_isp.h" +#include "fthd_ringbuf.h" + +static ssize_t fthd_show_debug(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return -EINVAL; +} + +static ssize_t fthd_store_debug(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fthd_isp_debug_cmd cmd; + struct fthd_private *dev_priv = dev_get_drvdata(dev); + int ret, opcode; + + if (count == 0) + return 0; + + if (count > 64) + return -EINVAL; + + memset(&cmd, 0, sizeof(cmd)); + + if (!strcmp(buf, "ps")) + opcode = CISP_CMD_DEBUG_PS; + else if (!strcmp(buf, "banner")) + opcode = CISP_CMD_DEBUG_BANNER; + else if (!strcmp(buf, "get_root")) + opcode = CISP_CMD_DEBUG_GET_ROOT_HANDLE; + else if (!strcmp(buf, "heap")) + opcode = CISP_CMD_DEBUG_HEAP_STATISTICS; + else if (!strcmp(buf, "irq")) + opcode = CISP_CMD_DEBUG_IRQ_STATISTICS; + else if (!strcmp(buf, "semaphore")) + opcode = CISP_CMD_DEBUG_SHOW_SEMAPHORE_STATUS; + else if (!strcmp(buf, "wiring")) + opcode = CISP_CMD_DEBUG_SHOW_WIRING_OPERATIONS; + else if (sscanf(buf, "get_object_by_name %s", (char *)&cmd.arg) == 1) + opcode = CISP_CMD_DEBUG_GET_OBJECT_BY_NAME; + else if (sscanf(buf, "dump_object %x", &cmd.arg[0]) == 1) + opcode = CISP_CMD_DEBUG_DUMP_OBJECT; + else if (!strcmp(buf, "dump_objects")) + opcode = CISP_CMD_DEBUG_DUMP_ALL_OBJECTS; + else if (!strcmp(buf, "show_objects")) + opcode = CISP_CMD_DEBUG_SHOW_OBJECT_GRAPH; + else if (sscanf(buf, "get_debug_level %i", &cmd.arg[0]) == 1) + opcode = CISP_CMD_DEBUG_GET_DEBUG_LEVEL; + else if (sscanf(buf, "set_debug_level %x %i", &cmd.arg[0], &cmd.arg[1]) == 2) + opcode = CISP_CMD_DEBUG_SET_DEBUG_LEVEL; + else if (sscanf(buf, "set_debug_level_rec %x %i", &cmd.arg[0], &cmd.arg[1]) == 2) + opcode = CISP_CMD_DEBUG_SET_DEBUG_LEVEL_RECURSIVE; + else if (!strcmp(buf, "get_fsm_count")) + opcode = CISP_CMD_DEBUG_GET_FSM_COUNT; + else if (sscanf(buf, "get_fsm_by_name %s", (char *)&cmd.arg[0]) == 1) + opcode = CISP_CMD_DEBUG_GET_FSM_BY_NAME; + else if (sscanf(buf, "get_fsm_by_index %i", &cmd.arg[0]) == 1) + opcode = CISP_CMD_DEBUG_GET_FSM_BY_INDEX; + else if (sscanf(buf, "get_fsm_debug_level %x", &cmd.arg[0]) == 1) + opcode = CISP_CMD_DEBUG_GET_FSM_DEBUG_LEVEL; + else if (sscanf(buf, "set_fsm_debug_level %x", &cmd.arg[0]) == 2) + opcode = CISP_CMD_DEBUG_SET_FSM_DEBUG_LEVEL; + + else if (sscanf(buf, "%i %i\n", &opcode, &cmd.arg[0]) != 2) + return -EINVAL; + cmd.show_errors = 1; + + ret = fthd_isp_debug_cmd(dev_priv, opcode, &cmd, sizeof(cmd), NULL); + if (ret) + return ret; + + return count; +} + +static DEVICE_ATTR(debug, S_IWUSR | S_IRUGO, fthd_show_debug, + fthd_store_debug); + +static struct attribute *fthd_attributes[] = { + &dev_attr_debug.attr, +}; + +static struct attribute_group fthd_attribute_group = { + .attrs = fthd_attributes, +}; + +int fthd_sysfs_init(struct fthd_private *dev_priv) +{ + return sysfs_create_group(&dev_priv->pdev->dev.kobj, &fthd_attribute_group); +} + +void fthd_sysfs_exit(struct fthd_private *dev_priv) +{ + sysfs_remove_group(&dev_priv->pdev->dev.kobj, &fthd_attribute_group); +} diff --git a/fthd_sysfs.h b/fthd_sysfs.h new file mode 100644 index 0000000..392ee04 --- /dev/null +++ b/fthd_sysfs.h @@ -0,0 +1,27 @@ +/* + * Broadcom PCIe 1570 webcam driver + * + * Copyright (C) 2015 Sven Schnelle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation. + * + */ + +#ifndef _FTHD_SYSFS_H +#define _FTHD_SYSFS_H + +struct fthd_private; + +int fthd_sysfs_init(struct fthd_private *priv); +void fthd_sysfs_exit(struct fthd_private *priv); +#endif