linux/drivers/misc/mei/debugfs.c
<<
>>
Prefs
   1/*
   2 *
   3 * Intel Management Engine Interface (Intel MEI) Linux driver
   4 * Copyright (c) 2012-2013, Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 */
  16#include <linux/slab.h>
  17#include <linux/kernel.h>
  18#include <linux/device.h>
  19#include <linux/debugfs.h>
  20#include <linux/pci.h>
  21
  22#include <linux/mei.h>
  23
  24#include "mei_dev.h"
  25#include "hw.h"
  26
  27static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
  28                                        size_t cnt, loff_t *ppos)
  29{
  30        struct mei_device *dev = fp->private_data;
  31        struct mei_me_client *cl;
  32        const size_t bufsz = 1024;
  33        char *buf = kzalloc(bufsz, GFP_KERNEL);
  34        int i;
  35        int pos = 0;
  36        int ret;
  37
  38        if  (!buf)
  39                return -ENOMEM;
  40
  41        pos += scnprintf(buf + pos, bufsz - pos,
  42                        "  |id|addr|         UUID                       |con|msg len|\n");
  43
  44        mutex_lock(&dev->device_lock);
  45
  46        /*  if the driver is not enabled the list won't b consitent */
  47        if (dev->dev_state != MEI_DEV_ENABLED)
  48                goto out;
  49
  50        for (i = 0; i < dev->me_clients_num; i++) {
  51                cl = &dev->me_clients[i];
  52
  53                /* skip me clients that cannot be connected */
  54                if (cl->props.max_number_of_connections == 0)
  55                        continue;
  56
  57                pos += scnprintf(buf + pos, bufsz - pos,
  58                        "%2d|%2d|%4d|%pUl|%3d|%7d|\n",
  59                        i, cl->client_id,
  60                        cl->props.fixed_address,
  61                        &cl->props.protocol_name,
  62                        cl->props.max_number_of_connections,
  63                        cl->props.max_msg_length);
  64        }
  65out:
  66        mutex_unlock(&dev->device_lock);
  67        ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
  68        kfree(buf);
  69        return ret;
  70}
  71
  72static const struct file_operations mei_dbgfs_fops_meclients = {
  73        .open = simple_open,
  74        .read = mei_dbgfs_read_meclients,
  75        .llseek = generic_file_llseek,
  76};
  77
  78static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf,
  79                                        size_t cnt, loff_t *ppos)
  80{
  81        struct mei_device *dev = fp->private_data;
  82        const size_t bufsz = 1024;
  83        char *buf = kzalloc(bufsz, GFP_KERNEL);
  84        int pos = 0;
  85        int ret;
  86
  87        if  (!buf)
  88                return -ENOMEM;
  89
  90        pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
  91                        mei_dev_state_str(dev->dev_state));
  92        ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
  93        kfree(buf);
  94        return ret;
  95}
  96static const struct file_operations mei_dbgfs_fops_devstate = {
  97        .open = simple_open,
  98        .read = mei_dbgfs_read_devstate,
  99        .llseek = generic_file_llseek,
 100};
 101
 102/**
 103 * mei_dbgfs_deregister - Remove the debugfs files and directories
 104 * @mei - pointer to mei device private dat
 105 */
 106void mei_dbgfs_deregister(struct mei_device *dev)
 107{
 108        if (!dev->dbgfs_dir)
 109                return;
 110        debugfs_remove_recursive(dev->dbgfs_dir);
 111        dev->dbgfs_dir = NULL;
 112}
 113
 114/**
 115 * Add the debugfs files
 116 *
 117 */
 118int mei_dbgfs_register(struct mei_device *dev, const char *name)
 119{
 120        struct dentry *dir, *f;
 121        dir = debugfs_create_dir(name, NULL);
 122        if (!dir)
 123                return -ENOMEM;
 124
 125        f = debugfs_create_file("meclients", S_IRUSR, dir,
 126                                dev, &mei_dbgfs_fops_meclients);
 127        if (!f) {
 128                dev_err(&dev->pdev->dev, "meclients: registration failed\n");
 129                goto err;
 130        }
 131        f = debugfs_create_file("devstate", S_IRUSR, dir,
 132                                dev, &mei_dbgfs_fops_devstate);
 133        if (!f) {
 134                dev_err(&dev->pdev->dev, "devstate: registration failed\n");
 135                goto err;
 136        }
 137        dev->dbgfs_dir = dir;
 138        return 0;
 139err:
 140        mei_dbgfs_deregister(dev);
 141        return -ENODEV;
 142}
 143
 144