Merge tag 'linux-kselftest-4.9-rc1-update' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 22:17:12 +0000 (15:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 22:17:12 +0000 (15:17 -0700)
Pull kselftest updates from Shuah Khan:
 "This update consists of:

   - Fixes and improvements to existing tests

   - Moving code from Documentation to selftests, samples, and tools:

     * Moves dnotify_test, prctl, ptp, vDSO, ia64, watchdog, and
       networking tests from Documentation to selftests.

     * Moves mic/mpssd, misc-devices/mei, timers, watchdog, auxdisplay,
       and blackfin examples from Documentation to samples.

     * Moves accounting, laptops/dslm, and pcmcia/crc32hash tools from
       Documentation to tools.

     * Deletes BUILD_DOCSRC and its dependencies"

* tag 'linux-kselftest-4.9-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (21 commits)
  selftests/futex: Check ANSI terminal color support
  Doc: update 00-INDEX files to reflect the runnable code move
  samples: move blackfin gptimers-example from Documentation
  tools: move pcmcia crc32hash tool from Documentation
  tools: move laptops dslm tool from Documentation
  tools: move accounting tool from Documentation
  samples: move auxdisplay example code from Documentation
  samples: move watchdog example code from Documentation
  samples: move timers example code from Documentation
  samples: move misc-devices/mei example code from Documentation
  samples: move mic/mpssd example code from Documentation
  selftests: Move networking/timestamping from Documentation
  selftests: move watchdog tests from Documentation/watchdog
  selftests: move ia64 tests from Documentation/ia64
  selftests: move vDSO tests from Documentation/vDSO
  selftests: move ptp tests from Documentation/ptp
  selftests: move prctl tests from Documentation/prctl
  selftests: move dnotify_test from Documentation/filesystems
  selftests/timers: Add missing error code assignment before test
  selftests/zram: replace ZRAM_LZ4_COMPRESS
  ...

147 files changed:
Documentation/00-INDEX
Documentation/Makefile
Documentation/accounting/.gitignore [deleted file]
Documentation/accounting/Makefile [deleted file]
Documentation/accounting/delay-accounting.txt
Documentation/accounting/getdelays.c [deleted file]
Documentation/arm/00-INDEX
Documentation/auxdisplay/.gitignore [deleted file]
Documentation/auxdisplay/Makefile [deleted file]
Documentation/auxdisplay/cfag12864b
Documentation/auxdisplay/cfag12864b-example.c [deleted file]
Documentation/blackfin/00-INDEX
Documentation/blackfin/Makefile [deleted file]
Documentation/blackfin/gptimers-example.c [deleted file]
Documentation/filesystems/.gitignore [deleted file]
Documentation/filesystems/00-INDEX
Documentation/filesystems/Makefile [deleted file]
Documentation/filesystems/dnotify_test.c [deleted file]
Documentation/ia64/.gitignore [deleted file]
Documentation/ia64/Makefile [deleted file]
Documentation/ia64/aliasing-test.c [deleted file]
Documentation/kselftest.txt
Documentation/laptops/.gitignore [deleted file]
Documentation/laptops/00-INDEX
Documentation/laptops/Makefile [deleted file]
Documentation/laptops/dslm.c [deleted file]
Documentation/laptops/laptop-mode.txt
Documentation/mic/Makefile [deleted file]
Documentation/mic/mpssd/.gitignore [deleted file]
Documentation/mic/mpssd/Makefile [deleted file]
Documentation/mic/mpssd/micctrl [deleted file]
Documentation/mic/mpssd/mpss [deleted file]
Documentation/mic/mpssd/mpssd.c [deleted file]
Documentation/mic/mpssd/mpssd.h [deleted file]
Documentation/mic/mpssd/sysfs.c [deleted file]
Documentation/misc-devices/Makefile [deleted file]
Documentation/misc-devices/mei/.gitignore [deleted file]
Documentation/misc-devices/mei/Makefile [deleted file]
Documentation/misc-devices/mei/TODO [deleted file]
Documentation/misc-devices/mei/mei-amt-version.c [deleted file]
Documentation/networking/00-INDEX
Documentation/networking/Makefile [deleted file]
Documentation/networking/timestamping/.gitignore [deleted file]
Documentation/networking/timestamping/Makefile [deleted file]
Documentation/networking/timestamping/hwtstamp_config.c [deleted file]
Documentation/networking/timestamping/timestamping.c [deleted file]
Documentation/networking/timestamping/txtimestamp.c [deleted file]
Documentation/pcmcia/.gitignore [deleted file]
Documentation/pcmcia/Makefile [deleted file]
Documentation/pcmcia/crc32hash.c [deleted file]
Documentation/pcmcia/devicetable.txt
Documentation/prctl/.gitignore [deleted file]
Documentation/prctl/Makefile [deleted file]
Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c [deleted file]
Documentation/prctl/disable-tsc-on-off-stress-test.c [deleted file]
Documentation/prctl/disable-tsc-test.c [deleted file]
Documentation/ptp/.gitignore [deleted file]
Documentation/ptp/Makefile [deleted file]
Documentation/ptp/testptp.c [deleted file]
Documentation/ptp/testptp.mk [deleted file]
Documentation/spi/00-INDEX
Documentation/timers/.gitignore [deleted file]
Documentation/timers/00-INDEX
Documentation/timers/Makefile [deleted file]
Documentation/timers/hpet.txt
Documentation/timers/hpet_example.c [deleted file]
Documentation/vDSO/.gitignore [deleted file]
Documentation/vDSO/Makefile [deleted file]
Documentation/vDSO/parse_vdso.c [deleted file]
Documentation/vDSO/vdso_standalone_test_x86.c [deleted file]
Documentation/vDSO/vdso_test.c [deleted file]
Documentation/watchdog/Makefile [deleted file]
Documentation/watchdog/src/.gitignore [deleted file]
Documentation/watchdog/src/Makefile [deleted file]
Documentation/watchdog/src/watchdog-simple.c [deleted file]
Documentation/watchdog/src/watchdog-test.c [deleted file]
Documentation/watchdog/watchdog-api.txt
Documentation/watchdog/wdt.txt
MAINTAINERS
Makefile
drivers/media/v4l2-core/Kconfig
lib/Kconfig.debug
samples/Kconfig
samples/Makefile
samples/auxdisplay/.gitignore [new file with mode: 0644]
samples/auxdisplay/Makefile [new file with mode: 0644]
samples/auxdisplay/cfag12864b-example.c [new file with mode: 0644]
samples/blackfin/Makefile [new file with mode: 0644]
samples/blackfin/gptimers-example.c [new file with mode: 0644]
samples/mei/.gitignore [new file with mode: 0644]
samples/mei/Makefile [new file with mode: 0644]
samples/mei/TODO [new file with mode: 0644]
samples/mei/mei-amt-version.c [new file with mode: 0644]
samples/mic/mpssd/.gitignore [new file with mode: 0644]
samples/mic/mpssd/Makefile [new file with mode: 0644]
samples/mic/mpssd/micctrl [new file with mode: 0755]
samples/mic/mpssd/mpss [new file with mode: 0755]
samples/mic/mpssd/mpssd.c [new file with mode: 0644]
samples/mic/mpssd/mpssd.h [new file with mode: 0644]
samples/mic/mpssd/sysfs.c [new file with mode: 0644]
samples/timers/.gitignore [new file with mode: 0644]
samples/timers/Makefile [new file with mode: 0644]
samples/timers/hpet_example.c [new file with mode: 0644]
samples/watchdog/.gitignore [new file with mode: 0644]
samples/watchdog/Makefile [new file with mode: 0644]
samples/watchdog/watchdog-simple.c [new file with mode: 0644]
tools/accounting/.gitignore [new file with mode: 0644]
tools/accounting/Makefile [new file with mode: 0644]
tools/accounting/getdelays.c [new file with mode: 0644]
tools/laptop/dslm/.gitignore [new file with mode: 0644]
tools/laptop/dslm/Makefile [new file with mode: 0644]
tools/laptop/dslm/dslm.c [new file with mode: 0644]
tools/pcmcia/.gitignore [new file with mode: 0644]
tools/pcmcia/Makefile [new file with mode: 0644]
tools/pcmcia/crc32hash.c [new file with mode: 0644]
tools/testing/selftests/filesystems/.gitignore [new file with mode: 0644]
tools/testing/selftests/filesystems/Makefile [new file with mode: 0644]
tools/testing/selftests/filesystems/dnotify_test.c [new file with mode: 0644]
tools/testing/selftests/futex/functional/run.sh
tools/testing/selftests/futex/run.sh
tools/testing/selftests/ia64/.gitignore [new file with mode: 0644]
tools/testing/selftests/ia64/Makefile [new file with mode: 0644]
tools/testing/selftests/ia64/aliasing-test.c [new file with mode: 0644]
tools/testing/selftests/networking/timestamping/.gitignore [new file with mode: 0644]
tools/testing/selftests/networking/timestamping/Makefile [new file with mode: 0644]
tools/testing/selftests/networking/timestamping/hwtstamp_config.c [new file with mode: 0644]
tools/testing/selftests/networking/timestamping/timestamping.c [new file with mode: 0644]
tools/testing/selftests/networking/timestamping/txtimestamp.c [new file with mode: 0644]
tools/testing/selftests/prctl/.gitignore [new file with mode: 0644]
tools/testing/selftests/prctl/Makefile [new file with mode: 0644]
tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c [new file with mode: 0644]
tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c [new file with mode: 0644]
tools/testing/selftests/prctl/disable-tsc-test.c [new file with mode: 0644]
tools/testing/selftests/ptp/.gitignore [new file with mode: 0644]
tools/testing/selftests/ptp/Makefile [new file with mode: 0644]
tools/testing/selftests/ptp/testptp.c [new file with mode: 0644]
tools/testing/selftests/ptp/testptp.mk [new file with mode: 0644]
tools/testing/selftests/timers/posix_timers.c
tools/testing/selftests/vDSO/.gitignore [new file with mode: 0644]
tools/testing/selftests/vDSO/Makefile [new file with mode: 0644]
tools/testing/selftests/vDSO/parse_vdso.c [new file with mode: 0644]
tools/testing/selftests/vDSO/vdso_standalone_test_x86.c [new file with mode: 0644]
tools/testing/selftests/vDSO/vdso_test.c [new file with mode: 0644]
tools/testing/selftests/watchdog/.gitignore [new file with mode: 0644]
tools/testing/selftests/watchdog/Makefile [new file with mode: 0644]
tools/testing/selftests/watchdog/watchdog-test.c [new file with mode: 0644]
tools/testing/selftests/zram/README

index cb9a6c6..3acc4f1 100644 (file)
@@ -46,7 +46,8 @@ IRQ.txt
 Intel-IOMMU.txt
        - basic info on the Intel IOMMU virtualization support.
 Makefile
-       - some files in Documentation dir are actually sample code to build
+       - This file does nothing. Removing it breaks make htmldocs and
+         make distclean.
 ManagementStyle
        - how to (attempt to) manage kernel hackers.
 RCU/
index de955e1..c2a4691 100644 (file)
@@ -1,3 +1 @@
-subdir-y := accounting auxdisplay blackfin \
-       filesystems filesystems ia64 laptops mic misc-devices \
-       networking pcmcia prctl ptp timers vDSO watchdog
+subdir-y :=
diff --git a/Documentation/accounting/.gitignore b/Documentation/accounting/.gitignore
deleted file mode 100644 (file)
index 8648520..0000000
+++ /dev/null
@@ -1 +0,0 @@
-getdelays
diff --git a/Documentation/accounting/Makefile b/Documentation/accounting/Makefile
deleted file mode 100644 (file)
index 7e232cb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# List of programs to build
-hostprogs-y := getdelays
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_getdelays.o += -I$(objtree)/usr/include
index 8a12f07..042ea59 100644 (file)
@@ -54,9 +54,9 @@ are sent to userspace without requiring a command. If it is the last exiting
 task of a thread group, the per-tgid statistics are also sent. More details
 are given in the taskstats interface description.
 
-The getdelays.c userspace utility in this directory allows simple commands to
-be run and the corresponding delay statistics to be displayed. It also serves
-as an example of using the taskstats interface.
+The getdelays.c userspace utility in tools/accounting directory allows simple
+commands to be run and the corresponding delay statistics to be displayed. It
+also serves as an example of using the taskstats interface.
 
 Usage
 -----
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
deleted file mode 100644 (file)
index b5ca536..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-/* getdelays.c
- *
- * Utility to get per-pid and per-tgid delay accounting statistics
- * Also illustrates usage of the taskstats interface
- *
- * Copyright (C) Shailabh Nagar, IBM Corp. 2005
- * Copyright (C) Balbir Singh, IBM Corp. 2006
- * Copyright (c) Jay Lan, SGI. 2006
- *
- * Compile with
- *     gcc -I/usr/src/linux/include getdelays.c -o getdelays
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <poll.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <signal.h>
-
-#include <linux/genetlink.h>
-#include <linux/taskstats.h>
-#include <linux/cgroupstats.h>
-
-/*
- * Generic macros for dealing with netlink sockets. Might be duplicated
- * elsewhere. It is recommended that commercial grade applications use
- * libnl or libnetlink and use the interfaces provided by the library
- */
-#define GENLMSG_DATA(glh)      ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
-#define GENLMSG_PAYLOAD(glh)   (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
-#define NLA_DATA(na)           ((void *)((char*)(na) + NLA_HDRLEN))
-#define NLA_PAYLOAD(len)       (len - NLA_HDRLEN)
-
-#define err(code, fmt, arg...)                 \
-       do {                                    \
-               fprintf(stderr, fmt, ##arg);    \
-               exit(code);                     \
-       } while (0)
-
-int done;
-int rcvbufsz;
-char name[100];
-int dbg;
-int print_delays;
-int print_io_accounting;
-int print_task_context_switch_counts;
-
-#define PRINTF(fmt, arg...) {                  \
-           if (dbg) {                          \
-               printf(fmt, ##arg);             \
-           }                                   \
-       }
-
-/* Maximum size of response requested or message sent */
-#define MAX_MSG_SIZE   1024
-/* Maximum number of cpus expected to be specified in a cpumask */
-#define MAX_CPUS       32
-
-struct msgtemplate {
-       struct nlmsghdr n;
-       struct genlmsghdr g;
-       char buf[MAX_MSG_SIZE];
-};
-
-char cpumask[100+6*MAX_CPUS];
-
-static void usage(void)
-{
-       fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] "
-                       "[-m cpumask] [-t tgid] [-p pid]\n");
-       fprintf(stderr, "  -d: print delayacct stats\n");
-       fprintf(stderr, "  -i: print IO accounting (works only with -p)\n");
-       fprintf(stderr, "  -l: listen forever\n");
-       fprintf(stderr, "  -v: debug on\n");
-       fprintf(stderr, "  -C: container path\n");
-}
-
-/*
- * Create a raw netlink socket and bind
- */
-static int create_nl_socket(int protocol)
-{
-       int fd;
-       struct sockaddr_nl local;
-
-       fd = socket(AF_NETLINK, SOCK_RAW, protocol);
-       if (fd < 0)
-               return -1;
-
-       if (rcvbufsz)
-               if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
-                               &rcvbufsz, sizeof(rcvbufsz)) < 0) {
-                       fprintf(stderr, "Unable to set socket rcv buf size to %d\n",
-                               rcvbufsz);
-                       goto error;
-               }
-
-       memset(&local, 0, sizeof(local));
-       local.nl_family = AF_NETLINK;
-
-       if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
-               goto error;
-
-       return fd;
-error:
-       close(fd);
-       return -1;
-}
-
-
-static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
-            __u8 genl_cmd, __u16 nla_type,
-            void *nla_data, int nla_len)
-{
-       struct nlattr *na;
-       struct sockaddr_nl nladdr;
-       int r, buflen;
-       char *buf;
-
-       struct msgtemplate msg;
-
-       msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
-       msg.n.nlmsg_type = nlmsg_type;
-       msg.n.nlmsg_flags = NLM_F_REQUEST;
-       msg.n.nlmsg_seq = 0;
-       msg.n.nlmsg_pid = nlmsg_pid;
-       msg.g.cmd = genl_cmd;
-       msg.g.version = 0x1;
-       na = (struct nlattr *) GENLMSG_DATA(&msg);
-       na->nla_type = nla_type;
-       na->nla_len = nla_len + 1 + NLA_HDRLEN;
-       memcpy(NLA_DATA(na), nla_data, nla_len);
-       msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
-
-       buf = (char *) &msg;
-       buflen = msg.n.nlmsg_len ;
-       memset(&nladdr, 0, sizeof(nladdr));
-       nladdr.nl_family = AF_NETLINK;
-       while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
-                          sizeof(nladdr))) < buflen) {
-               if (r > 0) {
-                       buf += r;
-                       buflen -= r;
-               } else if (errno != EAGAIN)
-                       return -1;
-       }
-       return 0;
-}
-
-
-/*
- * Probe the controller in genetlink to find the family id
- * for the TASKSTATS family
- */
-static int get_family_id(int sd)
-{
-       struct {
-               struct nlmsghdr n;
-               struct genlmsghdr g;
-               char buf[256];
-       } ans;
-
-       int id = 0, rc;
-       struct nlattr *na;
-       int rep_len;
-
-       strcpy(name, TASKSTATS_GENL_NAME);
-       rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
-                       CTRL_ATTR_FAMILY_NAME, (void *)name,
-                       strlen(TASKSTATS_GENL_NAME)+1);
-       if (rc < 0)
-               return 0;       /* sendto() failure? */
-
-       rep_len = recv(sd, &ans, sizeof(ans), 0);
-       if (ans.n.nlmsg_type == NLMSG_ERROR ||
-           (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
-               return 0;
-
-       na = (struct nlattr *) GENLMSG_DATA(&ans);
-       na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
-       if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
-               id = *(__u16 *) NLA_DATA(na);
-       }
-       return id;
-}
-
-#define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
-
-static void print_delayacct(struct taskstats *t)
-{
-       printf("\n\nCPU   %15s%15s%15s%15s%15s\n"
-              "      %15llu%15llu%15llu%15llu%15.3fms\n"
-              "IO    %15s%15s%15s\n"
-              "      %15llu%15llu%15llums\n"
-              "SWAP  %15s%15s%15s\n"
-              "      %15llu%15llu%15llums\n"
-              "RECLAIM  %12s%15s%15s\n"
-              "      %15llu%15llu%15llums\n",
-              "count", "real total", "virtual total",
-              "delay total", "delay average",
-              (unsigned long long)t->cpu_count,
-              (unsigned long long)t->cpu_run_real_total,
-              (unsigned long long)t->cpu_run_virtual_total,
-              (unsigned long long)t->cpu_delay_total,
-              average_ms((double)t->cpu_delay_total, t->cpu_count),
-              "count", "delay total", "delay average",
-              (unsigned long long)t->blkio_count,
-              (unsigned long long)t->blkio_delay_total,
-              average_ms(t->blkio_delay_total, t->blkio_count),
-              "count", "delay total", "delay average",
-              (unsigned long long)t->swapin_count,
-              (unsigned long long)t->swapin_delay_total,
-              average_ms(t->swapin_delay_total, t->swapin_count),
-              "count", "delay total", "delay average",
-              (unsigned long long)t->freepages_count,
-              (unsigned long long)t->freepages_delay_total,
-              average_ms(t->freepages_delay_total, t->freepages_count));
-}
-
-static void task_context_switch_counts(struct taskstats *t)
-{
-       printf("\n\nTask   %15s%15s\n"
-              "       %15llu%15llu\n",
-              "voluntary", "nonvoluntary",
-              (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw);
-}
-
-static void print_cgroupstats(struct cgroupstats *c)
-{
-       printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, "
-               "uninterruptible %llu\n", (unsigned long long)c->nr_sleeping,
-               (unsigned long long)c->nr_io_wait,
-               (unsigned long long)c->nr_running,
-               (unsigned long long)c->nr_stopped,
-               (unsigned long long)c->nr_uninterruptible);
-}
-
-
-static void print_ioacct(struct taskstats *t)
-{
-       printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
-               t->ac_comm,
-               (unsigned long long)t->read_bytes,
-               (unsigned long long)t->write_bytes,
-               (unsigned long long)t->cancelled_write_bytes);
-}
-
-int main(int argc, char *argv[])
-{
-       int c, rc, rep_len, aggr_len, len2;
-       int cmd_type = TASKSTATS_CMD_ATTR_UNSPEC;
-       __u16 id;
-       __u32 mypid;
-
-       struct nlattr *na;
-       int nl_sd = -1;
-       int len = 0;
-       pid_t tid = 0;
-       pid_t rtid = 0;
-
-       int fd = 0;
-       int count = 0;
-       int write_file = 0;
-       int maskset = 0;
-       char *logfile = NULL;
-       int loop = 0;
-       int containerset = 0;
-       char *containerpath = NULL;
-       int cfd = 0;
-       int forking = 0;
-       sigset_t sigset;
-
-       struct msgtemplate msg;
-
-       while (!forking) {
-               c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:");
-               if (c < 0)
-                       break;
-
-               switch (c) {
-               case 'd':
-                       printf("print delayacct stats ON\n");
-                       print_delays = 1;
-                       break;
-               case 'i':
-                       printf("printing IO accounting\n");
-                       print_io_accounting = 1;
-                       break;
-               case 'q':
-                       printf("printing task/process context switch rates\n");
-                       print_task_context_switch_counts = 1;
-                       break;
-               case 'C':
-                       containerset = 1;
-                       containerpath = optarg;
-                       break;
-               case 'w':
-                       logfile = strdup(optarg);
-                       printf("write to file %s\n", logfile);
-                       write_file = 1;
-                       break;
-               case 'r':
-                       rcvbufsz = atoi(optarg);
-                       printf("receive buf size %d\n", rcvbufsz);
-                       if (rcvbufsz < 0)
-                               err(1, "Invalid rcv buf size\n");
-                       break;
-               case 'm':
-                       strncpy(cpumask, optarg, sizeof(cpumask));
-                       cpumask[sizeof(cpumask) - 1] = '\0';
-                       maskset = 1;
-                       printf("cpumask %s maskset %d\n", cpumask, maskset);
-                       break;
-               case 't':
-                       tid = atoi(optarg);
-                       if (!tid)
-                               err(1, "Invalid tgid\n");
-                       cmd_type = TASKSTATS_CMD_ATTR_TGID;
-                       break;
-               case 'p':
-                       tid = atoi(optarg);
-                       if (!tid)
-                               err(1, "Invalid pid\n");
-                       cmd_type = TASKSTATS_CMD_ATTR_PID;
-                       break;
-               case 'c':
-
-                       /* Block SIGCHLD for sigwait() later */
-                       if (sigemptyset(&sigset) == -1)
-                               err(1, "Failed to empty sigset");
-                       if (sigaddset(&sigset, SIGCHLD))
-                               err(1, "Failed to set sigchld in sigset");
-                       sigprocmask(SIG_BLOCK, &sigset, NULL);
-
-                       /* fork/exec a child */
-                       tid = fork();
-                       if (tid < 0)
-                               err(1, "Fork failed\n");
-                       if (tid == 0)
-                               if (execvp(argv[optind - 1],
-                                   &argv[optind - 1]) < 0)
-                                       exit(-1);
-
-                       /* Set the command type and avoid further processing */
-                       cmd_type = TASKSTATS_CMD_ATTR_PID;
-                       forking = 1;
-                       break;
-               case 'v':
-                       printf("debug on\n");
-                       dbg = 1;
-                       break;
-               case 'l':
-                       printf("listen forever\n");
-                       loop = 1;
-                       break;
-               default:
-                       usage();
-                       exit(-1);
-               }
-       }
-
-       if (write_file) {
-               fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
-                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-               if (fd == -1) {
-                       perror("Cannot open output file\n");
-                       exit(1);
-               }
-       }
-
-       nl_sd = create_nl_socket(NETLINK_GENERIC);
-       if (nl_sd < 0)
-               err(1, "error creating Netlink socket\n");
-
-
-       mypid = getpid();
-       id = get_family_id(nl_sd);
-       if (!id) {
-               fprintf(stderr, "Error getting family id, errno %d\n", errno);
-               goto err;
-       }
-       PRINTF("family id %d\n", id);
-
-       if (maskset) {
-               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
-                             TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
-                             &cpumask, strlen(cpumask) + 1);
-               PRINTF("Sent register cpumask, retval %d\n", rc);
-               if (rc < 0) {
-                       fprintf(stderr, "error sending register cpumask\n");
-                       goto err;
-               }
-       }
-
-       if (tid && containerset) {
-               fprintf(stderr, "Select either -t or -C, not both\n");
-               goto err;
-       }
-
-       /*
-        * If we forked a child, wait for it to exit. Cannot use waitpid()
-        * as all the delicious data would be reaped as part of the wait
-        */
-       if (tid && forking) {
-               int sig_received;
-               sigwait(&sigset, &sig_received);
-       }
-
-       if (tid) {
-               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
-                             cmd_type, &tid, sizeof(__u32));
-               PRINTF("Sent pid/tgid, retval %d\n", rc);
-               if (rc < 0) {
-                       fprintf(stderr, "error sending tid/tgid cmd\n");
-                       goto done;
-               }
-       }
-
-       if (containerset) {
-               cfd = open(containerpath, O_RDONLY);
-               if (cfd < 0) {
-                       perror("error opening container file");
-                       goto err;
-               }
-               rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET,
-                             CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32));
-               if (rc < 0) {
-                       perror("error sending cgroupstats command");
-                       goto err;
-               }
-       }
-       if (!maskset && !tid && !containerset) {
-               usage();
-               goto err;
-       }
-
-       do {
-               rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
-               PRINTF("received %d bytes\n", rep_len);
-
-               if (rep_len < 0) {
-                       fprintf(stderr, "nonfatal reply error: errno %d\n",
-                               errno);
-                       continue;
-               }
-               if (msg.n.nlmsg_type == NLMSG_ERROR ||
-                   !NLMSG_OK((&msg.n), rep_len)) {
-                       struct nlmsgerr *err = NLMSG_DATA(&msg);
-                       fprintf(stderr, "fatal reply error,  errno %d\n",
-                               err->error);
-                       goto done;
-               }
-
-               PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d\n",
-                      sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
-
-
-               rep_len = GENLMSG_PAYLOAD(&msg.n);
-
-               na = (struct nlattr *) GENLMSG_DATA(&msg);
-               len = 0;
-               while (len < rep_len) {
-                       len += NLA_ALIGN(na->nla_len);
-                       switch (na->nla_type) {
-                       case TASKSTATS_TYPE_AGGR_TGID:
-                               /* Fall through */
-                       case TASKSTATS_TYPE_AGGR_PID:
-                               aggr_len = NLA_PAYLOAD(na->nla_len);
-                               len2 = 0;
-                               /* For nested attributes, na follows */
-                               na = (struct nlattr *) NLA_DATA(na);
-                               done = 0;
-                               while (len2 < aggr_len) {
-                                       switch (na->nla_type) {
-                                       case TASKSTATS_TYPE_PID:
-                                               rtid = *(int *) NLA_DATA(na);
-                                               if (print_delays)
-                                                       printf("PID\t%d\n", rtid);
-                                               break;
-                                       case TASKSTATS_TYPE_TGID:
-                                               rtid = *(int *) NLA_DATA(na);
-                                               if (print_delays)
-                                                       printf("TGID\t%d\n", rtid);
-                                               break;
-                                       case TASKSTATS_TYPE_STATS:
-                                               count++;
-                                               if (print_delays)
-                                                       print_delayacct((struct taskstats *) NLA_DATA(na));
-                                               if (print_io_accounting)
-                                                       print_ioacct((struct taskstats *) NLA_DATA(na));
-                                               if (print_task_context_switch_counts)
-                                                       task_context_switch_counts((struct taskstats *) NLA_DATA(na));
-                                               if (fd) {
-                                                       if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
-                                                               err(1,"write error\n");
-                                                       }
-                                               }
-                                               if (!loop)
-                                                       goto done;
-                                               break;
-                                       case TASKSTATS_TYPE_NULL:
-                                               break;
-                                       default:
-                                               fprintf(stderr, "Unknown nested"
-                                                       " nla_type %d\n",
-                                                       na->nla_type);
-                                               break;
-                                       }
-                                       len2 += NLA_ALIGN(na->nla_len);
-                                       na = (struct nlattr *)((char *)na +
-                                                              NLA_ALIGN(na->nla_len));
-                               }
-                               break;
-
-                       case CGROUPSTATS_TYPE_CGROUP_STATS:
-                               print_cgroupstats(NLA_DATA(na));
-                               break;
-                       default:
-                               fprintf(stderr, "Unknown nla_type %d\n",
-                                       na->nla_type);
-                       case TASKSTATS_TYPE_NULL:
-                               break;
-                       }
-                       na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
-               }
-       } while (loop);
-done:
-       if (maskset) {
-               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
-                             TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
-                             &cpumask, strlen(cpumask) + 1);
-               printf("Sent deregister mask, retval %d\n", rc);
-               if (rc < 0)
-                       err(rc, "error sending deregister cpumask\n");
-       }
-err:
-       close(nl_sd);
-       if (fd)
-               close(fd);
-       if (cfd)
-               close(cfd);
-       return 0;
-}
index dea011c..b6e69fd 100644 (file)
@@ -8,8 +8,6 @@ Interrupts
        - ARM Interrupt subsystem documentation
 IXP4xx
        - Intel IXP4xx Network processor.
-Makefile
-       - Build sourcefiles as part of the Documentation-build for arm
 Netwinder
        - Netwinder specific documentation
 Porting
diff --git a/Documentation/auxdisplay/.gitignore b/Documentation/auxdisplay/.gitignore
deleted file mode 100644 (file)
index 7af2228..0000000
+++ /dev/null
@@ -1 +0,0 @@
-cfag12864b-example
diff --git a/Documentation/auxdisplay/Makefile b/Documentation/auxdisplay/Makefile
deleted file mode 100644 (file)
index ada4dac..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# List of programs to build
-hostprogs-y := cfag12864b-example
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_cfag12864b-example.o += -I$(objtree)/usr/include
index eb7be39..12fd51b 100644 (file)
@@ -101,5 +101,5 @@ Although the LCD won't get updated until the next refresh time arrives.
 Also, you can mmap the framebuffer: open & mmap, munmap & close...
 which is the best option for most uses.
 
-Check Documentation/auxdisplay/cfag12864b-example.c
+Check samples/auxdisplay/cfag12864b-example.c
 for a real working userspace complete program with usage examples.
diff --git a/Documentation/auxdisplay/cfag12864b-example.c b/Documentation/auxdisplay/cfag12864b-example.c
deleted file mode 100644 (file)
index e7823ff..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *    Filename: cfag12864b-example.c
- *     Version: 0.1.0
- * Description: cfag12864b LCD userspace example program
- *     License: GPLv2
- *
- *      Author: Copyright (C) Miguel Ojeda Sandonis
- *        Date: 2006-10-31
- *
- *  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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-/*
- * ------------------------
- * start of cfag12864b code
- * ------------------------
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#define CFAG12864B_WIDTH               (128)
-#define CFAG12864B_HEIGHT              (64)
-#define CFAG12864B_SIZE                        (128 * 64 / 8)
-#define CFAG12864B_BPB                 (8)
-#define CFAG12864B_ADDRESS(x, y)       ((y) * CFAG12864B_WIDTH / \
-                                       CFAG12864B_BPB + (x) / CFAG12864B_BPB)
-#define CFAG12864B_BIT(n)              (((unsigned char) 1) << (n))
-
-#undef CFAG12864B_DOCHECK
-#ifdef CFAG12864B_DOCHECK
-       #define CFAG12864B_CHECK(x, y)          ((x) < CFAG12864B_WIDTH && \
-                                               (y) < CFAG12864B_HEIGHT)
-#else
-       #define CFAG12864B_CHECK(x, y)          (1)
-#endif
-
-int cfag12864b_fd;
-unsigned char * cfag12864b_mem;
-unsigned char cfag12864b_buffer[CFAG12864B_SIZE];
-
-/*
- * init a cfag12864b framebuffer device
- *
- * No error:       return = 0
- * Unable to open: return = -1
- * Unable to mmap: return = -2
- */
-static int cfag12864b_init(char *path)
-{
-       cfag12864b_fd = open(path, O_RDWR);
-       if (cfag12864b_fd == -1)
-               return -1;
-
-       cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE,
-               MAP_SHARED, cfag12864b_fd, 0);
-       if (cfag12864b_mem == MAP_FAILED) {
-               close(cfag12864b_fd);
-               return -2;
-       }
-
-       return 0;
-}
-
-/*
- * exit a cfag12864b framebuffer device
- */
-static void cfag12864b_exit(void)
-{
-       munmap(cfag12864b_mem, CFAG12864B_SIZE);
-       close(cfag12864b_fd);
-}
-
-/*
- * set (x, y) pixel
- */
-static void cfag12864b_set(unsigned char x, unsigned char y)
-{
-       if (CFAG12864B_CHECK(x, y))
-               cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |=
-                       CFAG12864B_BIT(x % CFAG12864B_BPB);
-}
-
-/*
- * unset (x, y) pixel
- */
-static void cfag12864b_unset(unsigned char x, unsigned char y)
-{
-       if (CFAG12864B_CHECK(x, y))
-               cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &=
-                       ~CFAG12864B_BIT(x % CFAG12864B_BPB);
-}
-
-/*
- * is set (x, y) pixel?
- *
- * Pixel off: return = 0
- * Pixel on:  return = 1
- */
-static unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
-{
-       if (CFAG12864B_CHECK(x, y))
-               if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &
-                       CFAG12864B_BIT(x % CFAG12864B_BPB))
-                       return 1;
-
-       return 0;
-}
-
-/*
- * not (x, y) pixel
- */
-static void cfag12864b_not(unsigned char x, unsigned char y)
-{
-       if (cfag12864b_isset(x, y))
-               cfag12864b_unset(x, y);
-       else
-               cfag12864b_set(x, y);
-}
-
-/*
- * fill (set all pixels)
- */
-static void cfag12864b_fill(void)
-{
-       unsigned short i;
-
-       for (i = 0; i < CFAG12864B_SIZE; i++)
-               cfag12864b_buffer[i] = 0xFF;
-}
-
-/*
- * clear (unset all pixels)
- */
-static void cfag12864b_clear(void)
-{
-       unsigned short i;
-
-       for (i = 0; i < CFAG12864B_SIZE; i++)
-               cfag12864b_buffer[i] = 0;
-}
-
-/*
- * format a [128*64] matrix
- *
- * Pixel off: src[i] = 0
- * Pixel on:  src[i] > 0
- */
-static void cfag12864b_format(unsigned char * matrix)
-{
-       unsigned char i, j, n;
-
-       for (i = 0; i < CFAG12864B_HEIGHT; i++)
-       for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) {
-               cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB +
-                       j] = 0;
-               for (n = 0; n < CFAG12864B_BPB; n++)
-                       if (matrix[i * CFAG12864B_WIDTH +
-                               j * CFAG12864B_BPB + n])
-                               cfag12864b_buffer[i * CFAG12864B_WIDTH /
-                                       CFAG12864B_BPB + j] |=
-                                       CFAG12864B_BIT(n);
-       }
-}
-
-/*
- * blit buffer to lcd
- */
-static void cfag12864b_blit(void)
-{
-       memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE);
-}
-
-/*
- * ----------------------
- * end of cfag12864b code
- * ----------------------
- */
-
-#include <stdio.h>
-
-#define EXAMPLES       6
-
-static void example(unsigned char n)
-{
-       unsigned short i, j;
-       unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT];
-
-       if (n > EXAMPLES)
-               return;
-
-       printf("Example %i/%i - ", n, EXAMPLES);
-
-       switch (n) {
-       case 1:
-               printf("Draw points setting bits");
-               cfag12864b_clear();
-               for (i = 0; i < CFAG12864B_WIDTH; i += 2)
-                       for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
-                               cfag12864b_set(i, j);
-               break;
-
-       case 2:
-               printf("Clear the LCD");
-               cfag12864b_clear();
-               break;
-
-       case 3:
-               printf("Draw rows formatting a [128*64] matrix");
-               memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT);
-               for (i = 0; i < CFAG12864B_WIDTH; i++)
-                       for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
-                               matrix[j * CFAG12864B_WIDTH + i] = 1;
-               cfag12864b_format(matrix);
-               break;
-
-       case 4:
-               printf("Fill the lcd");
-               cfag12864b_fill();
-               break;
-
-       case 5:
-               printf("Draw columns unsetting bits");
-               for (i = 0; i < CFAG12864B_WIDTH; i += 2)
-                       for (j = 0; j < CFAG12864B_HEIGHT; j++)
-                               cfag12864b_unset(i, j);
-               break;
-
-       case 6:
-               printf("Do negative not-ing all bits");
-               for (i = 0; i < CFAG12864B_WIDTH; i++)
-                       for (j = 0; j < CFAG12864B_HEIGHT; j ++)
-                               cfag12864b_not(i, j);
-               break;
-       }
-
-       puts(" - [Press Enter]");
-}
-
-int main(int argc, char *argv[])
-{
-       unsigned char n;
-
-       if (argc != 2) {
-               printf(
-                       "Sintax:  %s fbdev\n"
-                       "Usually: /dev/fb0, /dev/fb1...\n", argv[0]);
-               return -1;
-       }
-
-       if (cfag12864b_init(argv[1])) {
-               printf("Can't init %s fbdev\n", argv[1]);
-               return -2;
-       }
-
-       for (n = 1; n <= EXAMPLES; n++) {
-               example(n);
-               cfag12864b_blit();
-               while (getchar() != '\n');
-       }
-
-       cfag12864b_exit();
-
-       return 0;
-}
index c54fcdd..265a1ef 100644 (file)
@@ -1,10 +1,6 @@
 00-INDEX
        - This file
-Makefile
-       - Makefile for gptimers example file.
 bfin-gpio-notes.txt
        - Notes in developing/using bfin-gpio driver.
 bfin-spi-notes.txt
        - Notes for using bfin spi bus driver.
-gptimers-example.c
-       - gptimers example
diff --git a/Documentation/blackfin/Makefile b/Documentation/blackfin/Makefile
deleted file mode 100644 (file)
index 6782c58..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-ifneq ($(CONFIG_BLACKFIN),)
-ifneq ($(CONFIG_BFIN_GPTIMERS),)
-obj-m := gptimers-example.o
-endif
-endif
diff --git a/Documentation/blackfin/gptimers-example.c b/Documentation/blackfin/gptimers-example.c
deleted file mode 100644 (file)
index 283eba9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Simple gptimers example
- *     http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gptimers
- *
- * Copyright 2007-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-
-#include <asm/gptimers.h>
-#include <asm/portmux.h>
-
-/* ... random driver includes ... */
-
-#define DRIVER_NAME "gptimer_example"
-
-#ifdef IRQ_TIMER5
-#define SAMPLE_IRQ_TIMER IRQ_TIMER5
-#else
-#define SAMPLE_IRQ_TIMER IRQ_TIMER2
-#endif
-
-struct gptimer_data {
-       uint32_t period, width;
-};
-static struct gptimer_data data;
-
-/* ... random driver state ... */
-
-static irqreturn_t gptimer_example_irq(int irq, void *dev_id)
-{
-       struct gptimer_data *data = dev_id;
-
-       /* make sure it was our timer which caused the interrupt */
-       if (!get_gptimer_intr(TIMER5_id))
-               return IRQ_NONE;
-
-       /* read the width/period values that were captured for the waveform */
-       data->width = get_gptimer_pwidth(TIMER5_id);
-       data->period = get_gptimer_period(TIMER5_id);
-
-       /* acknowledge the interrupt */
-       clear_gptimer_intr(TIMER5_id);
-
-       /* tell the upper layers we took care of things */
-       return IRQ_HANDLED;
-}
-
-/* ... random driver code ... */
-
-static int __init gptimer_example_init(void)
-{
-       int ret;
-
-       /* grab the peripheral pins */
-       ret = peripheral_request(P_TMR5, DRIVER_NAME);
-       if (ret) {
-               printk(KERN_NOTICE DRIVER_NAME ": peripheral request failed\n");
-               return ret;
-       }
-
-       /* grab the IRQ for the timer */
-       ret = request_irq(SAMPLE_IRQ_TIMER, gptimer_example_irq,
-                       IRQF_SHARED, DRIVER_NAME, &data);
-       if (ret) {
-               printk(KERN_NOTICE DRIVER_NAME ": IRQ request failed\n");
-               peripheral_free(P_TMR5);
-               return ret;
-       }
-
-       /* setup the timer and enable it */
-       set_gptimer_config(TIMER5_id,
-                       WDTH_CAP | PULSE_HI | PERIOD_CNT | IRQ_ENA);
-       enable_gptimers(TIMER5bit);
-
-       return 0;
-}
-module_init(gptimer_example_init);
-
-static void __exit gptimer_example_exit(void)
-{
-       disable_gptimers(TIMER5bit);
-       free_irq(SAMPLE_IRQ_TIMER, &data);
-       peripheral_free(P_TMR5);
-}
-module_exit(gptimer_example_exit);
-
-MODULE_LICENSE("BSD");
diff --git a/Documentation/filesystems/.gitignore b/Documentation/filesystems/.gitignore
deleted file mode 100644 (file)
index 31d6e42..0000000
+++ /dev/null
@@ -1 +0,0 @@
-dnotify_test
index 9922939..f66e748 100644 (file)
@@ -2,8 +2,6 @@
        - this file (info on some of the filesystems supported by linux).
 Locking
        - info on locking rules as they pertain to Linux VFS.
-Makefile
-       - Makefile for building the filsystems-part of DocBook.
 9p.txt
        - 9p (v9fs) is an implementation of the Plan 9 remote fs protocol.
 adfs.txt
diff --git a/Documentation/filesystems/Makefile b/Documentation/filesystems/Makefile
deleted file mode 100644 (file)
index 883010c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := dnotify_test
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/filesystems/dnotify_test.c b/Documentation/filesystems/dnotify_test.c
deleted file mode 100644 (file)
index 8b37b4a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#define _GNU_SOURCE    /* needed to get the defines */
-#include <fcntl.h>     /* in glibc 2.2 this has the needed
-                                  values defined */
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-
-static volatile int event_fd;
-
-static void handler(int sig, siginfo_t *si, void *data)
-{
-       event_fd = si->si_fd;
-}
-
-int main(void)
-{
-       struct sigaction act;
-       int fd;
-
-       act.sa_sigaction = handler;
-       sigemptyset(&act.sa_mask);
-       act.sa_flags = SA_SIGINFO;
-       sigaction(SIGRTMIN + 1, &act, NULL);
-
-       fd = open(".", O_RDONLY);
-       fcntl(fd, F_SETSIG, SIGRTMIN + 1);
-       fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
-       /* we will now be notified if any of the files
-          in "." is modified or new files are created */
-       while (1) {
-               pause();
-               printf("Got event on fd=%d\n", event_fd);
-       }
-}
diff --git a/Documentation/ia64/.gitignore b/Documentation/ia64/.gitignore
deleted file mode 100644 (file)
index ab806ed..0000000
+++ /dev/null
@@ -1 +0,0 @@
-aliasing-test
diff --git a/Documentation/ia64/Makefile b/Documentation/ia64/Makefile
deleted file mode 100644 (file)
index d493163..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := aliasing-test
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/ia64/aliasing-test.c b/Documentation/ia64/aliasing-test.c
deleted file mode 100644 (file)
index 62a190d..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Exercise /dev/mem mmap cases that have been troublesome in the past
- *
- * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
- *     Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * 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.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <linux/pci.h>
-
-int sum;
-
-static int map_mem(char *path, off_t offset, size_t length, int touch)
-{
-       int fd, rc;
-       void *addr;
-       int *c;
-
-       fd = open(path, O_RDWR);
-       if (fd == -1) {
-               perror(path);
-               return -1;
-       }
-
-       if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
-               rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
-               if (rc == -1)
-                       perror("PCIIOC_MMAP_IS_MEM ioctl");
-       }
-
-       addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
-       if (addr == MAP_FAILED)
-               return 1;
-
-       if (touch) {
-               c = (int *) addr;
-               while (c < (int *) (addr + length))
-                       sum += *c++;
-       }
-
-       rc = munmap(addr, length);
-       if (rc == -1) {
-               perror("munmap");
-               return -1;
-       }
-
-       close(fd);
-       return 0;
-}
-
-static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
-{
-       struct dirent **namelist;
-       char *name, *path2;
-       int i, n, r, rc = 0, result = 0;
-       struct stat buf;
-
-       n = scandir(path, &namelist, 0, alphasort);
-       if (n < 0) {
-               perror("scandir");
-               return -1;
-       }
-
-       for (i = 0; i < n; i++) {
-               name = namelist[i]->d_name;
-
-               if (fnmatch(".", name, 0) == 0)
-                       goto skip;
-               if (fnmatch("..", name, 0) == 0)
-                       goto skip;
-
-               path2 = malloc(strlen(path) + strlen(name) + 3);
-               strcpy(path2, path);
-               strcat(path2, "/");
-               strcat(path2, name);
-
-               if (fnmatch(file, name, 0) == 0) {
-                       rc = map_mem(path2, offset, length, touch);
-                       if (rc == 0)
-                               fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
-                       else if (rc > 0)
-                               fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
-                       else {
-                               fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
-                               return rc;
-                       }
-               } else {
-                       r = lstat(path2, &buf);
-                       if (r == 0 && S_ISDIR(buf.st_mode)) {
-                               rc = scan_tree(path2, file, offset, length, touch);
-                               if (rc < 0)
-                                       return rc;
-                       }
-               }
-
-               result |= rc;
-               free(path2);
-
-skip:
-               free(namelist[i]);
-       }
-       free(namelist);
-       return result;
-}
-
-char buf[1024];
-
-static int read_rom(char *path)
-{
-       int fd, rc;
-       size_t size = 0;
-
-       fd = open(path, O_RDWR);
-       if (fd == -1) {
-               perror(path);
-               return -1;
-       }
-
-       rc = write(fd, "1", 2);
-       if (rc <= 0) {
-               close(fd);
-               perror("write");
-               return -1;
-       }
-
-       do {
-               rc = read(fd, buf, sizeof(buf));
-               if (rc > 0)
-                       size += rc;
-       } while (rc > 0);
-
-       close(fd);
-       return size;
-}
-
-static int scan_rom(char *path, char *file)
-{
-       struct dirent **namelist;
-       char *name, *path2;
-       int i, n, r, rc = 0, result = 0;
-       struct stat buf;
-
-       n = scandir(path, &namelist, 0, alphasort);
-       if (n < 0) {
-               perror("scandir");
-               return -1;
-       }
-
-       for (i = 0; i < n; i++) {
-               name = namelist[i]->d_name;
-
-               if (fnmatch(".", name, 0) == 0)
-                       goto skip;
-               if (fnmatch("..", name, 0) == 0)
-                       goto skip;
-
-               path2 = malloc(strlen(path) + strlen(name) + 3);
-               strcpy(path2, path);
-               strcat(path2, "/");
-               strcat(path2, name);
-
-               if (fnmatch(file, name, 0) == 0) {
-                       rc = read_rom(path2);
-
-                       /*
-                        * It's OK if the ROM is unreadable.  Maybe there
-                        * is no ROM, or some other error occurred.  The
-                        * important thing is that no MCA happened.
-                        */
-                       if (rc > 0)
-                               fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
-                       else {
-                               fprintf(stderr, "PASS: %s not readable\n", path2);
-                               return rc;
-                       }
-               } else {
-                       r = lstat(path2, &buf);
-                       if (r == 0 && S_ISDIR(buf.st_mode)) {
-                               rc = scan_rom(path2, file);
-                               if (rc < 0)
-                                       return rc;
-                       }
-               }
-
-               result |= rc;
-               free(path2);
-
-skip:
-               free(namelist[i]);
-       }
-       free(namelist);
-       return result;
-}
-
-int main(void)
-{
-       int rc;
-
-       if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
-               fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
-       else
-               fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
-
-       /*
-        * It's not safe to blindly read the VGA frame buffer.  If you know
-        * how to poke the card the right way, it should respond, but it's
-        * not safe in general.  Many machines, e.g., Intel chipsets, cover
-        * up a non-responding card by just returning -1, but others will
-        * report the failure as a machine check.
-        */
-       if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
-               fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
-       else
-               fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
-
-       if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
-               fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
-       else
-               fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
-
-       /*
-        * Often you can map all the individual pieces above (0-0xA0000,
-        * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
-        * thing at once.  This is because the individual pieces use different
-        * attributes, and there's no single attribute supported over the
-        * whole region.
-        */
-       rc = map_mem("/dev/mem", 0, 1024*1024, 0);
-       if (rc == 0)
-               fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
-       else if (rc > 0)
-               fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
-       else
-               fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
-
-       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
-       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
-       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
-       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
-
-       scan_rom("/sys/devices", "rom");
-
-       scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
-       scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
-       scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
-       scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
-
-       return rc;
-}
index 979eaca..54bee77 100644 (file)
@@ -1,8 +1,9 @@
 Linux Kernel Selftests
 
 The kernel contains a set of "self tests" under the tools/testing/selftests/
-directory. These are intended to be small unit tests to exercise individual
-code paths in the kernel.
+directory. These are intended to be small tests to exercise individual code
+paths in the kernel. Tests are intended to be run after building, installing
+and booting a kernel.
 
 On some systems, hot-plug tests could hang forever waiting for cpu and
 memory to be ready to be offlined. A special hot-plug target is created
diff --git a/Documentation/laptops/.gitignore b/Documentation/laptops/.gitignore
deleted file mode 100644 (file)
index 9fc984e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-dslm
index 7c0ac2a..86169dc 100644 (file)
@@ -1,13 +1,9 @@
 00-INDEX
        - This file
-Makefile
-       - Makefile for building dslm example program.
 asus-laptop.txt
        - information on the Asus Laptop Extras driver.
 disk-shock-protection.txt
        - information on hard disk shock protection.
-dslm.c
-       - Simple Disk Sleep Monitor program
 laptop-mode.txt
        - how to conserve battery power using laptop-mode.
 sony-laptop.txt
diff --git a/Documentation/laptops/Makefile b/Documentation/laptops/Makefile
deleted file mode 100644 (file)
index 0abe44f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := dslm
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/laptops/dslm.c b/Documentation/laptops/dslm.c
deleted file mode 100644 (file)
index d5dd2d4..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * dslm.c
- * Simple Disk Sleep Monitor
- *  by Bartek Kania
- * Licensed under the GPL
- */
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-
-#ifdef DEBUG
-#define D(x) x
-#else
-#define D(x)
-#endif
-
-int endit = 0;
-
-/* Check if the disk is in powersave-mode
- * Most of the code is stolen from hdparm.
- * 1 = active, 0 = standby/sleep, -1 = unknown */
-static int check_powermode(int fd)
-{
-    unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
-    int state;
-
-    if (ioctl(fd, HDIO_DRIVE_CMD, &args)
-       && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
-       && ioctl(fd, HDIO_DRIVE_CMD, &args)) {
-       if (errno != EIO || args[0] != 0 || args[1] != 0) {
-           state = -1; /* "unknown"; */
-       } else
-           state = 0; /* "sleeping"; */
-    } else {
-       state = (args[2] == 255) ? 1 : 0;
-    }
-    D(printf(" drive state is:  %d\n", state));
-
-    return state;
-}
-
-static char *state_name(int i)
-{
-    if (i == -1) return "unknown";
-    if (i == 0) return "sleeping";
-    if (i == 1) return "active";
-
-    return "internal error";
-}
-
-static char *myctime(time_t time)
-{
-    char *ts = ctime(&time);
-    ts[strlen(ts) - 1] = 0;
-
-    return ts;
-}
-
-static void measure(int fd)
-{
-    time_t start_time;
-    int last_state;
-    time_t last_time;
-    int curr_state;
-    time_t curr_time = 0;
-    time_t time_diff;
-    time_t active_time = 0;
-    time_t sleep_time = 0;
-    time_t unknown_time = 0;
-    time_t total_time = 0;
-    int changes = 0;
-    float tmp;
-
-    printf("Starting measurements\n");
-
-    last_state = check_powermode(fd);
-    start_time = last_time = time(0);
-    printf("  System is in state %s\n\n", state_name(last_state));
-
-    while(!endit) {
-       sleep(1);
-       curr_state = check_powermode(fd);
-
-       if (curr_state != last_state || endit) {
-           changes++;
-           curr_time = time(0);
-           time_diff = curr_time - last_time;
-
-           if (last_state == 1) active_time += time_diff;
-           else if (last_state == 0) sleep_time += time_diff;
-           else unknown_time += time_diff;
-
-           last_state = curr_state;
-           last_time = curr_time;
-
-           printf("%s: State-change to %s\n", myctime(curr_time),
-                  state_name(curr_state));
-       }
-    }
-    changes--; /* Compensate for SIGINT */
-
-    total_time = time(0) - start_time;
-    printf("\nTotal running time:  %lus\n", curr_time - start_time);
-    printf(" State changed %d times\n", changes);
-
-    tmp = (float)sleep_time / (float)total_time * 100;
-    printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
-    tmp = (float)active_time / (float)total_time * 100;
-    printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
-    tmp = (float)unknown_time / (float)total_time * 100;
-    printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
-}
-
-static void ender(int s)
-{
-    endit = 1;
-}
-
-static void usage(void)
-{
-    puts("usage: dslm [-w <time>] <disk>");
-    exit(0);
-}
-
-int main(int argc, char **argv)
-{
-    int fd;
-    char *disk = 0;
-    int settle_time = 60;
-
-    /* Parse the simple command-line */
-    if (argc == 2)
-       disk = argv[1];
-    else if (argc == 4) {
-       settle_time = atoi(argv[2]);
-       disk = argv[3];
-    } else
-       usage();
-
-    if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
-       printf("Can't open %s, because: %s\n", disk, strerror(errno));
-       exit(-1);
-    }
-
-    if (settle_time) {
-       printf("Waiting %d seconds for the system to settle down to "
-              "'normal'\n", settle_time);
-       sleep(settle_time);
-    } else
-       puts("Not waiting for system to settle down");
-
-    signal(SIGINT, ender);
-
-    measure(fd);
-
-    close(fd);
-
-    return 0;
-}
index 4ebbfc3..19276f5 100644 (file)
@@ -779,4 +779,4 @@ Monitoring tool
 ---------------
 
 Bartek Kania submitted this, it can be used to measure how much time your disk
-spends spun up/down.  See Documentation/laptops/dslm.c
+spends spun up/down.  See tools/laptop/dslm/dslm.c
diff --git a/Documentation/mic/Makefile b/Documentation/mic/Makefile
deleted file mode 100644 (file)
index a191d45..0000000
+++ /dev/null
@@ -1 +0,0 @@
-subdir-y := mpssd
diff --git a/Documentation/mic/mpssd/.gitignore b/Documentation/mic/mpssd/.gitignore
deleted file mode 100644 (file)
index 8b7c72f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-mpssd
diff --git a/Documentation/mic/mpssd/Makefile b/Documentation/mic/mpssd/Makefile
deleted file mode 100644 (file)
index 06871b0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-ifndef CROSS_COMPILE
-# List of programs to build
-hostprogs-$(CONFIG_X86_64) := mpssd
-
-mpssd-objs := mpssd.o sysfs.o
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS += -I$(objtree)/usr/include -I$(srctree)/tools/include
-
-ifdef DEBUG
-HOSTCFLAGS += -DDEBUG=$(DEBUG)
-endif
-
-HOSTLOADLIBES_mpssd := -lpthread
-
-install:
-       install mpssd /usr/sbin/mpssd
-       install micctrl /usr/sbin/micctrl
-endif
diff --git a/Documentation/mic/mpssd/micctrl b/Documentation/mic/mpssd/micctrl
deleted file mode 100755 (executable)
index 8f2629b..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/bin/bash
-# Intel MIC Platform Software Stack (MPSS)
-#
-# Copyright(c) 2013 Intel Corporation.
-#
-# 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.
-#
-# The full GNU General Public License is included in this distribution in
-# the file called "COPYING".
-#
-# Intel MIC User Space Tools.
-#
-# micctrl - Controls MIC boot/start/stop.
-#
-# chkconfig: 2345 95 05
-# description: start MPSS stack processing.
-#
-### BEGIN INIT INFO
-# Provides: micctrl
-### END INIT INFO
-
-# Source function library.
-. /etc/init.d/functions
-
-sysfs="/sys/class/mic"
-
-_status()
-{
-       f=$sysfs/$1
-       echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
-}
-
-status()
-{
-       if [ "`echo $1 | head -c3`" == "mic" ]; then
-               _status $1
-               return $?
-       fi
-       for f in $sysfs/*
-       do
-               _status `basename $f`
-               RETVAL=$?
-               [ $RETVAL -ne 0 ] && return $RETVAL
-       done
-       return 0
-}
-
-_reset()
-{
-       f=$sysfs/$1
-       echo reset > $f/state
-}
-
-reset()
-{
-       if [ "`echo $1 | head -c3`" == "mic" ]; then
-               _reset $1
-               return $?
-       fi
-       for f in $sysfs/*
-       do
-               _reset `basename $f`
-               RETVAL=$?
-               [ $RETVAL -ne 0 ] && return $RETVAL
-       done
-       return 0
-}
-
-_boot()
-{
-       f=$sysfs/$1
-       echo "linux" > $f/bootmode
-       echo "mic/uos.img" > $f/firmware
-       echo "mic/$1.image" > $f/ramdisk
-       echo "boot" > $f/state
-}
-
-boot()
-{
-       if [ "`echo $1 | head -c3`" == "mic" ]; then
-               _boot $1
-               return $?
-       fi
-       for f in $sysfs/*
-       do
-               _boot `basename $f`
-               RETVAL=$?
-               [ $RETVAL -ne 0 ] && return $RETVAL
-       done
-       return 0
-}
-
-_shutdown()
-{
-       f=$sysfs/$1
-       echo shutdown > $f/state
-}
-
-shutdown()
-{
-       if [ "`echo $1 | head -c3`" == "mic" ]; then
-               _shutdown $1
-               return $?
-       fi
-       for f in $sysfs/*
-       do
-               _shutdown `basename $f`
-               RETVAL=$?
-               [ $RETVAL -ne 0 ] && return $RETVAL
-       done
-       return 0
-}
-
-_wait()
-{
-       f=$sysfs/$1
-       while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
-       do
-               sleep 1
-               echo -e "Waiting for $1 to go offline"
-       done
-}
-
-wait()
-{
-       if [ "`echo $1 | head -c3`" == "mic" ]; then
-               _wait $1
-               return $?
-       fi
-       # Wait for the cards to go offline
-       for f in $sysfs/*
-       do
-               _wait `basename $f`
-               RETVAL=$?
-               [ $RETVAL -ne 0 ] && return $RETVAL
-       done
-       return 0
-}
-
-if [ ! -d "$sysfs" ]; then
-       echo -e $"Module unloaded "
-       exit 3
-fi
-
-case $1 in
-       -s)
-               status $2
-               ;;
-       -r)
-               reset $2
-               ;;
-       -b)
-               boot $2
-               ;;
-       -S)
-               shutdown $2
-               ;;
-       -w)
-               wait $2
-               ;;
-       *)
-               echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
-               exit 2
-esac
-
-exit $?
diff --git a/Documentation/mic/mpssd/mpss b/Documentation/mic/mpssd/mpss
deleted file mode 100755 (executable)
index 5fcf9fa..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/bin/bash
-# Intel MIC Platform Software Stack (MPSS)
-#
-# Copyright(c) 2013 Intel Corporation.
-#
-# 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.
-#
-# The full GNU General Public License is included in this distribution in
-# the file called "COPYING".
-#
-# Intel MIC User Space Tools.
-#
-# mpss Start mpssd.
-#
-# chkconfig: 2345 95 05
-# description: start MPSS stack processing.
-#
-### BEGIN INIT INFO
-# Provides: mpss
-# Required-Start:
-# Required-Stop:
-# Short-Description: MPSS stack control
-# Description: MPSS stack control
-### END INIT INFO
-
-# Source function library.
-. /etc/init.d/functions
-
-exec=/usr/sbin/mpssd
-sysfs="/sys/class/mic"
-mic_modules="mic_host mic_x100_dma scif vop"
-
-start()
-{
-       [ -x $exec ] || exit 5
-
-       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
-               echo -e $"MPSSD already running! "
-               success
-               echo
-               return 0
-       fi
-
-       echo -e $"Starting MPSS Stack"
-       echo -e $"Loading MIC drivers:" $mic_modules
-
-       modprobe -a $mic_modules
-       RETVAL=$?
-       if [ $RETVAL -ne 0 ]; then
-               failure
-               echo
-               return $RETVAL
-       fi
-
-       # Start the daemon
-       echo -n $"Starting MPSSD "
-       $exec
-       RETVAL=$?
-       if [ $RETVAL -ne 0 ]; then
-               failure
-               echo
-               return $RETVAL
-       fi
-       success
-       echo
-
-       sleep 5
-
-       # Boot the cards
-       micctrl -b
-
-       # Wait till ping works
-       for f in $sysfs/*
-       do
-               count=100
-               ipaddr=`cat $f/cmdline`
-               ipaddr=${ipaddr#*address,}
-               ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
-               while [ $count -ge 0 ]
-               do
-                       echo -e "Pinging "`basename $f`" "
-                       ping -c 1 $ipaddr &> /dev/null
-                       RETVAL=$?
-                       if [ $RETVAL -eq 0 ]; then
-                               success
-                               break
-                       fi
-                       sleep 1
-                       count=`expr $count - 1`
-               done
-               [ $RETVAL -ne 0 ] && failure || success
-               echo
-       done
-       return $RETVAL
-}
-
-stop()
-{
-       echo -e $"Shutting down MPSS Stack: "
-
-       # Bail out if module is unloaded
-       if [ ! -d "$sysfs" ]; then
-               echo -n $"Module unloaded "
-               success
-               echo
-               return 0
-       fi
-
-       # Shut down the cards.
-       micctrl -S
-
-       # Wait for the cards to go offline
-       for f in $sysfs/*
-       do
-               while [ "`cat $f/state`" != "ready" ]
-               do
-                       sleep 1
-                       echo -e "Waiting for "`basename $f`" to become ready"
-               done
-       done
-
-       # Display the status of the cards
-       micctrl -s
-
-       # Kill MPSSD now
-       echo -n $"Killing MPSSD"
-       killall -9 mpssd 2>/dev/null
-       RETVAL=$?
-       [ $RETVAL -ne 0 ] && failure || success
-       echo
-       return $RETVAL
-}
-
-restart()
-{
-       stop
-       sleep 5
-       start
-}
-
-status()
-{
-       micctrl -s
-       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
-               echo "mpssd is running"
-       else
-               echo "mpssd is stopped"
-       fi
-       return 0
-}
-
-unload()
-{
-       if [ ! -d "$sysfs" ]; then
-               echo -n $"No MIC_HOST Module: "
-               success
-               echo
-               return
-       fi
-
-       stop
-
-       sleep 5
-       echo -n $"Removing MIC drivers:" $mic_modules
-       modprobe -r $mic_modules
-       RETVAL=$?
-       [ $RETVAL -ne 0 ] && failure || success
-       echo
-       return $RETVAL
-}
-
-case $1 in
-       start)
-               start
-               ;;
-       stop)
-               stop
-               ;;
-       restart)
-               restart
-               ;;
-       status)
-               status
-               ;;
-       unload)
-               unload
-               ;;
-       *)
-               echo $"Usage: $0 {start|stop|restart|status|unload}"
-               exit 2
-esac
-
-exit $?
diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c
deleted file mode 100644 (file)
index 49db1de..0000000
+++ /dev/null
@@ -1,1826 +0,0 @@
-/*
- * Intel MIC Platform Software Stack (MPSS)
- *
- * Copyright(c) 2013 Intel Corporation.
- *
- * 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.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Intel MIC User Space Tools.
- */
-
-#define _GNU_SOURCE
-
-#include <stdlib.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <assert.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <signal.h>
-#include <poll.h>
-#include <features.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <linux/virtio_ring.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_console.h>
-#include <linux/virtio_blk.h>
-#include <linux/version.h>
-#include "mpssd.h"
-#include <linux/mic_ioctl.h>
-#include <linux/mic_common.h>
-#include <tools/endian.h>
-
-static void *init_mic(void *arg);
-
-static FILE *logfp;
-static struct mic_info mic_list;
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define min_t(type, x, y) ({                           \
-               type __min1 = (x);                      \
-               type __min2 = (y);                      \
-               __min1 < __min2 ? __min1 : __min2; })
-
-/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_DOWN(addr, size)  ((addr)&(~((size)-1)))
-#define _ALIGN_UP(addr, size)    _ALIGN_DOWN(addr + size - 1, size)
-
-/* align addr on a size boundary - adjust address up if needed */
-#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)        _ALIGN(addr, PAGE_SIZE)
-
-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-
-#define GSO_ENABLED            1
-#define MAX_GSO_SIZE           (64 * 1024)
-#define ETH_H_LEN              14
-#define MAX_NET_PKT_SIZE       (_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
-#define MIC_DEVICE_PAGE_END    0x1000
-
-#ifndef VIRTIO_NET_HDR_F_DATA_VALID
-#define VIRTIO_NET_HDR_F_DATA_VALID    2       /* Csum is valid */
-#endif
-
-static struct {
-       struct mic_device_desc dd;
-       struct mic_vqconfig vqconfig[2];
-       __u32 host_features, guest_acknowledgements;
-       struct virtio_console_config cons_config;
-} virtcons_dev_page = {
-       .dd = {
-               .type = VIRTIO_ID_CONSOLE,
-               .num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
-               .feature_len = sizeof(virtcons_dev_page.host_features),
-               .config_len = sizeof(virtcons_dev_page.cons_config),
-       },
-       .vqconfig[0] = {
-               .num = htole16(MIC_VRING_ENTRIES),
-       },
-       .vqconfig[1] = {
-               .num = htole16(MIC_VRING_ENTRIES),
-       },
-};
-
-static struct {
-       struct mic_device_desc dd;
-       struct mic_vqconfig vqconfig[2];
-       __u32 host_features, guest_acknowledgements;
-       struct virtio_net_config net_config;
-} virtnet_dev_page = {
-       .dd = {
-               .type = VIRTIO_ID_NET,
-               .num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
-               .feature_len = sizeof(virtnet_dev_page.host_features),
-               .config_len = sizeof(virtnet_dev_page.net_config),
-       },
-       .vqconfig[0] = {
-               .num = htole16(MIC_VRING_ENTRIES),
-       },
-       .vqconfig[1] = {
-               .num = htole16(MIC_VRING_ENTRIES),
-       },
-#if GSO_ENABLED
-       .host_features = htole32(
-               1 << VIRTIO_NET_F_CSUM |
-               1 << VIRTIO_NET_F_GSO |
-               1 << VIRTIO_NET_F_GUEST_TSO4 |
-               1 << VIRTIO_NET_F_GUEST_TSO6 |
-               1 << VIRTIO_NET_F_GUEST_ECN),
-#else
-               .host_features = 0,
-#endif
-};
-
-static const char *mic_config_dir = "/etc/mpss";
-static const char *virtblk_backend = "VIRTBLK_BACKEND";
-static struct {
-       struct mic_device_desc dd;
-       struct mic_vqconfig vqconfig[1];
-       __u32 host_features, guest_acknowledgements;
-       struct virtio_blk_config blk_config;
-} virtblk_dev_page = {
-       .dd = {
-               .type = VIRTIO_ID_BLOCK,
-               .num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
-               .feature_len = sizeof(virtblk_dev_page.host_features),
-               .config_len = sizeof(virtblk_dev_page.blk_config),
-       },
-       .vqconfig[0] = {
-               .num = htole16(MIC_VRING_ENTRIES),
-       },
-       .host_features =
-               htole32(1<<VIRTIO_BLK_F_SEG_MAX),
-       .blk_config = {
-               .seg_max = htole32(MIC_VRING_ENTRIES - 2),
-               .capacity = htole64(0),
-        }
-};
-
-static char *myname;
-
-static int
-tap_configure(struct mic_info *mic, char *dev)
-{
-       pid_t pid;
-       char *ifargv[7];
-       char ipaddr[IFNAMSIZ];
-       int ret = 0;
-
-       pid = fork();
-       if (pid == 0) {
-               ifargv[0] = "ip";
-               ifargv[1] = "link";
-               ifargv[2] = "set";
-               ifargv[3] = dev;
-               ifargv[4] = "up";
-               ifargv[5] = NULL;
-               mpsslog("Configuring %s\n", dev);
-               ret = execvp("ip", ifargv);
-               if (ret < 0) {
-                       mpsslog("%s execvp failed errno %s\n",
-                               mic->name, strerror(errno));
-                       return ret;
-               }
-       }
-       if (pid < 0) {
-               mpsslog("%s fork failed errno %s\n",
-                       mic->name, strerror(errno));
-               return ret;
-       }
-
-       ret = waitpid(pid, NULL, 0);
-       if (ret < 0) {
-               mpsslog("%s waitpid failed errno %s\n",
-                       mic->name, strerror(errno));
-               return ret;
-       }
-
-       snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id + 1);
-
-       pid = fork();
-       if (pid == 0) {
-               ifargv[0] = "ip";
-               ifargv[1] = "addr";
-               ifargv[2] = "add";
-               ifargv[3] = ipaddr;
-               ifargv[4] = "dev";
-               ifargv[5] = dev;
-               ifargv[6] = NULL;
-               mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
-               ret = execvp("ip", ifargv);
-               if (ret < 0) {
-                       mpsslog("%s execvp failed errno %s\n",
-                               mic->name, strerror(errno));
-                       return ret;
-               }
-       }
-       if (pid < 0) {
-               mpsslog("%s fork failed errno %s\n",
-                       mic->name, strerror(errno));
-               return ret;
-       }
-
-       ret = waitpid(pid, NULL, 0);
-       if (ret < 0) {
-               mpsslog("%s waitpid failed errno %s\n",
-                       mic->name, strerror(errno));
-               return ret;
-       }
-       mpsslog("MIC name %s %s %d DONE!\n",
-               mic->name, __func__, __LINE__);
-       return 0;
-}
-
-static int tun_alloc(struct mic_info *mic, char *dev)
-{
-       struct ifreq ifr;
-       int fd, err;
-#if GSO_ENABLED
-       unsigned offload;
-#endif
-       fd = open("/dev/net/tun", O_RDWR);
-       if (fd < 0) {
-               mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
-               goto done;
-       }
-
-       memset(&ifr, 0, sizeof(ifr));
-
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
-       if (*dev)
-               strncpy(ifr.ifr_name, dev, IFNAMSIZ);
-
-       err = ioctl(fd, TUNSETIFF, (void *)&ifr);
-       if (err < 0) {
-               mpsslog("%s %s %d TUNSETIFF failed %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               close(fd);
-               return err;
-       }
-#if GSO_ENABLED
-       offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
-
-       err = ioctl(fd, TUNSETOFFLOAD, offload);
-       if (err < 0) {
-               mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               close(fd);
-               return err;
-       }
-#endif
-       strcpy(dev, ifr.ifr_name);
-       mpsslog("Created TAP %s\n", dev);
-done:
-       return fd;
-}
-
-#define NET_FD_VIRTIO_NET 0
-#define NET_FD_TUN 1
-#define MAX_NET_FD 2
-
-static void set_dp(struct mic_info *mic, int type, void *dp)
-{
-       switch (type) {
-       case VIRTIO_ID_CONSOLE:
-               mic->mic_console.console_dp = dp;
-               return;
-       case VIRTIO_ID_NET:
-               mic->mic_net.net_dp = dp;
-               return;
-       case VIRTIO_ID_BLOCK:
-               mic->mic_virtblk.block_dp = dp;
-               return;
-       }
-       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
-       assert(0);
-}
-
-static void *get_dp(struct mic_info *mic, int type)
-{
-       switch (type) {
-       case VIRTIO_ID_CONSOLE:
-               return mic->mic_console.console_dp;
-       case VIRTIO_ID_NET:
-               return mic->mic_net.net_dp;
-       case VIRTIO_ID_BLOCK:
-               return mic->mic_virtblk.block_dp;
-       }
-       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
-       assert(0);
-       return NULL;
-}
-
-static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
-{
-       struct mic_device_desc *d;
-       int i;
-       void *dp = get_dp(mic, type);
-
-       for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
-               i += mic_total_desc_size(d)) {
-               d = dp + i;
-
-               /* End of list */
-               if (d->type == 0)
-                       break;
-
-               if (d->type == -1)
-                       continue;
-
-               mpsslog("%s %s d-> type %d d %p\n",
-                       mic->name, __func__, d->type, d);
-
-               if (d->type == (__u8)type)
-                       return d;
-       }
-       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
-       return NULL;
-}
-
-/* See comments in vhost.c for explanation of next_desc() */
-static unsigned next_desc(struct vring_desc *desc)
-{
-       unsigned int next;
-
-       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
-               return -1U;
-       next = le16toh(desc->next);
-       return next;
-}
-
-/* Sum up all the IOVEC length */
-static ssize_t
-sum_iovec_len(struct mic_copy_desc *copy)
-{
-       ssize_t sum = 0;
-       unsigned int i;
-
-       for (i = 0; i < copy->iovcnt; i++)
-               sum += copy->iov[i].iov_len;
-       return sum;
-}
-
-static inline void verify_out_len(struct mic_info *mic,
-       struct mic_copy_desc *copy)
-{
-       if (copy->out_len != sum_iovec_len(copy)) {
-               mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
-                       mic->name, __func__, __LINE__,
-                       copy->out_len, sum_iovec_len(copy));
-               assert(copy->out_len == sum_iovec_len(copy));
-       }
-}
-
-/* Display an iovec */
-static void
-disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
-          const char *s, int line)
-{
-       unsigned int i;
-
-       for (i = 0; i < copy->iovcnt; i++)
-               mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
-                       mic->name, s, line, i,
-                       copy->iov[i].iov_base, copy->iov[i].iov_len);
-}
-
-static inline __u16 read_avail_idx(struct mic_vring *vr)
-{
-       return ACCESS_ONCE(vr->info->avail_idx);
-}
-
-static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
-                               struct mic_copy_desc *copy, ssize_t len)
-{
-       copy->vr_idx = tx ? 0 : 1;
-       copy->update_used = true;
-       if (type == VIRTIO_ID_NET)
-               copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
-       else
-               copy->iov[0].iov_len = len;
-}
-
-/* Central API which triggers the copies */
-static int
-mic_virtio_copy(struct mic_info *mic, int fd,
-               struct mic_vring *vr, struct mic_copy_desc *copy)
-{
-       int ret;
-
-       ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
-       if (ret) {
-               mpsslog("%s %s %d errno %s ret %d\n",
-                       mic->name, __func__, __LINE__,
-                       strerror(errno), ret);
-       }
-       return ret;
-}
-
-static inline unsigned _vring_size(unsigned int num, unsigned long align)
-{
-       return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
-                               + align - 1) & ~(align - 1))
-               + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
-}
-
-/*
- * This initialization routine requires at least one
- * vring i.e. vr0. vr1 is optional.
- */
-static void *
-init_vr(struct mic_info *mic, int fd, int type,
-       struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
-{
-       int vr_size;
-       char *va;
-
-       vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
-                                        MIC_VIRTIO_RING_ALIGN) +
-                            sizeof(struct _mic_vring_info));
-       va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
-               PROT_READ, MAP_SHARED, fd, 0);
-       if (MAP_FAILED == va) {
-               mpsslog("%s %s %d mmap failed errno %s\n",
-                       mic->name, __func__, __LINE__,
-                       strerror(errno));
-               goto done;
-       }
-       set_dp(mic, type, va);
-       vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
-       vr0->info = vr0->va +
-               _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
-       vring_init(&vr0->vr,
-                  MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
-       mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
-               __func__, mic->name, vr0->va, vr0->info, vr_size,
-               _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
-       mpsslog("magic 0x%x expected 0x%x\n",
-               le32toh(vr0->info->magic), MIC_MAGIC + type);
-       assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
-       if (vr1) {
-               vr1->va = (struct mic_vring *)
-                       &va[MIC_DEVICE_PAGE_END + vr_size];
-               vr1->info = vr1->va + _vring_size(MIC_VRING_ENTRIES,
-                       MIC_VIRTIO_RING_ALIGN);
-               vring_init(&vr1->vr,
-                          MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
-               mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
-                       __func__, mic->name, vr1->va, vr1->info, vr_size,
-                       _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
-               mpsslog("magic 0x%x expected 0x%x\n",
-                       le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
-               assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
-       }
-done:
-       return va;
-}
-
-static int
-wait_for_card_driver(struct mic_info *mic, int fd, int type)
-{
-       struct pollfd pollfd;
-       int err;
-       struct mic_device_desc *desc = get_device_desc(mic, type);
-       __u8 prev_status;
-
-       if (!desc)
-               return -ENODEV;
-       prev_status = desc->status;
-       pollfd.fd = fd;
-       mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
-               mic->name, __func__, type, desc->status);
-
-       while (1) {
-               pollfd.events = POLLIN;
-               pollfd.revents = 0;
-               err = poll(&pollfd, 1, -1);
-               if (err < 0) {
-                       mpsslog("%s %s poll failed %s\n",
-                               mic->name, __func__, strerror(errno));
-                       continue;
-               }
-
-               if (pollfd.revents) {
-                       if (desc->status != prev_status) {
-                               mpsslog("%s %s Waiting... desc-> type %d "
-                                       "status 0x%x\n",
-                                       mic->name, __func__, type,
-                                       desc->status);
-                               prev_status = desc->status;
-                       }
-                       if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
-                               mpsslog("%s %s poll.revents %d\n",
-                                       mic->name, __func__, pollfd.revents);
-                               mpsslog("%s %s desc-> type %d status 0x%x\n",
-                                       mic->name, __func__, type,
-                                       desc->status);
-                               break;
-                       }
-               }
-       }
-       return 0;
-}
-
-/* Spin till we have some descriptors */
-static void
-spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
-{
-       __u16 avail_idx = read_avail_idx(vr);
-
-       while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
-#ifdef DEBUG
-               mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
-                       mic->name, __func__,
-                       le16toh(vr->vr.avail->idx), vr->info->avail_idx);
-#endif
-               sched_yield();
-       }
-}
-
-static void *
-virtio_net(void *arg)
-{
-       static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
-       static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
-       struct iovec vnet_iov[2][2] = {
-               { { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
-                 { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
-               { { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
-                 { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
-       };
-       struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
-       struct mic_info *mic = (struct mic_info *)arg;
-       char if_name[IFNAMSIZ];
-       struct pollfd net_poll[MAX_NET_FD];
-       struct mic_vring tx_vr, rx_vr;
-       struct mic_copy_desc copy;
-       struct mic_device_desc *desc;
-       int err;
-
-       snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
-       mic->mic_net.tap_fd = tun_alloc(mic, if_name);
-       if (mic->mic_net.tap_fd < 0)
-               goto done;
-
-       if (tap_configure(mic, if_name))
-               goto done;
-       mpsslog("MIC name %s id %d\n", mic->name, mic->id);
-
-       net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
-       net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
-       net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
-       net_poll[NET_FD_TUN].events = POLLIN;
-
-       if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
-                                 VIRTIO_ID_NET, &tx_vr, &rx_vr,
-               virtnet_dev_page.dd.num_vq)) {
-               mpsslog("%s init_vr failed %s\n",
-                       mic->name, strerror(errno));
-               goto done;
-       }
-
-       copy.iovcnt = 2;
-       desc = get_device_desc(mic, VIRTIO_ID_NET);
-
-       while (1) {
-               ssize_t len;
-
-               net_poll[NET_FD_VIRTIO_NET].revents = 0;
-               net_poll[NET_FD_TUN].revents = 0;
-
-               /* Start polling for data from tap and virtio net */
-               err = poll(net_poll, 2, -1);
-               if (err < 0) {
-                       mpsslog("%s poll failed %s\n",
-                               __func__, strerror(errno));
-                       continue;
-               }
-               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-                       err = wait_for_card_driver(mic,
-                                                  mic->mic_net.virtio_net_fd,
-                                                  VIRTIO_ID_NET);
-                       if (err) {
-                               mpsslog("%s %s %d Exiting...\n",
-                                       mic->name, __func__, __LINE__);
-                               break;
-                       }
-               }
-               /*
-                * Check if there is data to be read from TUN and write to
-                * virtio net fd if there is.
-                */
-               if (net_poll[NET_FD_TUN].revents & POLLIN) {
-                       copy.iov = iov0;
-                       len = readv(net_poll[NET_FD_TUN].fd,
-                               copy.iov, copy.iovcnt);
-                       if (len > 0) {
-                               struct virtio_net_hdr *hdr
-                                       = (struct virtio_net_hdr *)vnet_hdr[0];
-
-                               /* Disable checksums on the card since we are on
-                                  a reliable PCIe link */
-                               hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
-#ifdef DEBUG
-                               mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
-                                       __func__, __LINE__, hdr->flags);
-                               mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
-                                       copy.out_len, hdr->gso_type);
-#endif
-#ifdef DEBUG
-                               disp_iovec(mic, copy, __func__, __LINE__);
-                               mpsslog("%s %s %d read from tap 0x%lx\n",
-                                       mic->name, __func__, __LINE__,
-                                       len);
-#endif
-                               spin_for_descriptors(mic, &tx_vr);
-                               txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
-                                            len);
-
-                               err = mic_virtio_copy(mic,
-                                       mic->mic_net.virtio_net_fd, &tx_vr,
-                                       &copy);
-                               if (err < 0) {
-                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
-                                               mic->name, __func__, __LINE__,
-                                               strerror(errno));
-                               }
-                               if (!err)
-                                       verify_out_len(mic, &copy);
-#ifdef DEBUG
-                               disp_iovec(mic, copy, __func__, __LINE__);
-                               mpsslog("%s %s %d wrote to net 0x%lx\n",
-                                       mic->name, __func__, __LINE__,
-                                       sum_iovec_len(&copy));
-#endif
-                               /* Reinitialize IOV for next run */
-                               iov0[1].iov_len = MAX_NET_PKT_SIZE;
-                       } else if (len < 0) {
-                               disp_iovec(mic, &copy, __func__, __LINE__);
-                               mpsslog("%s %s %d read failed %s ", mic->name,
-                                       __func__, __LINE__, strerror(errno));
-                               mpsslog("cnt %d sum %zd\n",
-                                       copy.iovcnt, sum_iovec_len(&copy));
-                       }
-               }
-
-               /*
-                * Check if there is data to be read from virtio net and
-                * write to TUN if there is.
-                */
-               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
-                       while (rx_vr.info->avail_idx !=
-                               le16toh(rx_vr.vr.avail->idx)) {
-                               copy.iov = iov1;
-                               txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
-                                            MAX_NET_PKT_SIZE
-                                       + sizeof(struct virtio_net_hdr));
-
-                               err = mic_virtio_copy(mic,
-                                       mic->mic_net.virtio_net_fd, &rx_vr,
-                                       &copy);
-                               if (!err) {
-#ifdef DEBUG
-                                       struct virtio_net_hdr *hdr
-                                               = (struct virtio_net_hdr *)
-                                                       vnet_hdr[1];
-
-                                       mpsslog("%s %s %d hdr->flags 0x%x, ",
-                                               mic->name, __func__, __LINE__,
-                                               hdr->flags);
-                                       mpsslog("out_len %d gso_type 0x%x\n",
-                                               copy.out_len,
-                                               hdr->gso_type);
-#endif
-                                       /* Set the correct output iov_len */
-                                       iov1[1].iov_len = copy.out_len -
-                                               sizeof(struct virtio_net_hdr);
-                                       verify_out_len(mic, &copy);
-#ifdef DEBUG
-                                       disp_iovec(mic, copy, __func__,
-                                                  __LINE__);
-                                       mpsslog("%s %s %d ",
-                                               mic->name, __func__, __LINE__);
-                                       mpsslog("read from net 0x%lx\n",
-                                               sum_iovec_len(copy));
-#endif
-                                       len = writev(net_poll[NET_FD_TUN].fd,
-                                               copy.iov, copy.iovcnt);
-                                       if (len != sum_iovec_len(&copy)) {
-                                               mpsslog("Tun write failed %s ",
-                                                       strerror(errno));
-                                               mpsslog("len 0x%zx ", len);
-                                               mpsslog("read_len 0x%zx\n",
-                                                       sum_iovec_len(&copy));
-                                       } else {
-#ifdef DEBUG
-                                               disp_iovec(mic, &copy, __func__,
-                                                          __LINE__);
-                                               mpsslog("%s %s %d ",
-                                                       mic->name, __func__,
-                                                       __LINE__);
-                                               mpsslog("wrote to tap 0x%lx\n",
-                                                       len);
-#endif
-                                       }
-                               } else {
-                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
-                                               mic->name, __func__, __LINE__,
-                                               strerror(errno));
-                                       break;
-                               }
-                       }
-               }
-               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
-                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
-       }
-done:
-       pthread_exit(NULL);
-}
-
-/* virtio_console */
-#define VIRTIO_CONSOLE_FD 0
-#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
-#define MAX_CONSOLE_FD (MONITOR_FD + 1)  /* must be the last one + 1 */
-#define MAX_BUFFER_SIZE PAGE_SIZE
-
-static void *
-virtio_console(void *arg)
-{
-       static __u8 vcons_buf[2][PAGE_SIZE];
-       struct iovec vcons_iov[2] = {
-               { .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
-               { .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
-       };
-       struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
-       struct mic_info *mic = (struct mic_info *)arg;
-       int err;
-       struct pollfd console_poll[MAX_CONSOLE_FD];
-       int pty_fd;
-       char *pts_name;
-       ssize_t len;
-       struct mic_vring tx_vr, rx_vr;
-       struct mic_copy_desc copy;
-       struct mic_device_desc *desc;
-
-       pty_fd = posix_openpt(O_RDWR);
-       if (pty_fd < 0) {
-               mpsslog("can't open a pseudoterminal master device: %s\n",
-                       strerror(errno));
-               goto _return;
-       }
-       pts_name = ptsname(pty_fd);
-       if (pts_name == NULL) {
-               mpsslog("can't get pts name\n");
-               goto _close_pty;
-       }
-       printf("%s console message goes to %s\n", mic->name, pts_name);
-       mpsslog("%s console message goes to %s\n", mic->name, pts_name);
-       err = grantpt(pty_fd);
-       if (err < 0) {
-               mpsslog("can't grant access: %s %s\n",
-                       pts_name, strerror(errno));
-               goto _close_pty;
-       }
-       err = unlockpt(pty_fd);
-       if (err < 0) {
-               mpsslog("can't unlock a pseudoterminal: %s %s\n",
-                       pts_name, strerror(errno));
-               goto _close_pty;
-       }
-       console_poll[MONITOR_FD].fd = pty_fd;
-       console_poll[MONITOR_FD].events = POLLIN;
-
-       console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
-       console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
-
-       if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
-                                 VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
-               virtcons_dev_page.dd.num_vq)) {
-               mpsslog("%s init_vr failed %s\n",
-                       mic->name, strerror(errno));
-               goto _close_pty;
-       }
-
-       copy.iovcnt = 1;
-       desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
-
-       for (;;) {
-               console_poll[MONITOR_FD].revents = 0;
-               console_poll[VIRTIO_CONSOLE_FD].revents = 0;
-               err = poll(console_poll, MAX_CONSOLE_FD, -1);
-               if (err < 0) {
-                       mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
-                               strerror(errno));
-                       continue;
-               }
-               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-                       err = wait_for_card_driver(mic,
-                                       mic->mic_console.virtio_console_fd,
-                                       VIRTIO_ID_CONSOLE);
-                       if (err) {
-                               mpsslog("%s %s %d Exiting...\n",
-                                       mic->name, __func__, __LINE__);
-                               break;
-                       }
-               }
-
-               if (console_poll[MONITOR_FD].revents & POLLIN) {
-                       copy.iov = iov0;
-                       len = readv(pty_fd, copy.iov, copy.iovcnt);
-                       if (len > 0) {
-#ifdef DEBUG
-                               disp_iovec(mic, copy, __func__, __LINE__);
-                               mpsslog("%s %s %d read from tap 0x%lx\n",
-                                       mic->name, __func__, __LINE__,
-                                       len);
-#endif
-                               spin_for_descriptors(mic, &tx_vr);
-                               txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
-                                            &copy, len);
-
-                               err = mic_virtio_copy(mic,
-                                       mic->mic_console.virtio_console_fd,
-                                       &tx_vr, &copy);
-                               if (err < 0) {
-                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
-                                               mic->name, __func__, __LINE__,
-                                               strerror(errno));
-                               }
-                               if (!err)
-                                       verify_out_len(mic, &copy);
-#ifdef DEBUG
-                               disp_iovec(mic, copy, __func__, __LINE__);
-                               mpsslog("%s %s %d wrote to net 0x%lx\n",
-                                       mic->name, __func__, __LINE__,
-                                       sum_iovec_len(copy));
-#endif
-                               /* Reinitialize IOV for next run */
-                               iov0->iov_len = PAGE_SIZE;
-                       } else if (len < 0) {
-                               disp_iovec(mic, &copy, __func__, __LINE__);
-                               mpsslog("%s %s %d read failed %s ",
-                                       mic->name, __func__, __LINE__,
-                                       strerror(errno));
-                               mpsslog("cnt %d sum %zd\n",
-                                       copy.iovcnt, sum_iovec_len(&copy));
-                       }
-               }
-
-               if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
-                       while (rx_vr.info->avail_idx !=
-                               le16toh(rx_vr.vr.avail->idx)) {
-                               copy.iov = iov1;
-                               txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
-                                            &copy, PAGE_SIZE);
-
-                               err = mic_virtio_copy(mic,
-                                       mic->mic_console.virtio_console_fd,
-                                       &rx_vr, &copy);
-                               if (!err) {
-                                       /* Set the correct output iov_len */
-                                       iov1->iov_len = copy.out_len;
-                                       verify_out_len(mic, &copy);
-#ifdef DEBUG
-                                       disp_iovec(mic, copy, __func__,
-                                                  __LINE__);
-                                       mpsslog("%s %s %d ",
-                                               mic->name, __func__, __LINE__);
-                                       mpsslog("read from net 0x%lx\n",
-                                               sum_iovec_len(copy));
-#endif
-                                       len = writev(pty_fd,
-                                               copy.iov, copy.iovcnt);
-                                       if (len != sum_iovec_len(&copy)) {
-                                               mpsslog("Tun write failed %s ",
-                                                       strerror(errno));
-                                               mpsslog("len 0x%zx ", len);
-                                               mpsslog("read_len 0x%zx\n",
-                                                       sum_iovec_len(&copy));
-                                       } else {
-#ifdef DEBUG
-                                               disp_iovec(mic, copy, __func__,
-                                                          __LINE__);
-                                               mpsslog("%s %s %d ",
-                                                       mic->name, __func__,
-                                                       __LINE__);
-                                               mpsslog("wrote to tap 0x%lx\n",
-                                                       len);
-#endif
-                                       }
-                               } else {
-                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
-                                               mic->name, __func__, __LINE__,
-                                               strerror(errno));
-                                       break;
-                               }
-                       }
-               }
-               if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
-                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
-       }
-_close_pty:
-       close(pty_fd);
-_return:
-       pthread_exit(NULL);
-}
-
-static void
-add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
-{
-       char path[PATH_MAX];
-       int fd, err;
-
-       snprintf(path, PATH_MAX, "/dev/vop_virtio%d", mic->id);
-       fd = open(path, O_RDWR);
-       if (fd < 0) {
-               mpsslog("Could not open %s %s\n", path, strerror(errno));
-               return;
-       }
-
-       err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
-       if (err < 0) {
-               mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
-               close(fd);
-               return;
-       }
-       switch (dd->type) {
-       case VIRTIO_ID_NET:
-               mic->mic_net.virtio_net_fd = fd;
-               mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
-               break;
-       case VIRTIO_ID_CONSOLE:
-               mic->mic_console.virtio_console_fd = fd;
-               mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
-               break;
-       case VIRTIO_ID_BLOCK:
-               mic->mic_virtblk.virtio_block_fd = fd;
-               mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
-               break;
-       }
-}
-
-static bool
-set_backend_file(struct mic_info *mic)
-{
-       FILE *config;
-       char buff[PATH_MAX], *line, *evv, *p;
-
-       snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
-       config = fopen(buff, "r");
-       if (config == NULL)
-               return false;
-       do {  /* look for "virtblk_backend=XXXX" */
-               line = fgets(buff, PATH_MAX, config);
-               if (line == NULL)
-                       break;
-               if (*line == '#')
-                       continue;
-               p = strchr(line, '\n');
-               if (p)
-                       *p = '\0';
-       } while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
-       fclose(config);
-       if (line == NULL)
-               return false;
-       evv = strchr(line, '=');
-       if (evv == NULL)
-               return false;
-       mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
-       if (mic->mic_virtblk.backend_file == NULL) {
-               mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
-               return false;
-       }
-       strcpy(mic->mic_virtblk.backend_file, evv + 1);
-       return true;
-}
-
-#define SECTOR_SIZE 512
-static bool
-set_backend_size(struct mic_info *mic)
-{
-       mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
-               SEEK_END);
-       if (mic->mic_virtblk.backend_size < 0) {
-               mpsslog("%s: can't seek: %s\n",
-                       mic->name, mic->mic_virtblk.backend_file);
-               return false;
-       }
-       virtblk_dev_page.blk_config.capacity =
-               mic->mic_virtblk.backend_size / SECTOR_SIZE;
-       if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
-               virtblk_dev_page.blk_config.capacity++;
-
-       virtblk_dev_page.blk_config.capacity =
-               htole64(virtblk_dev_page.blk_config.capacity);
-
-       return true;
-}
-
-static bool
-open_backend(struct mic_info *mic)
-{
-       if (!set_backend_file(mic))
-               goto _error_exit;
-       mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
-       if (mic->mic_virtblk.backend < 0) {
-               mpsslog("%s: can't open: %s\n", mic->name,
-                       mic->mic_virtblk.backend_file);
-               goto _error_free;
-       }
-       if (!set_backend_size(mic))
-               goto _error_close;
-       mic->mic_virtblk.backend_addr = mmap(NULL,
-               mic->mic_virtblk.backend_size,
-               PROT_READ|PROT_WRITE, MAP_SHARED,
-               mic->mic_virtblk.backend, 0L);
-       if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
-               mpsslog("%s: can't map: %s %s\n",
-                       mic->name, mic->mic_virtblk.backend_file,
-                       strerror(errno));
-               goto _error_close;
-       }
-       return true;
-
- _error_close:
-       close(mic->mic_virtblk.backend);
- _error_free:
-       free(mic->mic_virtblk.backend_file);
- _error_exit:
-       return false;
-}
-
-static void
-close_backend(struct mic_info *mic)
-{
-       munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
-       close(mic->mic_virtblk.backend);
-       free(mic->mic_virtblk.backend_file);
-}
-
-static bool
-start_virtblk(struct mic_info *mic, struct mic_vring *vring)
-{
-       if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
-               mpsslog("%s: blk_config is not 8 byte aligned.\n",
-                       mic->name);
-               return false;
-       }
-       add_virtio_device(mic, &virtblk_dev_page.dd);
-       if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
-                                 VIRTIO_ID_BLOCK, vring, NULL,
-                                 virtblk_dev_page.dd.num_vq)) {
-               mpsslog("%s init_vr failed %s\n",
-                       mic->name, strerror(errno));
-               return false;
-       }
-       return true;
-}
-
-static void
-stop_virtblk(struct mic_info *mic)
-{
-       int vr_size, ret;
-
-       vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
-                                        MIC_VIRTIO_RING_ALIGN) +
-                            sizeof(struct _mic_vring_info));
-       ret = munmap(mic->mic_virtblk.block_dp,
-               MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
-       if (ret < 0)
-               mpsslog("%s munmap errno %d\n", mic->name, errno);
-       close(mic->mic_virtblk.virtio_block_fd);
-}
-
-static __u8
-header_error_check(struct vring_desc *desc)
-{
-       if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
-               mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
-                       __func__, __LINE__);
-               return -EIO;
-       }
-       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
-               mpsslog("%s() %d: alone\n",
-                       __func__, __LINE__);
-               return -EIO;
-       }
-       if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
-               mpsslog("%s() %d: not read\n",
-                       __func__, __LINE__);
-               return -EIO;
-       }
-       return 0;
-}
-
-static int
-read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
-{
-       struct iovec iovec;
-       struct mic_copy_desc copy;
-
-       iovec.iov_len = sizeof(*hdr);
-       iovec.iov_base = hdr;
-       copy.iov = &iovec;
-       copy.iovcnt = 1;
-       copy.vr_idx = 0;  /* only one vring on virtio_block */
-       copy.update_used = false;  /* do not update used index */
-       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
-}
-
-static int
-transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
-{
-       struct mic_copy_desc copy;
-
-       copy.iov = iovec;
-       copy.iovcnt = iovcnt;
-       copy.vr_idx = 0;  /* only one vring on virtio_block */
-       copy.update_used = false;  /* do not update used index */
-       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
-}
-
-static __u8
-status_error_check(struct vring_desc *desc)
-{
-       if (le32toh(desc->len) != sizeof(__u8)) {
-               mpsslog("%s() %d: length is not sizeof(status)\n",
-                       __func__, __LINE__);
-               return -EIO;
-       }
-       return 0;
-}
-
-static int
-write_status(int fd, __u8 *status)
-{
-       struct iovec iovec;
-       struct mic_copy_desc copy;
-
-       iovec.iov_base = status;
-       iovec.iov_len = sizeof(*status);
-       copy.iov = &iovec;
-       copy.iovcnt = 1;
-       copy.vr_idx = 0;  /* only one vring on virtio_block */
-       copy.update_used = true; /* Update used index */
-       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
-}
-
-#ifndef VIRTIO_BLK_T_GET_ID
-#define VIRTIO_BLK_T_GET_ID    8
-#endif
-
-static void *
-virtio_block(void *arg)
-{
-       struct mic_info *mic = (struct mic_info *)arg;
-       int ret;
-       struct pollfd block_poll;
-       struct mic_vring vring;
-       __u16 avail_idx;
-       __u32 desc_idx;
-       struct vring_desc *desc;
-       struct iovec *iovec, *piov;
-       __u8 status;
-       __u32 buffer_desc_idx;
-       struct virtio_blk_outhdr hdr;
-       void *fos;
-
-       for (;;) {  /* forever */
-               if (!open_backend(mic)) { /* No virtblk */
-                       for (mic->mic_virtblk.signaled = 0;
-                               !mic->mic_virtblk.signaled;)
-                               sleep(1);
-                       continue;
-               }
-
-               /* backend file is specified. */
-               if (!start_virtblk(mic, &vring))
-                       goto _close_backend;
-               iovec = malloc(sizeof(*iovec) *
-                       le32toh(virtblk_dev_page.blk_config.seg_max));
-               if (!iovec) {
-                       mpsslog("%s: can't alloc iovec: %s\n",
-                               mic->name, strerror(ENOMEM));
-                       goto _stop_virtblk;
-               }
-
-               block_poll.fd = mic->mic_virtblk.virtio_block_fd;
-               block_poll.events = POLLIN;
-               for (mic->mic_virtblk.signaled = 0;
-                    !mic->mic_virtblk.signaled;) {
-                       block_poll.revents = 0;
-                                       /* timeout in 1 sec to see signaled */
-                       ret = poll(&block_poll, 1, 1000);
-                       if (ret < 0) {
-                               mpsslog("%s %d: poll failed: %s\n",
-                                       __func__, __LINE__,
-                                       strerror(errno));
-                               continue;
-                       }
-
-                       if (!(block_poll.revents & POLLIN)) {
-#ifdef DEBUG
-                               mpsslog("%s %d: block_poll.revents=0x%x\n",
-                                       __func__, __LINE__, block_poll.revents);
-#endif
-                               continue;
-                       }
-
-                       /* POLLIN */
-                       while (vring.info->avail_idx !=
-                               le16toh(vring.vr.avail->idx)) {
-                               /* read header element */
-                               avail_idx =
-                                       vring.info->avail_idx &
-                                       (vring.vr.num - 1);
-                               desc_idx = le16toh(
-                                       vring.vr.avail->ring[avail_idx]);
-                               desc = &vring.vr.desc[desc_idx];
-#ifdef DEBUG
-                               mpsslog("%s() %d: avail_idx=%d ",
-                                       __func__, __LINE__,
-                                       vring.info->avail_idx);
-                               mpsslog("vring.vr.num=%d desc=%p\n",
-                                       vring.vr.num, desc);
-#endif
-                               status = header_error_check(desc);
-                               ret = read_header(
-                                       mic->mic_virtblk.virtio_block_fd,
-                                       &hdr, desc_idx);
-                               if (ret < 0) {
-                                       mpsslog("%s() %d %s: ret=%d %s\n",
-                                               __func__, __LINE__,
-                                               mic->name, ret,
-                                               strerror(errno));
-                                       break;
-                               }
-                               /* buffer element */
-                               piov = iovec;
-                               status = 0;
-                               fos = mic->mic_virtblk.backend_addr +
-                                       (hdr.sector * SECTOR_SIZE);
-                               buffer_desc_idx = next_desc(desc);
-                               desc_idx = buffer_desc_idx;
-                               for (desc = &vring.vr.desc[buffer_desc_idx];
-                                    desc->flags & VRING_DESC_F_NEXT;
-                                    desc_idx = next_desc(desc),
-                                            desc = &vring.vr.desc[desc_idx]) {
-                                       piov->iov_len = desc->len;
-                                       piov->iov_base = fos;
-                                       piov++;
-                                       fos += desc->len;
-                               }
-                               /* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
-                               if (hdr.type & ~(VIRTIO_BLK_T_OUT |
-                                       VIRTIO_BLK_T_GET_ID)) {
-                                       /*
-                                         VIRTIO_BLK_T_IN - does not do
-                                         anything. Probably for documenting.
-                                         VIRTIO_BLK_T_SCSI_CMD - for
-                                         virtio_scsi.
-                                         VIRTIO_BLK_T_FLUSH - turned off in
-                                         config space.
-                                         VIRTIO_BLK_T_BARRIER - defined but not
-                                         used in anywhere.
-                                       */
-                                       mpsslog("%s() %d: type %x ",
-                                               __func__, __LINE__,
-                                               hdr.type);
-                                       mpsslog("is not supported\n");
-                                       status = -ENOTSUP;
-
-                               } else {
-                                       ret = transfer_blocks(
-                                       mic->mic_virtblk.virtio_block_fd,
-                                               iovec,
-                                               piov - iovec);
-                                       if (ret < 0 &&
-                                           status != 0)
-                                               status = ret;
-                               }
-                               /* write status and update used pointer */
-                               if (status != 0)
-                                       status = status_error_check(desc);
-                               ret = write_status(
-                                       mic->mic_virtblk.virtio_block_fd,
-                                       &status);
-#ifdef DEBUG
-                               mpsslog("%s() %d: write status=%d on desc=%p\n",
-                                       __func__, __LINE__,
-                                       status, desc);
-#endif
-                       }
-               }
-               free(iovec);
-_stop_virtblk:
-               stop_virtblk(mic);
-_close_backend:
-               close_backend(mic);
-       }  /* forever */
-
-       pthread_exit(NULL);
-}
-
-static void
-reset(struct mic_info *mic)
-{
-#define RESET_TIMEOUT 120
-       int i = RESET_TIMEOUT;
-       setsysfs(mic->name, "state", "reset");
-       while (i) {
-               char *state;
-               state = readsysfs(mic->name, "state");
-               if (!state)
-                       goto retry;
-               mpsslog("%s: %s %d state %s\n",
-                       mic->name, __func__, __LINE__, state);
-
-               if (!strcmp(state, "ready")) {
-                       free(state);
-                       break;
-               }
-               free(state);
-retry:
-               sleep(1);
-               i--;
-       }
-}
-
-static int
-get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
-{
-       if (!strcmp(shutdown_status, "nop"))
-               return MIC_NOP;
-       if (!strcmp(shutdown_status, "crashed"))
-               return MIC_CRASHED;
-       if (!strcmp(shutdown_status, "halted"))
-               return MIC_HALTED;
-       if (!strcmp(shutdown_status, "poweroff"))
-               return MIC_POWER_OFF;
-       if (!strcmp(shutdown_status, "restart"))
-               return MIC_RESTART;
-       mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
-       /* Invalid state */
-       assert(0);
-};
-
-static int get_mic_state(struct mic_info *mic)
-{
-       char *state = NULL;
-       enum mic_states mic_state;
-
-       while (!state) {
-               state = readsysfs(mic->name, "state");
-               sleep(1);
-       }
-       mpsslog("%s: %s %d state %s\n",
-               mic->name, __func__, __LINE__, state);
-
-       if (!strcmp(state, "ready")) {
-               mic_state = MIC_READY;
-       } else if (!strcmp(state, "booting")) {
-               mic_state = MIC_BOOTING;
-       } else if (!strcmp(state, "online")) {
-               mic_state = MIC_ONLINE;
-       } else if (!strcmp(state, "shutting_down")) {
-               mic_state = MIC_SHUTTING_DOWN;
-       } else if (!strcmp(state, "reset_failed")) {
-               mic_state = MIC_RESET_FAILED;
-       } else if (!strcmp(state, "resetting")) {
-               mic_state = MIC_RESETTING;
-       } else {
-               mpsslog("%s: BUG invalid state %s\n", mic->name, state);
-               assert(0);
-       }
-
-       free(state);
-       return mic_state;
-};
-
-static void mic_handle_shutdown(struct mic_info *mic)
-{
-#define SHUTDOWN_TIMEOUT 60
-       int i = SHUTDOWN_TIMEOUT;
-       char *shutdown_status;
-       while (i) {
-               shutdown_status = readsysfs(mic->name, "shutdown_status");
-               if (!shutdown_status) {
-                       sleep(1);
-                       continue;
-               }
-               mpsslog("%s: %s %d shutdown_status %s\n",
-                       mic->name, __func__, __LINE__, shutdown_status);
-               switch (get_mic_shutdown_status(mic, shutdown_status)) {
-               case MIC_RESTART:
-                       mic->restart = 1;
-               case MIC_HALTED:
-               case MIC_POWER_OFF:
-               case MIC_CRASHED:
-                       free(shutdown_status);
-                       goto reset;
-               default:
-                       break;
-               }
-               free(shutdown_status);
-               sleep(1);
-               i--;
-       }
-reset:
-       if (!i)
-               mpsslog("%s: %s %d timing out waiting for shutdown_status %s\n",
-                       mic->name, __func__, __LINE__, shutdown_status);
-       reset(mic);
-}
-
-static int open_state_fd(struct mic_info *mic)
-{
-       char pathname[PATH_MAX];
-       int fd;
-
-       snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
-                MICSYSFSDIR, mic->name, "state");
-
-       fd = open(pathname, O_RDONLY);
-       if (fd < 0)
-               mpsslog("%s: opening file %s failed %s\n",
-                       mic->name, pathname, strerror(errno));
-       return fd;
-}
-
-static int block_till_state_change(int fd, struct mic_info *mic)
-{
-       struct pollfd ufds[1];
-       char value[PAGE_SIZE];
-       int ret;
-
-       ufds[0].fd = fd;
-       ufds[0].events = POLLERR | POLLPRI;
-       ret = poll(ufds, 1, -1);
-       if (ret < 0) {
-               mpsslog("%s: %s %d poll failed %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               return ret;
-       }
-
-       ret = lseek(fd, 0, SEEK_SET);
-       if (ret < 0) {
-               mpsslog("%s: %s %d Failed to seek to 0: %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               return ret;
-       }
-
-       ret = read(fd, value, sizeof(value));
-       if (ret < 0) {
-               mpsslog("%s: %s %d Failed to read sysfs entry: %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               return ret;
-       }
-
-       return 0;
-}
-
-static void *
-mic_config(void *arg)
-{
-       struct mic_info *mic = (struct mic_info *)arg;
-       int fd, ret, stat = 0;
-
-       fd = open_state_fd(mic);
-       if (fd < 0) {
-               mpsslog("%s: %s %d open state fd failed %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               goto exit;
-       }
-
-       do {
-               ret = block_till_state_change(fd, mic);
-               if (ret < 0) {
-                       mpsslog("%s: %s %d block_till_state_change error %s\n",
-                               mic->name, __func__, __LINE__, strerror(errno));
-                       goto close_exit;
-               }
-
-               switch (get_mic_state(mic)) {
-               case MIC_SHUTTING_DOWN:
-                       mic_handle_shutdown(mic);
-                       break;
-               case MIC_READY:
-               case MIC_RESET_FAILED:
-                       ret = kill(mic->pid, SIGTERM);
-                       mpsslog("%s: %s %d kill pid %d ret %d\n",
-                               mic->name, __func__, __LINE__,
-                               mic->pid, ret);
-                       if (!ret) {
-                               ret = waitpid(mic->pid, &stat,
-                                             WIFSIGNALED(stat));
-                               mpsslog("%s: %s %d waitpid ret %d pid %d\n",
-                                       mic->name, __func__, __LINE__,
-                                       ret, mic->pid);
-                       }
-                       if (mic->boot_on_resume) {
-                               setsysfs(mic->name, "state", "boot");
-                               mic->boot_on_resume = 0;
-                       }
-                       goto close_exit;
-               default:
-                       break;
-               }
-       } while (1);
-
-close_exit:
-       close(fd);
-exit:
-       init_mic(mic);
-       pthread_exit(NULL);
-}
-
-static void
-set_cmdline(struct mic_info *mic)
-{
-       char buffer[PATH_MAX];
-       int len;
-
-       len = snprintf(buffer, PATH_MAX,
-               "clocksource=tsc highres=off nohz=off ");
-       len += snprintf(buffer + len, PATH_MAX - len,
-               "cpufreq_on;corec6_off;pc3_off;pc6_off ");
-       len += snprintf(buffer + len, PATH_MAX - len,
-               "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
-               mic->id + 1);
-
-       setsysfs(mic->name, "cmdline", buffer);
-       mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
-       snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id + 1);
-       mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
-}
-
-static void
-set_log_buf_info(struct mic_info *mic)
-{
-       int fd;
-       off_t len;
-       char system_map[] = "/lib/firmware/mic/System.map";
-       char *map, *temp, log_buf[17] = {'\0'};
-
-       fd = open(system_map, O_RDONLY);
-       if (fd < 0) {
-               mpsslog("%s: Opening System.map failed: %d\n",
-                       mic->name, errno);
-               return;
-       }
-       len = lseek(fd, 0, SEEK_END);
-       if (len < 0) {
-               mpsslog("%s: Reading System.map size failed: %d\n",
-                       mic->name, errno);
-               close(fd);
-               return;
-       }
-       map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (map == MAP_FAILED) {
-               mpsslog("%s: mmap of System.map failed: %d\n",
-                       mic->name, errno);
-               close(fd);
-               return;
-       }
-       temp = strstr(map, "__log_buf");
-       if (!temp) {
-               mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
-               munmap(map, len);
-               close(fd);
-               return;
-       }
-       strncpy(log_buf, temp - 19, 16);
-       setsysfs(mic->name, "log_buf_addr", log_buf);
-       mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
-       temp = strstr(map, "log_buf_len");
-       if (!temp) {
-               mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
-               munmap(map, len);
-               close(fd);
-               return;
-       }
-       strncpy(log_buf, temp - 19, 16);
-       setsysfs(mic->name, "log_buf_len", log_buf);
-       mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
-       munmap(map, len);
-       close(fd);
-}
-
-static void
-change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
-{
-       struct mic_info *mic;
-
-       for (mic = mic_list.next; mic != NULL; mic = mic->next)
-               mic->mic_virtblk.signaled = 1/* true */;
-}
-
-static void
-set_mic_boot_params(struct mic_info *mic)
-{
-       set_log_buf_info(mic);
-       set_cmdline(mic);
-}
-
-static void *
-init_mic(void *arg)
-{
-       struct mic_info *mic = (struct mic_info *)arg;
-       struct sigaction ignore = {
-               .sa_flags = 0,
-               .sa_handler = SIG_IGN
-       };
-       struct sigaction act = {
-               .sa_flags = SA_SIGINFO,
-               .sa_sigaction = change_virtblk_backend,
-       };
-       char buffer[PATH_MAX];
-       int err, fd;
-
-       /*
-        * Currently, one virtio block device is supported for each MIC card
-        * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
-        * The signal informs the virtio block backend about a change in the
-        * configuration file which specifies the virtio backend file name on
-        * the host. Virtio block backend then re-reads the configuration file
-        * and switches to the new block device. This signalling mechanism may
-        * not be required once multiple virtio block devices are supported by
-        * the MIC daemon.
-        */
-       sigaction(SIGUSR1, &ignore, NULL);
-retry:
-       fd = open_state_fd(mic);
-       if (fd < 0) {
-               mpsslog("%s: %s %d open state fd failed %s\n",
-                       mic->name, __func__, __LINE__, strerror(errno));
-               sleep(2);
-               goto retry;
-       }
-
-       if (mic->restart) {
-               snprintf(buffer, PATH_MAX, "boot");
-               setsysfs(mic->name, "state", buffer);
-               mpsslog("%s restarting mic %d\n",
-                       mic->name, mic->restart);
-               mic->restart = 0;
-       }
-
-       while (1) {
-               while (block_till_state_change(fd, mic)) {
-                       mpsslog("%s: %s %d block_till_state_change error %s\n",
-                               mic->name, __func__, __LINE__, strerror(errno));
-                       sleep(2);
-                       continue;
-               }
-
-               if (get_mic_state(mic) == MIC_BOOTING)
-                       break;
-       }
-
-       mic->pid = fork();
-       switch (mic->pid) {
-       case 0:
-               add_virtio_device(mic, &virtcons_dev_page.dd);
-               add_virtio_device(mic, &virtnet_dev_page.dd);
-               err = pthread_create(&mic->mic_console.console_thread, NULL,
-                       virtio_console, mic);
-               if (err)
-                       mpsslog("%s virtcons pthread_create failed %s\n",
-                               mic->name, strerror(err));
-               err = pthread_create(&mic->mic_net.net_thread, NULL,
-                       virtio_net, mic);
-               if (err)
-                       mpsslog("%s virtnet pthread_create failed %s\n",
-                               mic->name, strerror(err));
-               err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
-                       virtio_block, mic);
-               if (err)
-                       mpsslog("%s virtblk pthread_create failed %s\n",
-                               mic->name, strerror(err));
-               sigemptyset(&act.sa_mask);
-               err = sigaction(SIGUSR1, &act, NULL);
-               if (err)
-                       mpsslog("%s sigaction SIGUSR1 failed %s\n",
-                               mic->name, strerror(errno));
-               while (1)
-                       sleep(60);
-       case -1:
-               mpsslog("fork failed MIC name %s id %d errno %d\n",
-                       mic->name, mic->id, errno);
-               break;
-       default:
-               err = pthread_create(&mic->config_thread, NULL,
-                                    mic_config, mic);
-               if (err)
-                       mpsslog("%s mic_config pthread_create failed %s\n",
-                               mic->name, strerror(err));
-       }
-
-       return NULL;
-}
-
-static void
-start_daemon(void)
-{
-       struct mic_info *mic;
-       int err;
-
-       for (mic = mic_list.next; mic; mic = mic->next) {
-               set_mic_boot_params(mic);
-               err = pthread_create(&mic->init_thread, NULL, init_mic, mic);
-               if (err)
-                       mpsslog("%s init_mic pthread_create failed %s\n",
-                               mic->name, strerror(err));
-       }
-
-       while (1)
-               sleep(60);
-}
-
-static int
-init_mic_list(void)
-{
-       struct mic_info *mic = &mic_list;
-       struct dirent *file;
-       DIR *dp;
-       int cnt = 0;
-
-       dp = opendir(MICSYSFSDIR);
-       if (!dp)
-               return 0;
-
-       while ((file = readdir(dp)) != NULL) {
-               if (!strncmp(file->d_name, "mic", 3)) {
-                       mic->next = calloc(1, sizeof(struct mic_info));
-                       if (mic->next) {
-                               mic = mic->next;
-                               mic->id = atoi(&file->d_name[3]);
-                               mic->name = malloc(strlen(file->d_name) + 16);
-                               if (mic->name)
-                                       strcpy(mic->name, file->d_name);
-                               mpsslog("MIC name %s id %d\n", mic->name,
-                                       mic->id);
-                               cnt++;
-                       }
-               }
-       }
-
-       closedir(dp);
-       return cnt;
-}
-
-void
-mpsslog(char *format, ...)
-{
-       va_list args;
-       char buffer[4096];
-       char ts[52], *ts1;
-       time_t t;
-
-       if (logfp == NULL)
-               return;
-
-       va_start(args, format);
-       vsprintf(buffer, format, args);
-       va_end(args);
-
-       time(&t);
-       ts1 = ctime_r(&t, ts);
-       ts1[strlen(ts1) - 1] = '\0';
-       fprintf(logfp, "%s: %s", ts1, buffer);
-
-       fflush(logfp);
-}
-
-int
-main(int argc, char *argv[])
-{
-       int cnt;
-       pid_t pid;
-
-       myname = argv[0];
-
-       logfp = fopen(LOGFILE_NAME, "a+");
-       if (!logfp) {
-               fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
-               exit(1);
-       }
-       pid = fork();
-       switch (pid) {
-       case 0:
-               break;
-       case -1:
-               exit(2);
-       default:
-               exit(0);
-       }
-
-       mpsslog("MIC Daemon start\n");
-
-       cnt = init_mic_list();
-       if (cnt == 0) {
-               mpsslog("MIC module not loaded\n");
-               exit(3);
-       }
-       mpsslog("MIC found %d devices\n", cnt);
-
-       start_daemon();
-
-       exit(0);
-}
diff --git a/Documentation/mic/mpssd/mpssd.h b/Documentation/mic/mpssd/mpssd.h
deleted file mode 100644 (file)
index 8bd6494..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Intel MIC Platform Software Stack (MPSS)
- *
- * Copyright(c) 2013 Intel Corporation.
- *
- * 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.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Intel MIC User Space Tools.
- */
-#ifndef _MPSSD_H_
-#define _MPSSD_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/dir.h>
-#include <sys/ioctl.h>
-#include <sys/poll.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <signal.h>
-#include <limits.h>
-#include <syslog.h>
-#include <getopt.h>
-#include <net/if.h>
-#include <linux/if_tun.h>
-#include <linux/if_tun.h>
-#include <linux/virtio_ids.h>
-
-#define MICSYSFSDIR "/sys/class/mic"
-#define LOGFILE_NAME "/var/log/mpssd"
-#define PAGE_SIZE 4096
-
-struct mic_console_info {
-       pthread_t       console_thread;
-       int             virtio_console_fd;
-       void            *console_dp;
-};
-
-struct mic_net_info {
-       pthread_t       net_thread;
-       int             virtio_net_fd;
-       int             tap_fd;
-       void            *net_dp;
-};
-
-struct mic_virtblk_info {
-       pthread_t       block_thread;
-       int             virtio_block_fd;
-       void            *block_dp;
-       volatile sig_atomic_t   signaled;
-       char            *backend_file;
-       int             backend;
-       void            *backend_addr;
-       long            backend_size;
-};
-
-struct mic_info {
-       int             id;
-       char            *name;
-       pthread_t       config_thread;
-       pthread_t       init_thread;
-       pid_t           pid;
-       struct mic_console_info mic_console;
-       struct mic_net_info     mic_net;
-       struct mic_virtblk_info mic_virtblk;
-       int             restart;
-       int             boot_on_resume;
-       struct mic_info *next;
-};
-
-__attribute__((format(printf, 1, 2)))
-void mpsslog(char *format, ...);
-char *readsysfs(char *dir, char *entry);
-int setsysfs(char *dir, char *entry, char *value);
-#endif
diff --git a/Documentation/mic/mpssd/sysfs.c b/Documentation/mic/mpssd/sysfs.c
deleted file mode 100644 (file)
index 8dd3269..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Intel MIC Platform Software Stack (MPSS)
- *
- * Copyright(c) 2013 Intel Corporation.
- *
- * 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.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * Intel MIC User Space Tools.
- */
-
-#include "mpssd.h"
-
-#define PAGE_SIZE 4096
-
-char *
-readsysfs(char *dir, char *entry)
-{
-       char filename[PATH_MAX];
-       char value[PAGE_SIZE];
-       char *string = NULL;
-       int fd;
-       int len;
-
-       if (dir == NULL)
-               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
-       else
-               snprintf(filename, PATH_MAX,
-                        "%s/%s/%s", MICSYSFSDIR, dir, entry);
-
-       fd = open(filename, O_RDONLY);
-       if (fd < 0) {
-               mpsslog("Failed to open sysfs entry '%s': %s\n",
-                       filename, strerror(errno));
-               return NULL;
-       }
-
-       len = read(fd, value, sizeof(value));
-       if (len < 0) {
-               mpsslog("Failed to read sysfs entry '%s': %s\n",
-                       filename, strerror(errno));
-               goto readsys_ret;
-       }
-       if (len == 0)
-               goto readsys_ret;
-
-       value[len - 1] = '\0';
-
-       string = malloc(strlen(value) + 1);
-       if (string)
-               strcpy(string, value);
-
-readsys_ret:
-       close(fd);
-       return string;
-}
-
-int
-setsysfs(char *dir, char *entry, char *value)
-{
-       char filename[PATH_MAX];
-       char *oldvalue;
-       int fd, ret = 0;
-
-       if (dir == NULL)
-               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
-       else
-               snprintf(filename, PATH_MAX, "%s/%s/%s",
-                        MICSYSFSDIR, dir, entry);
-
-       oldvalue = readsysfs(dir, entry);
-
-       fd = open(filename, O_RDWR);
-       if (fd < 0) {
-               ret = errno;
-               mpsslog("Failed to open sysfs entry '%s': %s\n",
-                       filename, strerror(errno));
-               goto done;
-       }
-
-       if (!oldvalue || strcmp(value, oldvalue)) {
-               if (write(fd, value, strlen(value)) < 0) {
-                       ret = errno;
-                       mpsslog("Failed to write new sysfs entry '%s': %s\n",
-                               filename, strerror(errno));
-               }
-       }
-       close(fd);
-done:
-       if (oldvalue)
-               free(oldvalue);
-       return ret;
-}
diff --git a/Documentation/misc-devices/Makefile b/Documentation/misc-devices/Makefile
deleted file mode 100644 (file)
index e2b7aa4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-subdir-y := mei
diff --git a/Documentation/misc-devices/mei/.gitignore b/Documentation/misc-devices/mei/.gitignore
deleted file mode 100644 (file)
index f356b81..0000000
+++ /dev/null
@@ -1 +0,0 @@
-mei-amt-version
diff --git a/Documentation/misc-devices/mei/Makefile b/Documentation/misc-devices/mei/Makefile
deleted file mode 100644 (file)
index d758047..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := mei-amt-version
-HOSTCFLAGS_mei-amt-version.o += -I$(objtree)/usr/include
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/misc-devices/mei/TODO b/Documentation/misc-devices/mei/TODO
deleted file mode 100644 (file)
index 6b3625d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-TODO:
-       - Cleanup and split the timer function
diff --git a/Documentation/misc-devices/mei/mei-amt-version.c b/Documentation/misc-devices/mei/mei-amt-version.c
deleted file mode 100644 (file)
index 57d0d87..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/******************************************************************************
- * Intel Management Engine Interface (Intel MEI) Linux driver
- * Intel MEI Interface Header
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *     Intel Corporation.
- *     linux-mei@linux.intel.com
- *     http://www.intel.com
- *
- * BSD LICENSE
- *
- * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <bits/wordsize.h>
-#include <linux/mei.h>
-
-/*****************************************************************************
- * Intel Management Engine Interface
- *****************************************************************************/
-
-#define mei_msg(_me, fmt, ARGS...) do {         \
-       if (_me->verbose)                       \
-               fprintf(stderr, fmt, ##ARGS);   \
-} while (0)
-
-#define mei_err(_me, fmt, ARGS...) do {         \
-       fprintf(stderr, "Error: " fmt, ##ARGS); \
-} while (0)
-
-struct mei {
-       uuid_le guid;
-       bool initialized;
-       bool verbose;
-       unsigned int buf_size;
-       unsigned char prot_ver;
-       int fd;
-};
-
-static void mei_deinit(struct mei *cl)
-{
-       if (cl->fd != -1)
-               close(cl->fd);
-       cl->fd = -1;
-       cl->buf_size = 0;
-       cl->prot_ver = 0;
-       cl->initialized = false;
-}
-
-static bool mei_init(struct mei *me, const uuid_le *guid,
-               unsigned char req_protocol_version, bool verbose)
-{
-       int result;
-       struct mei_client *cl;
-       struct mei_connect_client_data data;
-
-       me->verbose = verbose;
-
-       me->fd = open("/dev/mei", O_RDWR);
-       if (me->fd == -1) {
-               mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
-               goto err;
-       }
-       memcpy(&me->guid, guid, sizeof(*guid));
-       memset(&data, 0, sizeof(data));
-       me->initialized = true;
-
-       memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
-       result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
-       if (result) {
-               mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
-               goto err;
-       }
-       cl = &data.out_client_properties;
-       mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
-       mei_msg(me, "protocol_version %d\n", cl->protocol_version);
-
-       if ((req_protocol_version > 0) &&
-            (cl->protocol_version != req_protocol_version)) {
-               mei_err(me, "Intel MEI protocol version not supported\n");
-               goto err;
-       }
-
-       me->buf_size = cl->max_msg_length;
-       me->prot_ver = cl->protocol_version;
-
-       return true;
-err:
-       mei_deinit(me);
-       return false;
-}
-
-static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
-                       ssize_t len, unsigned long timeout)
-{
-       ssize_t rc;
-
-       mei_msg(me, "call read length = %zd\n", len);
-
-       rc = read(me->fd, buffer, len);
-       if (rc < 0) {
-               mei_err(me, "read failed with status %zd %s\n",
-                               rc, strerror(errno));
-               mei_deinit(me);
-       } else {
-               mei_msg(me, "read succeeded with result %zd\n", rc);
-       }
-       return rc;
-}
-
-static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer,
-                       ssize_t len, unsigned long timeout)
-{
-       struct timeval tv;
-       ssize_t written;
-       ssize_t rc;
-       fd_set set;
-
-       tv.tv_sec = timeout / 1000;
-       tv.tv_usec = (timeout % 1000) * 1000000;
-
-       mei_msg(me, "call write length = %zd\n", len);
-
-       written = write(me->fd, buffer, len);
-       if (written < 0) {
-               rc = -errno;
-               mei_err(me, "write failed with status %zd %s\n",
-                       written, strerror(errno));
-               goto out;
-       }
-
-       FD_ZERO(&set);
-       FD_SET(me->fd, &set);
-       rc = select(me->fd + 1 , &set, NULL, NULL, &tv);
-       if (rc > 0 && FD_ISSET(me->fd, &set)) {
-               mei_msg(me, "write success\n");
-       } else if (rc == 0) {
-               mei_err(me, "write failed on timeout with status\n");
-               goto out;
-       } else { /* rc < 0 */
-               mei_err(me, "write failed on select with status %zd\n", rc);
-               goto out;
-       }
-
-       rc = written;
-out:
-       if (rc < 0)
-               mei_deinit(me);
-
-       return rc;
-}
-
-/***************************************************************************
- * Intel Advanced Management Technology ME Client
- ***************************************************************************/
-
-#define AMT_MAJOR_VERSION 1
-#define AMT_MINOR_VERSION 1
-
-#define AMT_STATUS_SUCCESS                0x0
-#define AMT_STATUS_INTERNAL_ERROR         0x1
-#define AMT_STATUS_NOT_READY              0x2
-#define AMT_STATUS_INVALID_AMT_MODE       0x3
-#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
-
-#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE  0x4000
-#define AMT_STATUS_SDK_RESOURCES      0x1004
-
-
-#define AMT_BIOS_VERSION_LEN   65
-#define AMT_VERSIONS_NUMBER    50
-#define AMT_UNICODE_STRING_LEN 20
-
-struct amt_unicode_string {
-       uint16_t length;
-       char string[AMT_UNICODE_STRING_LEN];
-} __attribute__((packed));
-
-struct amt_version_type {
-       struct amt_unicode_string description;
-       struct amt_unicode_string version;
-} __attribute__((packed));
-
-struct amt_version {
-       uint8_t major;
-       uint8_t minor;
-} __attribute__((packed));
-
-struct amt_code_versions {
-       uint8_t bios[AMT_BIOS_VERSION_LEN];
-       uint32_t count;
-       struct amt_version_type versions[AMT_VERSIONS_NUMBER];
-} __attribute__((packed));
-
-/***************************************************************************
- * Intel Advanced Management Technology Host Interface
- ***************************************************************************/
-
-struct amt_host_if_msg_header {
-       struct amt_version version;
-       uint16_t _reserved;
-       uint32_t command;
-       uint32_t length;
-} __attribute__((packed));
-
-struct amt_host_if_resp_header {
-       struct amt_host_if_msg_header header;
-       uint32_t status;
-       unsigned char data[0];
-} __attribute__((packed));
-
-const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,  \
-                               0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
-
-#define AMT_HOST_IF_CODE_VERSIONS_REQUEST  0x0400001A
-#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
-
-const struct amt_host_if_msg_header CODE_VERSION_REQ = {
-       .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
-       ._reserved = 0,
-       .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
-       .length = 0
-};
-
-
-struct amt_host_if {
-       struct mei mei_cl;
-       unsigned long send_timeout;
-       bool initialized;
-};
-
-
-static bool amt_host_if_init(struct amt_host_if *acmd,
-                     unsigned long send_timeout, bool verbose)
-{
-       acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
-       acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose);
-       return acmd->initialized;
-}
-
-static void amt_host_if_deinit(struct amt_host_if *acmd)
-{
-       mei_deinit(&acmd->mei_cl);
-       acmd->initialized = false;
-}
-
-static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
-{
-       uint32_t status = AMT_STATUS_SUCCESS;
-       struct amt_code_versions *code_ver;
-       size_t code_ver_len;
-       uint32_t ver_type_cnt;
-       uint32_t len;
-       uint32_t i;
-
-       code_ver = (struct amt_code_versions *)resp->data;
-       /* length - sizeof(status) */
-       code_ver_len = resp->header.length - sizeof(uint32_t);
-       ver_type_cnt = code_ver_len -
-                       sizeof(code_ver->bios) -
-                       sizeof(code_ver->count);
-       if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
-               status = AMT_STATUS_INTERNAL_ERROR;
-               goto out;
-       }
-
-       for (i = 0; i < code_ver->count; i++) {
-               len = code_ver->versions[i].description.length;
-
-               if (len > AMT_UNICODE_STRING_LEN) {
-                       status = AMT_STATUS_INTERNAL_ERROR;
-                       goto out;
-               }
-
-               len = code_ver->versions[i].version.length;
-               if (code_ver->versions[i].version.string[len] != '\0' ||
-                   len != strlen(code_ver->versions[i].version.string)) {
-                       status = AMT_STATUS_INTERNAL_ERROR;
-                       goto out;
-               }
-       }
-out:
-       return status;
-}
-
-static uint32_t amt_verify_response_header(uint32_t command,
-                               const struct amt_host_if_msg_header *resp_hdr,
-                               uint32_t response_size)
-{
-       if (response_size < sizeof(struct amt_host_if_resp_header)) {
-               return AMT_STATUS_INTERNAL_ERROR;
-       } else if (response_size != (resp_hdr->length +
-                               sizeof(struct amt_host_if_msg_header))) {
-               return AMT_STATUS_INTERNAL_ERROR;
-       } else if (resp_hdr->command != command) {
-               return AMT_STATUS_INTERNAL_ERROR;
-       } else if (resp_hdr->_reserved != 0) {
-               return AMT_STATUS_INTERNAL_ERROR;
-       } else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
-                  resp_hdr->version.minor < AMT_MINOR_VERSION) {
-               return AMT_STATUS_INTERNAL_ERROR;
-       }
-       return AMT_STATUS_SUCCESS;
-}
-
-static uint32_t amt_host_if_call(struct amt_host_if *acmd,
-                       const unsigned char *command, ssize_t command_sz,
-                       uint8_t **read_buf, uint32_t rcmd,
-                       unsigned int expected_sz)
-{
-       uint32_t in_buf_sz;
-       uint32_t out_buf_sz;
-       ssize_t written;
-       uint32_t status;
-       struct amt_host_if_resp_header *msg_hdr;
-
-       in_buf_sz = acmd->mei_cl.buf_size;
-       *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
-       if (*read_buf == NULL)
-               return AMT_STATUS_SDK_RESOURCES;
-       memset(*read_buf, 0, in_buf_sz);
-       msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
-
-       written = mei_send_msg(&acmd->mei_cl,
-                               command, command_sz, acmd->send_timeout);
-       if (written != command_sz)
-               return AMT_STATUS_INTERNAL_ERROR;
-
-       out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
-       if (out_buf_sz <= 0)
-               return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
-
-       status = msg_hdr->status;
-       if (status != AMT_STATUS_SUCCESS)
-               return status;
-
-       status = amt_verify_response_header(rcmd,
-                               &msg_hdr->header, out_buf_sz);
-       if (status != AMT_STATUS_SUCCESS)
-               return status;
-
-       if (expected_sz && expected_sz != out_buf_sz)
-               return AMT_STATUS_INTERNAL_ERROR;
-
-       return AMT_STATUS_SUCCESS;
-}
-
-
-static uint32_t amt_get_code_versions(struct amt_host_if *cmd,
-                              struct amt_code_versions *versions)
-{
-       struct amt_host_if_resp_header *response = NULL;
-       uint32_t status;
-
-       status = amt_host_if_call(cmd,
-                       (const unsigned char *)&CODE_VERSION_REQ,
-                       sizeof(CODE_VERSION_REQ),
-                       (uint8_t **)&response,
-                       AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
-
-       if (status != AMT_STATUS_SUCCESS)
-               goto out;
-
-       status = amt_verify_code_versions(response);
-       if (status != AMT_STATUS_SUCCESS)
-               goto out;
-
-       memcpy(versions, response->data, sizeof(struct amt_code_versions));
-out:
-       if (response != NULL)
-               free(response);
-
-       return status;
-}
-
-/************************** end of amt_host_if_command ***********************/
-int main(int argc, char **argv)
-{
-       struct amt_code_versions ver;
-       struct amt_host_if acmd;
-       unsigned int i;
-       uint32_t status;
-       int ret;
-       bool verbose;
-
-       verbose = (argc > 1 && strcmp(argv[1], "-v") == 0);
-
-       if (!amt_host_if_init(&acmd, 5000, verbose)) {
-               ret = 1;
-               goto out;
-       }
-
-       status = amt_get_code_versions(&acmd, &ver);
-
-       amt_host_if_deinit(&acmd);
-
-       switch (status) {
-       case AMT_STATUS_HOST_IF_EMPTY_RESPONSE:
-               printf("Intel AMT: DISABLED\n");
-               ret = 0;
-               break;
-       case AMT_STATUS_SUCCESS:
-               printf("Intel AMT: ENABLED\n");
-               for (i = 0; i < ver.count; i++) {
-                       printf("%s:\t%s\n", ver.versions[i].description.string,
-                               ver.versions[i].version.string);
-               }
-               ret = 0;
-               break;
-       default:
-               printf("An error has occurred\n");
-               ret = 1;
-               break;
-       }
-
-out:
-       return ret;
-}
index a769778..c6beb5f 100644 (file)
@@ -10,8 +10,6 @@ LICENSE.qlge
        - GPLv2 for QLogic Linux qlge NIC Driver
 LICENSE.qlcnic
        - GPLv2 for QLogic Linux qlcnic NIC Driver
-Makefile
-       - Makefile for docsrc.
 PLIP.txt
        - PLIP: The Parallel Line Internet Protocol device driver
 README.ipw2100
diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile
deleted file mode 100644 (file)
index 4c5d7c4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-subdir-y := timestamping
diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore
deleted file mode 100644 (file)
index 9e69e98..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-timestamping
-txtimestamp
-hwtstamp_config
diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile
deleted file mode 100644 (file)
index 8c20dfa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# To compile, from the source root
-#
-#    make headers_install
-#    make M=documentation
-
-# List of programs to build
-hostprogs-y := hwtstamp_config timestamping txtimestamp
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
-HOSTCFLAGS_txtimestamp.o += -I$(objtree)/usr/include
-HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include
diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c
deleted file mode 100644 (file)
index e8b685a..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Test program for SIOC{G,S}HWTSTAMP
- * Copyright 2013 Solarflare Communications
- * Author: Ben Hutchings
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <linux/if.h>
-#include <linux/net_tstamp.h>
-#include <linux/sockios.h>
-
-static int
-lookup_value(const char **names, int size, const char *name)
-{
-       int value;
-
-       for (value = 0; value < size; value++)
-               if (names[value] && strcasecmp(names[value], name) == 0)
-                       return value;
-
-       return -1;
-}
-
-static const char *
-lookup_name(const char **names, int size, int value)
-{
-       return (value >= 0 && value < size) ? names[value] : NULL;
-}
-
-static void list_names(FILE *f, const char **names, int size)
-{
-       int value;
-
-       for (value = 0; value < size; value++)
-               if (names[value])
-                       fprintf(f, "    %s\n", names[value]);
-}
-
-static const char *tx_types[] = {
-#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
-       TX_TYPE(OFF),
-       TX_TYPE(ON),
-       TX_TYPE(ONESTEP_SYNC)
-#undef TX_TYPE
-};
-#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
-
-static const char *rx_filters[] = {
-#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
-       RX_FILTER(NONE),
-       RX_FILTER(ALL),
-       RX_FILTER(SOME),
-       RX_FILTER(PTP_V1_L4_EVENT),
-       RX_FILTER(PTP_V1_L4_SYNC),
-       RX_FILTER(PTP_V1_L4_DELAY_REQ),
-       RX_FILTER(PTP_V2_L4_EVENT),
-       RX_FILTER(PTP_V2_L4_SYNC),
-       RX_FILTER(PTP_V2_L4_DELAY_REQ),
-       RX_FILTER(PTP_V2_L2_EVENT),
-       RX_FILTER(PTP_V2_L2_SYNC),
-       RX_FILTER(PTP_V2_L2_DELAY_REQ),
-       RX_FILTER(PTP_V2_EVENT),
-       RX_FILTER(PTP_V2_SYNC),
-       RX_FILTER(PTP_V2_DELAY_REQ),
-#undef RX_FILTER
-};
-#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
-
-static void usage(void)
-{
-       fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
-             "tx_type is any of (case-insensitive):\n",
-             stderr);
-       list_names(stderr, tx_types, N_TX_TYPES);
-       fputs("rx_filter is any of (case-insensitive):\n", stderr);
-       list_names(stderr, rx_filters, N_RX_FILTERS);
-}
-
-int main(int argc, char **argv)
-{
-       struct ifreq ifr;
-       struct hwtstamp_config config;
-       const char *name;
-       int sock;
-
-       if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
-               usage();
-               return 2;
-       }
-
-       if (argc == 4) {
-               config.flags = 0;
-               config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
-               config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
-               if (config.tx_type < 0 || config.rx_filter < 0) {
-                       usage();
-                       return 2;
-               }
-       }
-
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-       if (sock < 0) {
-               perror("socket");
-               return 1;
-       }
-
-       strcpy(ifr.ifr_name, argv[1]);
-       ifr.ifr_data = (caddr_t)&config;
-
-       if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
-               perror("ioctl");
-               return 1;
-       }
-
-       printf("flags = %#x\n", config.flags);
-       name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
-       if (name)
-               printf("tx_type = %s\n", name);
-       else
-               printf("tx_type = %d\n", config.tx_type);
-       name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
-       if (name)
-               printf("rx_filter = %s\n", name);
-       else
-               printf("rx_filter = %d\n", config.rx_filter);
-
-       return 0;
-}
diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
deleted file mode 100644 (file)
index 5cdfd74..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * This program demonstrates how the various time stamping features in
- * the Linux kernel work. It emulates the behavior of a PTP
- * implementation in stand-alone master mode by sending PTPv1 Sync
- * multicasts once every second. It looks for similar packets, but
- * beyond that doesn't actually implement PTP.
- *
- * Outgoing packets are time stamped with SO_TIMESTAMPING with or
- * without hardware support.
- *
- * Incoming packets are time stamped with SO_TIMESTAMPING with or
- * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
- * SO_TIMESTAMP[NS].
- *
- * Copyright (C) 2009 Intel Corporation.
- * Author: Patrick Ohly <patrick.ohly@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-
-#include <asm/types.h>
-#include <linux/net_tstamp.h>
-#include <linux/errqueue.h>
-
-#ifndef SO_TIMESTAMPING
-# define SO_TIMESTAMPING         37
-# define SCM_TIMESTAMPING        SO_TIMESTAMPING
-#endif
-
-#ifndef SO_TIMESTAMPNS
-# define SO_TIMESTAMPNS 35
-#endif
-
-#ifndef SIOCGSTAMPNS
-# define SIOCGSTAMPNS 0x8907
-#endif
-
-#ifndef SIOCSHWTSTAMP
-# define SIOCSHWTSTAMP 0x89b0
-#endif
-
-static void usage(const char *error)
-{
-       if (error)
-               printf("invalid option: %s\n", error);
-       printf("timestamping interface option*\n\n"
-              "Options:\n"
-              "  IP_MULTICAST_LOOP - looping outgoing multicasts\n"
-              "  SO_TIMESTAMP - normal software time stamping, ms resolution\n"
-              "  SO_TIMESTAMPNS - more accurate software time stamping\n"
-              "  SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
-              "  SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
-              "  SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
-              "  SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
-              "  SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
-              "  SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
-              "  SIOCGSTAMP - check last socket time stamp\n"
-              "  SIOCGSTAMPNS - more accurate socket time stamp\n");
-       exit(1);
-}
-
-static void bail(const char *error)
-{
-       printf("%s: %s\n", error, strerror(errno));
-       exit(1);
-}
-
-static const unsigned char sync[] = {
-       0x00, 0x01, 0x00, 0x01,
-       0x5f, 0x44, 0x46, 0x4c,
-       0x54, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       0x01, 0x01,
-
-       /* fake uuid */
-       0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05,
-
-       0x00, 0x01, 0x00, 0x37,
-       0x00, 0x00, 0x00, 0x08,
-       0x00, 0x00, 0x00, 0x00,
-       0x49, 0x05, 0xcd, 0x01,
-       0x29, 0xb1, 0x8d, 0xb0,
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x01,
-
-       /* fake uuid */
-       0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05,
-
-       0x00, 0x00, 0x00, 0x37,
-       0x00, 0x00, 0x00, 0x04,
-       0x44, 0x46, 0x4c, 0x54,
-       0x00, 0x00, 0xf0, 0x60,
-       0x00, 0x01, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x01,
-       0x00, 0x00, 0xf0, 0x60,
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x04,
-       0x44, 0x46, 0x4c, 0x54,
-       0x00, 0x01,
-
-       /* fake uuid */
-       0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05,
-
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00
-};
-
-static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
-{
-       struct timeval now;
-       int res;
-
-       res = sendto(sock, sync, sizeof(sync), 0,
-               addr, addr_len);
-       gettimeofday(&now, 0);
-       if (res < 0)
-               printf("%s: %s\n", "send", strerror(errno));
-       else
-               printf("%ld.%06ld: sent %d bytes\n",
-                      (long)now.tv_sec, (long)now.tv_usec,
-                      res);
-}
-
-static void printpacket(struct msghdr *msg, int res,
-                       char *data,
-                       int sock, int recvmsg_flags,
-                       int siocgstamp, int siocgstampns)
-{
-       struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
-       struct cmsghdr *cmsg;
-       struct timeval tv;
-       struct timespec ts;
-       struct timeval now;
-
-       gettimeofday(&now, 0);
-
-       printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
-              (long)now.tv_sec, (long)now.tv_usec,
-              (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
-              res,
-              inet_ntoa(from_addr->sin_addr),
-              msg->msg_controllen);
-       for (cmsg = CMSG_FIRSTHDR(msg);
-            cmsg;
-            cmsg = CMSG_NXTHDR(msg, cmsg)) {
-               printf("   cmsg len %zu: ", cmsg->cmsg_len);
-               switch (cmsg->cmsg_level) {
-               case SOL_SOCKET:
-                       printf("SOL_SOCKET ");
-                       switch (cmsg->cmsg_type) {
-                       case SO_TIMESTAMP: {
-                               struct timeval *stamp =
-                                       (struct timeval *)CMSG_DATA(cmsg);
-                               printf("SO_TIMESTAMP %ld.%06ld",
-                                      (long)stamp->tv_sec,
-                                      (long)stamp->tv_usec);
-                               break;
-                       }
-                       case SO_TIMESTAMPNS: {
-                               struct timespec *stamp =
-                                       (struct timespec *)CMSG_DATA(cmsg);
-                               printf("SO_TIMESTAMPNS %ld.%09ld",
-                                      (long)stamp->tv_sec,
-                                      (long)stamp->tv_nsec);
-                               break;
-                       }
-                       case SO_TIMESTAMPING: {
-                               struct timespec *stamp =
-                                       (struct timespec *)CMSG_DATA(cmsg);
-                               printf("SO_TIMESTAMPING ");
-                               printf("SW %ld.%09ld ",
-                                      (long)stamp->tv_sec,
-                                      (long)stamp->tv_nsec);
-                               stamp++;
-                               /* skip deprecated HW transformed */
-                               stamp++;
-                               printf("HW raw %ld.%09ld",
-                                      (long)stamp->tv_sec,
-                                      (long)stamp->tv_nsec);
-                               break;
-                       }
-                       default:
-                               printf("type %d", cmsg->cmsg_type);
-                               break;
-                       }
-                       break;
-               case IPPROTO_IP:
-                       printf("IPPROTO_IP ");
-                       switch (cmsg->cmsg_type) {
-                       case IP_RECVERR: {
-                               struct sock_extended_err *err =
-                                       (struct sock_extended_err *)CMSG_DATA(cmsg);
-                               printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
-                                       strerror(err->ee_errno),
-                                       err->ee_origin,
-#ifdef SO_EE_ORIGIN_TIMESTAMPING
-                                       err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
-                                       "bounced packet" : "unexpected origin"
-#else
-                                       "probably SO_EE_ORIGIN_TIMESTAMPING"
-#endif
-                                       );
-                               if (res < sizeof(sync))
-                                       printf(" => truncated data?!");
-                               else if (!memcmp(sync, data + res - sizeof(sync),
-                                                       sizeof(sync)))
-                                       printf(" => GOT OUR DATA BACK (HURRAY!)");
-                               break;
-                       }
-                       case IP_PKTINFO: {
-                               struct in_pktinfo *pktinfo =
-                                       (struct in_pktinfo *)CMSG_DATA(cmsg);
-                               printf("IP_PKTINFO interface index %u",
-                                       pktinfo->ipi_ifindex);
-                               break;
-                       }
-                       default:
-                               printf("type %d", cmsg->cmsg_type);
-                               break;
-                       }
-                       break;
-               default:
-                       printf("level %d type %d",
-                               cmsg->cmsg_level,
-                               cmsg->cmsg_type);
-                       break;
-               }
-               printf("\n");
-       }
-
-       if (siocgstamp) {
-               if (ioctl(sock, SIOCGSTAMP, &tv))
-                       printf("   %s: %s\n", "SIOCGSTAMP", strerror(errno));
-               else
-                       printf("SIOCGSTAMP %ld.%06ld\n",
-                              (long)tv.tv_sec,
-                              (long)tv.tv_usec);
-       }
-       if (siocgstampns) {
-               if (ioctl(sock, SIOCGSTAMPNS, &ts))
-                       printf("   %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
-               else
-                       printf("SIOCGSTAMPNS %ld.%09ld\n",
-                              (long)ts.tv_sec,
-                              (long)ts.tv_nsec);
-       }
-}
-
-static void recvpacket(int sock, int recvmsg_flags,
-                      int siocgstamp, int siocgstampns)
-{
-       char data[256];
-       struct msghdr msg;
-       struct iovec entry;
-       struct sockaddr_in from_addr;
-       struct {
-               struct cmsghdr cm;
-               char control[512];
-       } control;
-       int res;
-
-       memset(&msg, 0, sizeof(msg));
-       msg.msg_iov = &entry;
-       msg.msg_iovlen = 1;
-       entry.iov_base = data;
-       entry.iov_len = sizeof(data);
-       msg.msg_name = (caddr_t)&from_addr;
-       msg.msg_namelen = sizeof(from_addr);
-       msg.msg_control = &control;
-       msg.msg_controllen = sizeof(control);
-
-       res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
-       if (res < 0) {
-               printf("%s %s: %s\n",
-                      "recvmsg",
-                      (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
-                      strerror(errno));
-       } else {
-               printpacket(&msg, res, data,
-                           sock, recvmsg_flags,
-                           siocgstamp, siocgstampns);
-       }
-}
-
-int main(int argc, char **argv)
-{
-       int so_timestamping_flags = 0;
-       int so_timestamp = 0;
-       int so_timestampns = 0;
-       int siocgstamp = 0;
-       int siocgstampns = 0;
-       int ip_multicast_loop = 0;
-       char *interface;
-       int i;
-       int enabled = 1;
-       int sock;
-       struct ifreq device;
-       struct ifreq hwtstamp;
-       struct hwtstamp_config hwconfig, hwconfig_requested;
-       struct sockaddr_in addr;
-       struct ip_mreq imr;
-       struct in_addr iaddr;
-       int val;
-       socklen_t len;
-       struct timeval next;
-
-       if (argc < 2)
-               usage(0);
-       interface = argv[1];
-
-       for (i = 2; i < argc; i++) {
-               if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
-                       so_timestamp = 1;
-               else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
-                       so_timestampns = 1;
-               else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
-                       siocgstamp = 1;
-               else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
-                       siocgstampns = 1;
-               else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
-                       ip_multicast_loop = 1;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
-               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
-               else
-                       usage(argv[i]);
-       }
-
-       sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       if (sock < 0)
-               bail("socket");
-
-       memset(&device, 0, sizeof(device));
-       strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
-       if (ioctl(sock, SIOCGIFADDR, &device) < 0)
-               bail("getting interface IP address");
-
-       memset(&hwtstamp, 0, sizeof(hwtstamp));
-       strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
-       hwtstamp.ifr_data = (void *)&hwconfig;
-       memset(&hwconfig, 0, sizeof(hwconfig));
-       hwconfig.tx_type =
-               (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
-               HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
-       hwconfig.rx_filter =
-               (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
-               HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
-       hwconfig_requested = hwconfig;
-       if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
-               if ((errno == EINVAL || errno == ENOTSUP) &&
-                   hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
-                   hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
-                       printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
-               else
-                       bail("SIOCSHWTSTAMP");
-       }
-       printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
-              hwconfig_requested.tx_type, hwconfig.tx_type,
-              hwconfig_requested.rx_filter, hwconfig.rx_filter);
-
-       /* bind to PTP port */
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       addr.sin_port = htons(319 /* PTP event port */);
-       if (bind(sock,
-                (struct sockaddr *)&addr,
-                sizeof(struct sockaddr_in)) < 0)
-               bail("bind");
-
-       /* set multicast group for outgoing packets */
-       inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
-       addr.sin_addr = iaddr;
-       imr.imr_multiaddr.s_addr = iaddr.s_addr;
-       imr.imr_interface.s_addr =
-               ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
-       if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
-                      &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
-               bail("set multicast");
-
-       /* join multicast group, loop our own packet */
-       if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                      &imr, sizeof(struct ip_mreq)) < 0)
-               bail("join multicast group");
-
-       if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
-                      &ip_multicast_loop, sizeof(enabled)) < 0) {
-               bail("loop multicast");
-       }
-
-       /* set socket options for time stamping */
-       if (so_timestamp &&
-               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
-                          &enabled, sizeof(enabled)) < 0)
-               bail("setsockopt SO_TIMESTAMP");
-
-       if (so_timestampns &&
-               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
-                          &enabled, sizeof(enabled)) < 0)
-               bail("setsockopt SO_TIMESTAMPNS");
-
-       if (so_timestamping_flags &&
-               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
-                          &so_timestamping_flags,
-                          sizeof(so_timestamping_flags)) < 0)
-               bail("setsockopt SO_TIMESTAMPING");
-
-       /* request IP_PKTINFO for debugging purposes */
-       if (setsockopt(sock, SOL_IP, IP_PKTINFO,
-                      &enabled, sizeof(enabled)) < 0)
-               printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
-
-       /* verify socket options */
-       len = sizeof(val);
-       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
-               printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
-       else
-               printf("SO_TIMESTAMP %d\n", val);
-
-       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
-               printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
-                      strerror(errno));
-       else
-               printf("SO_TIMESTAMPNS %d\n", val);
-
-       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
-               printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
-                      strerror(errno));
-       } else {
-               printf("SO_TIMESTAMPING %d\n", val);
-               if (val != so_timestamping_flags)
-                       printf("   not the expected value %d\n",
-                              so_timestamping_flags);
-       }
-
-       /* send packets forever every five seconds */
-       gettimeofday(&next, 0);
-       next.tv_sec = (next.tv_sec + 1) / 5 * 5;
-       next.tv_usec = 0;
-       while (1) {
-               struct timeval now;
-               struct timeval delta;
-               long delta_us;
-               int res;
-               fd_set readfs, errorfs;
-
-               gettimeofday(&now, 0);
-               delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
-                       (long)(next.tv_usec - now.tv_usec);
-               if (delta_us > 0) {
-                       /* continue waiting for timeout or data */
-                       delta.tv_sec = delta_us / 1000000;
-                       delta.tv_usec = delta_us % 1000000;
-
-                       FD_ZERO(&readfs);
-                       FD_ZERO(&errorfs);
-                       FD_SET(sock, &readfs);
-                       FD_SET(sock, &errorfs);
-                       printf("%ld.%06ld: select %ldus\n",
-                              (long)now.tv_sec, (long)now.tv_usec,
-                              delta_us);
-                       res = select(sock + 1, &readfs, 0, &errorfs, &delta);
-                       gettimeofday(&now, 0);
-                       printf("%ld.%06ld: select returned: %d, %s\n",
-                              (long)now.tv_sec, (long)now.tv_usec,
-                              res,
-                              res < 0 ? strerror(errno) : "success");
-                       if (res > 0) {
-                               if (FD_ISSET(sock, &readfs))
-                                       printf("ready for reading\n");
-                               if (FD_ISSET(sock, &errorfs))
-                                       printf("has error\n");
-                               recvpacket(sock, 0,
-                                          siocgstamp,
-                                          siocgstampns);
-                               recvpacket(sock, MSG_ERRQUEUE,
-                                          siocgstamp,
-                                          siocgstampns);
-                       }
-               } else {
-                       /* write one packet */
-                       sendpacket(sock,
-                                  (struct sockaddr *)&addr,
-                                  sizeof(addr));
-                       next.tv_sec += 5;
-                       continue;
-               }
-       }
-
-       return 0;
-}
diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c
deleted file mode 100644 (file)
index 5df0704..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- * Author: willemb@google.com (Willem de Bruijn)
- *
- * Test software tx timestamping, including
- *
- * - SCHED, SND and ACK timestamps
- * - RAW, UDP and TCP
- * - IPv4 and IPv6
- * - various packet sizes (to test GSO and TSO)
- *
- * Consult the command line arguments for help on running
- * the various testcases.
- *
- * This test requires a dummy TCP server.
- * A simple `nc6 [-u] -l -p $DESTPORT` will do
- *
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#define _GNU_SOURCE
-
-#include <arpa/inet.h>
-#include <asm/types.h>
-#include <error.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <linux/errqueue.h>
-#include <linux/if_ether.h>
-#include <linux/net_tstamp.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <netpacket/packet.h>
-#include <poll.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-/* command line parameters */
-static int cfg_proto = SOCK_STREAM;
-static int cfg_ipproto = IPPROTO_TCP;
-static int cfg_num_pkts = 4;
-static int do_ipv4 = 1;
-static int do_ipv6 = 1;
-static int cfg_payload_len = 10;
-static bool cfg_show_payload;
-static bool cfg_do_pktinfo;
-static bool cfg_loop_nodata;
-static uint16_t dest_port = 9000;
-
-static struct sockaddr_in daddr;
-static struct sockaddr_in6 daddr6;
-static struct timespec ts_prev;
-
-static void __print_timestamp(const char *name, struct timespec *cur,
-                             uint32_t key, int payload_len)
-{
-       if (!(cur->tv_sec | cur->tv_nsec))
-               return;
-
-       fprintf(stderr, "  %s: %lu s %lu us (seq=%u, len=%u)",
-                       name, cur->tv_sec, cur->tv_nsec / 1000,
-                       key, payload_len);
-
-       if ((ts_prev.tv_sec | ts_prev.tv_nsec)) {
-               int64_t cur_ms, prev_ms;
-
-               cur_ms = (long) cur->tv_sec * 1000 * 1000;
-               cur_ms += cur->tv_nsec / 1000;
-
-               prev_ms = (long) ts_prev.tv_sec * 1000 * 1000;
-               prev_ms += ts_prev.tv_nsec / 1000;
-
-               fprintf(stderr, "  (%+" PRId64 " us)", cur_ms - prev_ms);
-       }
-
-       ts_prev = *cur;
-       fprintf(stderr, "\n");
-}
-
-static void print_timestamp_usr(void)
-{
-       struct timespec ts;
-       struct timeval tv;      /* avoid dependency on -lrt */
-
-       gettimeofday(&tv, NULL);
-       ts.tv_sec = tv.tv_sec;
-       ts.tv_nsec = tv.tv_usec * 1000;
-
-       __print_timestamp("  USR", &ts, 0, 0);
-}
-
-static void print_timestamp(struct scm_timestamping *tss, int tstype,
-                           int tskey, int payload_len)
-{
-       const char *tsname;
-
-       switch (tstype) {
-       case SCM_TSTAMP_SCHED:
-               tsname = "  ENQ";
-               break;
-       case SCM_TSTAMP_SND:
-               tsname = "  SND";
-               break;
-       case SCM_TSTAMP_ACK:
-               tsname = "  ACK";
-               break;
-       default:
-               error(1, 0, "unknown timestamp type: %u",
-               tstype);
-       }
-       __print_timestamp(tsname, &tss->ts[0], tskey, payload_len);
-}
-
-/* TODO: convert to check_and_print payload once API is stable */
-static void print_payload(char *data, int len)
-{
-       int i;
-
-       if (!len)
-               return;
-
-       if (len > 70)
-               len = 70;
-
-       fprintf(stderr, "payload: ");
-       for (i = 0; i < len; i++)
-               fprintf(stderr, "%02hhx ", data[i]);
-       fprintf(stderr, "\n");
-}
-
-static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr)
-{
-       char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN];
-
-       fprintf(stderr, "         pktinfo: ifindex=%u src=%s dst=%s\n",
-               ifindex,
-               saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown",
-               daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown");
-}
-
-static void __poll(int fd)
-{
-       struct pollfd pollfd;
-       int ret;
-
-       memset(&pollfd, 0, sizeof(pollfd));
-       pollfd.fd = fd;
-       ret = poll(&pollfd, 1, 100);
-       if (ret != 1)
-               error(1, errno, "poll");
-}
-
-static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
-{
-       struct sock_extended_err *serr = NULL;
-       struct scm_timestamping *tss = NULL;
-       struct cmsghdr *cm;
-       int batch = 0;
-
-       for (cm = CMSG_FIRSTHDR(msg);
-            cm && cm->cmsg_len;
-            cm = CMSG_NXTHDR(msg, cm)) {
-               if (cm->cmsg_level == SOL_SOCKET &&
-                   cm->cmsg_type == SCM_TIMESTAMPING) {
-                       tss = (void *) CMSG_DATA(cm);
-               } else if ((cm->cmsg_level == SOL_IP &&
-                           cm->cmsg_type == IP_RECVERR) ||
-                          (cm->cmsg_level == SOL_IPV6 &&
-                           cm->cmsg_type == IPV6_RECVERR)) {
-                       serr = (void *) CMSG_DATA(cm);
-                       if (serr->ee_errno != ENOMSG ||
-                           serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) {
-                               fprintf(stderr, "unknown ip error %d %d\n",
-                                               serr->ee_errno,
-                                               serr->ee_origin);
-                               serr = NULL;
-                       }
-               } else if (cm->cmsg_level == SOL_IP &&
-                          cm->cmsg_type == IP_PKTINFO) {
-                       struct in_pktinfo *info = (void *) CMSG_DATA(cm);
-                       print_pktinfo(AF_INET, info->ipi_ifindex,
-                                     &info->ipi_spec_dst, &info->ipi_addr);
-               } else if (cm->cmsg_level == SOL_IPV6 &&
-                          cm->cmsg_type == IPV6_PKTINFO) {
-                       struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm);
-                       print_pktinfo(AF_INET6, info6->ipi6_ifindex,
-                                     NULL, &info6->ipi6_addr);
-               } else
-                       fprintf(stderr, "unknown cmsg %d,%d\n",
-                                       cm->cmsg_level, cm->cmsg_type);
-
-               if (serr && tss) {
-                       print_timestamp(tss, serr->ee_info, serr->ee_data,
-                                       payload_len);
-                       serr = NULL;
-                       tss = NULL;
-                       batch++;
-               }
-       }
-
-       if (batch > 1)
-               fprintf(stderr, "batched %d timestamps\n", batch);
-}
-
-static int recv_errmsg(int fd)
-{
-       static char ctrl[1024 /* overprovision*/];
-       static struct msghdr msg;
-       struct iovec entry;
-       static char *data;
-       int ret = 0;
-
-       data = malloc(cfg_payload_len);
-       if (!data)
-               error(1, 0, "malloc");
-
-       memset(&msg, 0, sizeof(msg));
-       memset(&entry, 0, sizeof(entry));
-       memset(ctrl, 0, sizeof(ctrl));
-
-       entry.iov_base = data;
-       entry.iov_len = cfg_payload_len;
-       msg.msg_iov = &entry;
-       msg.msg_iovlen = 1;
-       msg.msg_name = NULL;
-       msg.msg_namelen = 0;
-       msg.msg_control = ctrl;
-       msg.msg_controllen = sizeof(ctrl);
-
-       ret = recvmsg(fd, &msg, MSG_ERRQUEUE);
-       if (ret == -1 && errno != EAGAIN)
-               error(1, errno, "recvmsg");
-
-       if (ret >= 0) {
-               __recv_errmsg_cmsg(&msg, ret);
-               if (cfg_show_payload)
-                       print_payload(data, cfg_payload_len);
-       }
-
-       free(data);
-       return ret == -1;
-}
-
-static void do_test(int family, unsigned int opt)
-{
-       char *buf;
-       int fd, i, val = 1, total_len;
-
-       if (family == AF_INET6 && cfg_proto != SOCK_STREAM) {
-               /* due to lack of checksum generation code */
-               fprintf(stderr, "test: skipping datagram over IPv6\n");
-               return;
-       }
-
-       total_len = cfg_payload_len;
-       if (cfg_proto == SOCK_RAW) {
-               total_len += sizeof(struct udphdr);
-               if (cfg_ipproto == IPPROTO_RAW)
-                       total_len += sizeof(struct iphdr);
-       }
-
-       buf = malloc(total_len);
-       if (!buf)
-               error(1, 0, "malloc");
-
-       fd = socket(family, cfg_proto, cfg_ipproto);
-       if (fd < 0)
-               error(1, errno, "socket");
-
-       if (cfg_proto == SOCK_STREAM) {
-               if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
-                              (char*) &val, sizeof(val)))
-                       error(1, 0, "setsockopt no nagle");
-
-               if (family == PF_INET) {
-                       if (connect(fd, (void *) &daddr, sizeof(daddr)))
-                               error(1, errno, "connect ipv4");
-               } else {
-                       if (connect(fd, (void *) &daddr6, sizeof(daddr6)))
-                               error(1, errno, "connect ipv6");
-               }
-       }
-
-       if (cfg_do_pktinfo) {
-               if (family == AF_INET6) {
-                       if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO,
-                                      &val, sizeof(val)))
-                               error(1, errno, "setsockopt pktinfo ipv6");
-               } else {
-                       if (setsockopt(fd, SOL_IP, IP_PKTINFO,
-                                      &val, sizeof(val)))
-                               error(1, errno, "setsockopt pktinfo ipv4");
-               }
-       }
-
-       opt |= SOF_TIMESTAMPING_SOFTWARE |
-              SOF_TIMESTAMPING_OPT_CMSG |
-              SOF_TIMESTAMPING_OPT_ID;
-       if (cfg_loop_nodata)
-               opt |= SOF_TIMESTAMPING_OPT_TSONLY;
-
-       if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
-                      (char *) &opt, sizeof(opt)))
-               error(1, 0, "setsockopt timestamping");
-
-       for (i = 0; i < cfg_num_pkts; i++) {
-               memset(&ts_prev, 0, sizeof(ts_prev));
-               memset(buf, 'a' + i, total_len);
-
-               if (cfg_proto == SOCK_RAW) {
-                       struct udphdr *udph;
-                       int off = 0;
-
-                       if (cfg_ipproto == IPPROTO_RAW) {
-                               struct iphdr *iph = (void *) buf;
-
-                               memset(iph, 0, sizeof(*iph));
-                               iph->ihl      = 5;
-                               iph->version  = 4;
-                               iph->ttl      = 2;
-                               iph->daddr    = daddr.sin_addr.s_addr;
-                               iph->protocol = IPPROTO_UDP;
-                               /* kernel writes saddr, csum, len */
-
-                               off = sizeof(*iph);
-                       }
-
-                       udph = (void *) buf + off;
-                       udph->source = ntohs(9000);     /* random spoof */
-                       udph->dest   = ntohs(dest_port);
-                       udph->len    = ntohs(sizeof(*udph) + cfg_payload_len);
-                       udph->check  = 0;       /* not allowed for IPv6 */
-               }
-
-               print_timestamp_usr();
-               if (cfg_proto != SOCK_STREAM) {
-                       if (family == PF_INET)
-                               val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr));
-                       else
-                               val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6));
-               } else {
-                       val = send(fd, buf, cfg_payload_len, 0);
-               }
-               if (val != total_len)
-                       error(1, errno, "send");
-
-               /* wait for all errors to be queued, else ACKs arrive OOO */
-               usleep(50 * 1000);
-
-               __poll(fd);
-
-               while (!recv_errmsg(fd)) {}
-       }
-
-       if (close(fd))
-               error(1, errno, "close");
-
-       free(buf);
-       usleep(400 * 1000);
-}
-
-static void __attribute__((noreturn)) usage(const char *filepath)
-{
-       fprintf(stderr, "\nUsage: %s [options] hostname\n"
-                       "\nwhere options are:\n"
-                       "  -4:   only IPv4\n"
-                       "  -6:   only IPv6\n"
-                       "  -h:   show this message\n"
-                       "  -I:   request PKTINFO\n"
-                       "  -l N: send N bytes at a time\n"
-                       "  -n:   set no-payload option\n"
-                       "  -r:   use raw\n"
-                       "  -R:   use raw (IP_HDRINCL)\n"
-                       "  -p N: connect to port N\n"
-                       "  -u:   use udp\n"
-                       "  -x:   show payload (up to 70 bytes)\n",
-                       filepath);
-       exit(1);
-}
-
-static void parse_opt(int argc, char **argv)
-{
-       int proto_count = 0;
-       char c;
-
-       while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) {
-               switch (c) {
-               case '4':
-                       do_ipv6 = 0;
-                       break;
-               case '6':
-                       do_ipv4 = 0;
-                       break;
-               case 'I':
-                       cfg_do_pktinfo = true;
-                       break;
-               case 'n':
-                       cfg_loop_nodata = true;
-                       break;
-               case 'r':
-                       proto_count++;
-                       cfg_proto = SOCK_RAW;
-                       cfg_ipproto = IPPROTO_UDP;
-                       break;
-               case 'R':
-                       proto_count++;
-                       cfg_proto = SOCK_RAW;
-                       cfg_ipproto = IPPROTO_RAW;
-                       break;
-               case 'u':
-                       proto_count++;
-                       cfg_proto = SOCK_DGRAM;
-                       cfg_ipproto = IPPROTO_UDP;
-                       break;
-               case 'l':
-                       cfg_payload_len = strtoul(optarg, NULL, 10);
-                       break;
-               case 'p':
-                       dest_port = strtoul(optarg, NULL, 10);
-                       break;
-               case 'x':
-                       cfg_show_payload = true;
-                       break;
-               case 'h':
-               default:
-                       usage(argv[0]);
-               }
-       }
-
-       if (!cfg_payload_len)
-               error(1, 0, "payload may not be nonzero");
-       if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472)
-               error(1, 0, "udp packet might exceed expected MTU");
-       if (!do_ipv4 && !do_ipv6)
-               error(1, 0, "pass -4 or -6, not both");
-       if (proto_count > 1)
-               error(1, 0, "pass -r, -R or -u, not multiple");
-
-       if (optind != argc - 1)
-               error(1, 0, "missing required hostname argument");
-}
-
-static void resolve_hostname(const char *hostname)
-{
-       struct addrinfo *addrs, *cur;
-       int have_ipv4 = 0, have_ipv6 = 0;
-
-       if (getaddrinfo(hostname, NULL, NULL, &addrs))
-               error(1, errno, "getaddrinfo");
-
-       cur = addrs;
-       while (cur && !have_ipv4 && !have_ipv6) {
-               if (!have_ipv4 && cur->ai_family == AF_INET) {
-                       memcpy(&daddr, cur->ai_addr, sizeof(daddr));
-                       daddr.sin_port = htons(dest_port);
-                       have_ipv4 = 1;
-               }
-               else if (!have_ipv6 && cur->ai_family == AF_INET6) {
-                       memcpy(&daddr6, cur->ai_addr, sizeof(daddr6));
-                       daddr6.sin6_port = htons(dest_port);
-                       have_ipv6 = 1;
-               }
-               cur = cur->ai_next;
-       }
-       if (addrs)
-               freeaddrinfo(addrs);
-
-       do_ipv4 &= have_ipv4;
-       do_ipv6 &= have_ipv6;
-}
-
-static void do_main(int family)
-{
-       fprintf(stderr, "family:       %s\n",
-                       family == PF_INET ? "INET" : "INET6");
-
-       fprintf(stderr, "test SND\n");
-       do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE);
-
-       fprintf(stderr, "test ENQ\n");
-       do_test(family, SOF_TIMESTAMPING_TX_SCHED);
-
-       fprintf(stderr, "test ENQ + SND\n");
-       do_test(family, SOF_TIMESTAMPING_TX_SCHED |
-                       SOF_TIMESTAMPING_TX_SOFTWARE);
-
-       if (cfg_proto == SOCK_STREAM) {
-               fprintf(stderr, "\ntest ACK\n");
-               do_test(family, SOF_TIMESTAMPING_TX_ACK);
-
-               fprintf(stderr, "\ntest SND + ACK\n");
-               do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE |
-                               SOF_TIMESTAMPING_TX_ACK);
-
-               fprintf(stderr, "\ntest ENQ + SND + ACK\n");
-               do_test(family, SOF_TIMESTAMPING_TX_SCHED |
-                               SOF_TIMESTAMPING_TX_SOFTWARE |
-                               SOF_TIMESTAMPING_TX_ACK);
-       }
-}
-
-const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" };
-
-int main(int argc, char **argv)
-{
-       if (argc == 1)
-               usage(argv[0]);
-
-       parse_opt(argc, argv);
-       resolve_hostname(argv[argc - 1]);
-
-       fprintf(stderr, "protocol:     %s\n", sock_names[cfg_proto]);
-       fprintf(stderr, "payload:      %u\n", cfg_payload_len);
-       fprintf(stderr, "server port:  %u\n", dest_port);
-       fprintf(stderr, "\n");
-
-       if (do_ipv4)
-               do_main(PF_INET);
-       if (do_ipv6)
-               do_main(PF_INET6);
-
-       return 0;
-}
diff --git a/Documentation/pcmcia/.gitignore b/Documentation/pcmcia/.gitignore
deleted file mode 100644 (file)
index 53d0813..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crc32hash
diff --git a/Documentation/pcmcia/Makefile b/Documentation/pcmcia/Makefile
deleted file mode 100644 (file)
index 47a8fa1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# List of programs to build
-hostprogs-y := crc32hash
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_crc32hash.o += -I$(objtree)/usr/include
diff --git a/Documentation/pcmcia/crc32hash.c b/Documentation/pcmcia/crc32hash.c
deleted file mode 100644 (file)
index 44f8bee..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */
-/* Usage example:
-$ ./crc32hash "Dual Speed"
-*/
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-static unsigned int crc32(unsigned char const *p, unsigned int len)
-{
-       int i;
-       unsigned int crc = 0;
-       while (len--) {
-               crc ^= *p++;
-               for (i = 0; i < 8; i++)
-                       crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
-       }
-       return crc;
-}
-
-int main(int argc, char **argv) {
-       unsigned int result;
-       if (argc != 2) {
-               printf("no string passed as argument\n");
-               return -1;
-       }
-       result = crc32((unsigned char const *)argv[1], strlen(argv[1]));
-       printf("0x%x\n", result);
-       return 0;
-}
index 199afd1..5f3e00a 100644 (file)
@@ -27,7 +27,7 @@ pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000
 The hex value after "pa" is the hash of product ID string 1, after "pb" for
 string 2 and so on.
 
-Alternatively, you can use crc32hash (see Documentation/pcmcia/crc32hash.c)
+Alternatively, you can use crc32hash (see tools/pcmcia/crc32hash.c)
 to determine the crc32 hash.  Simply pass the string you want to evaluate
 as argument to this program, e.g.:
-$ ./crc32hash "Dual Speed"
+$ tools/pcmcia/crc32hash "Dual Speed"
diff --git a/Documentation/prctl/.gitignore b/Documentation/prctl/.gitignore
deleted file mode 100644 (file)
index 0b5c274..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-disable-tsc-ctxt-sw-stress-test
-disable-tsc-on-off-stress-test
-disable-tsc-test
diff --git a/Documentation/prctl/Makefile b/Documentation/prctl/Makefile
deleted file mode 100644 (file)
index 44de308..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-ifndef CROSS_COMPILE
-# List of programs to build
-hostprogs-$(CONFIG_X86) := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test disable-tsc-test
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_disable-tsc-ctxt-sw-stress-test.o += -I$(objtree)/usr/include
-HOSTCFLAGS_disable-tsc-on-off-stress-test.o += -I$(objtree)/usr/include
-HOSTCFLAGS_disable-tsc-test.o += -I$(objtree)/usr/include
-endif
diff --git a/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c b/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
deleted file mode 100644 (file)
index f7499d1..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Tests if the control register is updated correctly
- * at context switches
- *
- * Warning: this test will cause a very high load for a few seconds
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <wait.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-static void sigsegv_expect(int sig)
-{
-       /* */
-}
-
-static void segvtask(void)
-{
-       if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
-       {
-               perror("prctl");
-               exit(0);
-       }
-       signal(SIGSEGV, sigsegv_expect);
-       alarm(10);
-       rdtsc();
-       fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
-       exit(0);
-}
-
-
-static void sigsegv_fail(int sig)
-{
-       fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
-       exit(0);
-}
-
-static void rdtsctask(void)
-{
-       if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
-       {
-               perror("prctl");
-               exit(0);
-       }
-       signal(SIGSEGV, sigsegv_fail);
-       alarm(10);
-       for(;;) rdtsc();
-}
-
-
-int main(void)
-{
-       int n_tasks = 100, i;
-
-       fprintf(stderr, "[No further output means we're allright]\n");
-
-       for (i=0; i<n_tasks; i++)
-               if (fork() == 0)
-               {
-                       if (i & 1)
-                               segvtask();
-                       else
-                               rdtsctask();
-               }
-
-       for (i=0; i<n_tasks; i++)
-               wait(NULL);
-
-       exit(0);
-}
-
diff --git a/Documentation/prctl/disable-tsc-on-off-stress-test.c b/Documentation/prctl/disable-tsc-on-off-stress-test.c
deleted file mode 100644 (file)
index a06f027..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Tests if the control register is updated correctly
- * when set with prctl()
- *
- * Warning: this test will cause a very high load for a few seconds
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <wait.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-/* snippet from wikipedia :-) */
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-int should_segv = 0;
-
-static void sigsegv_cb(int sig)
-{
-       if (!should_segv)
-       {
-               fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
-               exit(0);
-       }
-       if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
-       {
-               perror("prctl");
-               exit(0);
-       }
-       should_segv = 0;
-
-       rdtsc();
-}
-
-static void task(void)
-{
-       signal(SIGSEGV, sigsegv_cb);
-       alarm(10);
-       for(;;)
-       {
-               rdtsc();
-               if (should_segv)
-               {
-                       fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
-                       exit(0);
-               }
-               if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
-               {
-                       perror("prctl");
-                       exit(0);
-               }
-               should_segv = 1;
-       }
-}
-
-
-int main(void)
-{
-       int n_tasks = 100, i;
-
-       fprintf(stderr, "[No further output means we're allright]\n");
-
-       for (i=0; i<n_tasks; i++)
-               if (fork() == 0)
-                       task();
-
-       for (i=0; i<n_tasks; i++)
-               wait(NULL);
-
-       exit(0);
-}
-
diff --git a/Documentation/prctl/disable-tsc-test.c b/Documentation/prctl/disable-tsc-test.c
deleted file mode 100644 (file)
index 8d494f7..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-const char *tsc_names[] =
-{
-       [0] = "[not set]",
-       [PR_TSC_ENABLE] = "PR_TSC_ENABLE",
-       [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
-};
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-static void sigsegv_cb(int sig)
-{
-       int tsc_val = 0;
-
-       printf("[ SIG_SEGV ]\n");
-       printf("prctl(PR_GET_TSC, &tsc_val); ");
-       fflush(stdout);
-
-       if ( prctl(PR_GET_TSC, &tsc_val) == -1)
-               perror("prctl");
-
-       printf("tsc_val == %s\n", tsc_names[tsc_val]);
-       printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
-       fflush(stdout);
-       if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
-               perror("prctl");
-
-       printf("rdtsc() == ");
-}
-
-int main(void)
-{
-       int tsc_val = 0;
-
-       signal(SIGSEGV, sigsegv_cb);
-
-       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-       printf("prctl(PR_GET_TSC, &tsc_val); ");
-       fflush(stdout);
-
-       if ( prctl(PR_GET_TSC, &tsc_val) == -1)
-               perror("prctl");
-
-       printf("tsc_val == %s\n", tsc_names[tsc_val]);
-       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-       printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
-       fflush(stdout);
-
-       if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
-               perror("prctl");
-
-       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-       printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
-       fflush(stdout);
-
-       if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
-               perror("prctl");
-
-       printf("rdtsc() == ");
-       fflush(stdout);
-       printf("%llu\n", (unsigned long long)rdtsc());
-       fflush(stdout);
-
-       exit(EXIT_SUCCESS);
-}
-
diff --git a/Documentation/ptp/.gitignore b/Documentation/ptp/.gitignore
deleted file mode 100644 (file)
index f562e49..0000000
+++ /dev/null
@@ -1 +0,0 @@
-testptp
diff --git a/Documentation/ptp/Makefile b/Documentation/ptp/Makefile
deleted file mode 100644 (file)
index 293d6c0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# List of programs to build
-hostprogs-y := testptp
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_testptp.o += -I$(objtree)/usr/include
-HOSTLOADLIBES_testptp := -lrt
diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c
deleted file mode 100644 (file)
index 5d2eae1..0000000
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * PTP 1588 clock support - User space test program
- *
- * Copyright (C) 2010 OMICRON electronics GmbH
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#define _GNU_SOURCE
-#define __SANE_USERSPACE_TYPES__        /* For PPC64, to get LL64 types */
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <math.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/timex.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <linux/ptp_clock.h>
-
-#define DEVICE "/dev/ptp0"
-
-#ifndef ADJ_SETOFFSET
-#define ADJ_SETOFFSET 0x0100
-#endif
-
-#ifndef CLOCK_INVALID
-#define CLOCK_INVALID -1
-#endif
-
-/* clock_adjtime is not available in GLIBC < 2.14 */
-#if !__GLIBC_PREREQ(2, 14)
-#include <sys/syscall.h>
-static int clock_adjtime(clockid_t id, struct timex *tx)
-{
-       return syscall(__NR_clock_adjtime, id, tx);
-}
-#endif
-
-static clockid_t get_clockid(int fd)
-{
-#define CLOCKFD 3
-#define FD_TO_CLOCKID(fd)      ((~(clockid_t) (fd) << 3) | CLOCKFD)
-
-       return FD_TO_CLOCKID(fd);
-}
-
-static void handle_alarm(int s)
-{
-       printf("received signal %d\n", s);
-}
-
-static int install_handler(int signum, void (*handler)(int))
-{
-       struct sigaction action;
-       sigset_t mask;
-
-       /* Unblock the signal. */
-       sigemptyset(&mask);
-       sigaddset(&mask, signum);
-       sigprocmask(SIG_UNBLOCK, &mask, NULL);
-
-       /* Install the signal handler. */
-       action.sa_handler = handler;
-       action.sa_flags = 0;
-       sigemptyset(&action.sa_mask);
-       sigaction(signum, &action, NULL);
-
-       return 0;
-}
-
-static long ppb_to_scaled_ppm(int ppb)
-{
-       /*
-        * The 'freq' field in the 'struct timex' is in parts per
-        * million, but with a 16 bit binary fractional field.
-        * Instead of calculating either one of
-        *
-        *    scaled_ppm = (ppb / 1000) << 16  [1]
-        *    scaled_ppm = (ppb << 16) / 1000  [2]
-        *
-        * we simply use double precision math, in order to avoid the
-        * truncation in [1] and the possible overflow in [2].
-        */
-       return (long) (ppb * 65.536);
-}
-
-static int64_t pctns(struct ptp_clock_time *t)
-{
-       return t->sec * 1000000000LL + t->nsec;
-}
-
-static void usage(char *progname)
-{
-       fprintf(stderr,
-               "usage: %s [options]\n"
-               " -a val     request a one-shot alarm after 'val' seconds\n"
-               " -A val     request a periodic alarm every 'val' seconds\n"
-               " -c         query the ptp clock's capabilities\n"
-               " -d name    device to open\n"
-               " -e val     read 'val' external time stamp events\n"
-               " -f val     adjust the ptp clock frequency by 'val' ppb\n"
-               " -g         get the ptp clock time\n"
-               " -h         prints this message\n"
-               " -i val     index for event/trigger\n"
-               " -k val     measure the time offset between system and phc clock\n"
-               "            for 'val' times (Maximum 25)\n"
-               " -l         list the current pin configuration\n"
-               " -L pin,val configure pin index 'pin' with function 'val'\n"
-               "            the channel index is taken from the '-i' option\n"
-               "            'val' specifies the auxiliary function:\n"
-               "            0 - none\n"
-               "            1 - external time stamp\n"
-               "            2 - periodic output\n"
-               " -p val     enable output with a period of 'val' nanoseconds\n"
-               " -P val     enable or disable (val=1|0) the system clock PPS\n"
-               " -s         set the ptp clock time from the system time\n"
-               " -S         set the system time from the ptp clock time\n"
-               " -t val     shift the ptp clock time by 'val' seconds\n"
-               " -T val     set the ptp clock time to 'val' seconds\n",
-               progname);
-}
-
-int main(int argc, char *argv[])
-{
-       struct ptp_clock_caps caps;
-       struct ptp_extts_event event;
-       struct ptp_extts_request extts_request;
-       struct ptp_perout_request perout_request;
-       struct ptp_pin_desc desc;
-       struct timespec ts;
-       struct timex tx;
-
-       static timer_t timerid;
-       struct itimerspec timeout;
-       struct sigevent sigevent;
-
-       struct ptp_clock_time *pct;
-       struct ptp_sys_offset *sysoff;
-
-
-       char *progname;
-       unsigned int i;
-       int c, cnt, fd;
-
-       char *device = DEVICE;
-       clockid_t clkid;
-       int adjfreq = 0x7fffffff;
-       int adjtime = 0;
-       int capabilities = 0;
-       int extts = 0;
-       int gettime = 0;
-       int index = 0;
-       int list_pins = 0;
-       int oneshot = 0;
-       int pct_offset = 0;
-       int n_samples = 0;
-       int periodic = 0;
-       int perout = -1;
-       int pin_index = -1, pin_func;
-       int pps = -1;
-       int seconds = 0;
-       int settime = 0;
-
-       int64_t t1, t2, tp;
-       int64_t interval, offset;
-
-       progname = strrchr(argv[0], '/');
-       progname = progname ? 1+progname : argv[0];
-       while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:T:v"))) {
-               switch (c) {
-               case 'a':
-                       oneshot = atoi(optarg);
-                       break;
-               case 'A':
-                       periodic = atoi(optarg);
-                       break;
-               case 'c':
-                       capabilities = 1;
-                       break;
-               case 'd':
-                       device = optarg;
-                       break;
-               case 'e':
-                       extts = atoi(optarg);
-                       break;
-               case 'f':
-                       adjfreq = atoi(optarg);
-                       break;
-               case 'g':
-                       gettime = 1;
-                       break;
-               case 'i':
-                       index = atoi(optarg);
-                       break;
-               case 'k':
-                       pct_offset = 1;
-                       n_samples = atoi(optarg);
-                       break;
-               case 'l':
-                       list_pins = 1;
-                       break;
-               case 'L':
-                       cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func);
-                       if (cnt != 2) {
-                               usage(progname);
-                               return -1;
-                       }
-                       break;
-               case 'p':
-                       perout = atoi(optarg);
-                       break;
-               case 'P':
-                       pps = atoi(optarg);
-                       break;
-               case 's':
-                       settime = 1;
-                       break;
-               case 'S':
-                       settime = 2;
-                       break;
-               case 't':
-                       adjtime = atoi(optarg);
-                       break;
-               case 'T':
-                       settime = 3;
-                       seconds = atoi(optarg);
-                       break;
-               case 'h':
-                       usage(progname);
-                       return 0;
-               case '?':
-               default:
-                       usage(progname);
-                       return -1;
-               }
-       }
-
-       fd = open(device, O_RDWR);
-       if (fd < 0) {
-               fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
-               return -1;
-       }
-
-       clkid = get_clockid(fd);
-       if (CLOCK_INVALID == clkid) {
-               fprintf(stderr, "failed to read clock id\n");
-               return -1;
-       }
-
-       if (capabilities) {
-               if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
-                       perror("PTP_CLOCK_GETCAPS");
-               } else {
-                       printf("capabilities:\n"
-                              "  %d maximum frequency adjustment (ppb)\n"
-                              "  %d programmable alarms\n"
-                              "  %d external time stamp channels\n"
-                              "  %d programmable periodic signals\n"
-                              "  %d pulse per second\n"
-                              "  %d programmable pins\n"
-                              "  %d cross timestamping\n",
-                              caps.max_adj,
-                              caps.n_alarm,
-                              caps.n_ext_ts,
-                              caps.n_per_out,
-                              caps.pps,
-                              caps.n_pins,
-                              caps.cross_timestamping);
-               }
-       }
-
-       if (0x7fffffff != adjfreq) {
-               memset(&tx, 0, sizeof(tx));
-               tx.modes = ADJ_FREQUENCY;
-               tx.freq = ppb_to_scaled_ppm(adjfreq);
-               if (clock_adjtime(clkid, &tx)) {
-                       perror("clock_adjtime");
-               } else {
-                       puts("frequency adjustment okay");
-               }
-       }
-
-       if (adjtime) {
-               memset(&tx, 0, sizeof(tx));
-               tx.modes = ADJ_SETOFFSET;
-               tx.time.tv_sec = adjtime;
-               tx.time.tv_usec = 0;
-               if (clock_adjtime(clkid, &tx) < 0) {
-                       perror("clock_adjtime");
-               } else {
-                       puts("time shift okay");
-               }
-       }
-
-       if (gettime) {
-               if (clock_gettime(clkid, &ts)) {
-                       perror("clock_gettime");
-               } else {
-                       printf("clock time: %ld.%09ld or %s",
-                              ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec));
-               }
-       }
-
-       if (settime == 1) {
-               clock_gettime(CLOCK_REALTIME, &ts);
-               if (clock_settime(clkid, &ts)) {
-                       perror("clock_settime");
-               } else {
-                       puts("set time okay");
-               }
-       }
-
-       if (settime == 2) {
-               clock_gettime(clkid, &ts);
-               if (clock_settime(CLOCK_REALTIME, &ts)) {
-                       perror("clock_settime");
-               } else {
-                       puts("set time okay");
-               }
-       }
-
-       if (settime == 3) {
-               ts.tv_sec = seconds;
-               ts.tv_nsec = 0;
-               if (clock_settime(clkid, &ts)) {
-                       perror("clock_settime");
-               } else {
-                       puts("set time okay");
-               }
-       }
-
-       if (extts) {
-               memset(&extts_request, 0, sizeof(extts_request));
-               extts_request.index = index;
-               extts_request.flags = PTP_ENABLE_FEATURE;
-               if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
-                       perror("PTP_EXTTS_REQUEST");
-                       extts = 0;
-               } else {
-                       puts("external time stamp request okay");
-               }
-               for (; extts; extts--) {
-                       cnt = read(fd, &event, sizeof(event));
-                       if (cnt != sizeof(event)) {
-                               perror("read");
-                               break;
-                       }
-                       printf("event index %u at %lld.%09u\n", event.index,
-                              event.t.sec, event.t.nsec);
-                       fflush(stdout);
-               }
-               /* Disable the feature again. */
-               extts_request.flags = 0;
-               if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
-                       perror("PTP_EXTTS_REQUEST");
-               }
-       }
-
-       if (list_pins) {
-               int n_pins = 0;
-               if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
-                       perror("PTP_CLOCK_GETCAPS");
-               } else {
-                       n_pins = caps.n_pins;
-               }
-               for (i = 0; i < n_pins; i++) {
-                       desc.index = i;
-                       if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) {
-                               perror("PTP_PIN_GETFUNC");
-                               break;
-                       }
-                       printf("name %s index %u func %u chan %u\n",
-                              desc.name, desc.index, desc.func, desc.chan);
-               }
-       }
-
-       if (oneshot) {
-               install_handler(SIGALRM, handle_alarm);
-               /* Create a timer. */
-               sigevent.sigev_notify = SIGEV_SIGNAL;
-               sigevent.sigev_signo = SIGALRM;
-               if (timer_create(clkid, &sigevent, &timerid)) {
-                       perror("timer_create");
-                       return -1;
-               }
-               /* Start the timer. */
-               memset(&timeout, 0, sizeof(timeout));
-               timeout.it_value.tv_sec = oneshot;
-               if (timer_settime(timerid, 0, &timeout, NULL)) {
-                       perror("timer_settime");
-                       return -1;
-               }
-               pause();
-               timer_delete(timerid);
-       }
-
-       if (periodic) {
-               install_handler(SIGALRM, handle_alarm);
-               /* Create a timer. */
-               sigevent.sigev_notify = SIGEV_SIGNAL;
-               sigevent.sigev_signo = SIGALRM;
-               if (timer_create(clkid, &sigevent, &timerid)) {
-                       perror("timer_create");
-                       return -1;
-               }
-               /* Start the timer. */
-               memset(&timeout, 0, sizeof(timeout));
-               timeout.it_interval.tv_sec = periodic;
-               timeout.it_value.tv_sec = periodic;
-               if (timer_settime(timerid, 0, &timeout, NULL)) {
-                       perror("timer_settime");
-                       return -1;
-               }
-               while (1) {
-                       pause();
-               }
-               timer_delete(timerid);
-       }
-
-       if (perout >= 0) {
-               if (clock_gettime(clkid, &ts)) {
-                       perror("clock_gettime");
-                       return -1;
-               }
-               memset(&perout_request, 0, sizeof(perout_request));
-               perout_request.index = index;
-               perout_request.start.sec = ts.tv_sec + 2;
-               perout_request.start.nsec = 0;
-               perout_request.period.sec = 0;
-               perout_request.period.nsec = perout;
-               if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) {
-                       perror("PTP_PEROUT_REQUEST");
-               } else {
-                       puts("periodic output request okay");
-               }
-       }
-
-       if (pin_index >= 0) {
-               memset(&desc, 0, sizeof(desc));
-               desc.index = pin_index;
-               desc.func = pin_func;
-               desc.chan = index;
-               if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) {
-                       perror("PTP_PIN_SETFUNC");
-               } else {
-                       puts("set pin function okay");
-               }
-       }
-
-       if (pps != -1) {
-               int enable = pps ? 1 : 0;
-               if (ioctl(fd, PTP_ENABLE_PPS, enable)) {
-                       perror("PTP_ENABLE_PPS");
-               } else {
-                       puts("pps for system time request okay");
-               }
-       }
-
-       if (pct_offset) {
-               if (n_samples <= 0 || n_samples > 25) {
-                       puts("n_samples should be between 1 and 25");
-                       usage(progname);
-                       return -1;
-               }
-
-               sysoff = calloc(1, sizeof(*sysoff));
-               if (!sysoff) {
-                       perror("calloc");
-                       return -1;
-               }
-               sysoff->n_samples = n_samples;
-
-               if (ioctl(fd, PTP_SYS_OFFSET, sysoff))
-                       perror("PTP_SYS_OFFSET");
-               else
-                       puts("system and phc clock time offset request okay");
-
-               pct = &sysoff->ts[0];
-               for (i = 0; i < sysoff->n_samples; i++) {
-                       t1 = pctns(pct+2*i);
-                       tp = pctns(pct+2*i+1);
-                       t2 = pctns(pct+2*i+2);
-                       interval = t2 - t1;
-                       offset = (t2 + t1) / 2 - tp;
-
-                       printf("system time: %lld.%u\n",
-                               (pct+2*i)->sec, (pct+2*i)->nsec);
-                       printf("phc    time: %lld.%u\n",
-                               (pct+2*i+1)->sec, (pct+2*i+1)->nsec);
-                       printf("system time: %lld.%u\n",
-                               (pct+2*i+2)->sec, (pct+2*i+2)->nsec);
-                       printf("system/phc clock time offset is %" PRId64 " ns\n"
-                              "system     clock time delay  is %" PRId64 " ns\n",
-                               offset, interval);
-               }
-
-               free(sysoff);
-       }
-
-       close(fd);
-       return 0;
-}
diff --git a/Documentation/ptp/testptp.mk b/Documentation/ptp/testptp.mk
deleted file mode 100644 (file)
index 4ef2d97..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-# PTP 1588 clock support - User space test program
-#
-# Copyright (C) 2010 OMICRON electronics GmbH
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 2 of the License, or
-#  (at your option) any later version.
-#
-#  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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-CC        = $(CROSS_COMPILE)gcc
-INC       = -I$(KBUILD_OUTPUT)/usr/include
-CFLAGS    = -Wall $(INC)
-LDLIBS    = -lrt
-PROGS     = testptp
-
-all: $(PROGS)
-
-testptp: testptp.o
-
-clean:
-       rm -f testptp.o
-
-distclean: clean
-       rm -f $(PROGS)
index 4644bf0..8e4bb17 100644 (file)
@@ -1,7 +1,5 @@
 00-INDEX
        - this file.
-Makefile
-       - Makefile for the example sourcefiles.
 butterfly
        - AVR Butterfly SPI driver overview and pin configuration.
 ep93xx_spi
diff --git a/Documentation/timers/.gitignore b/Documentation/timers/.gitignore
deleted file mode 100644 (file)
index c5c45d7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-hpet_example
index ee212a2..3be05fe 100644 (file)
@@ -4,12 +4,8 @@ highres.txt
        - High resolution timers and dynamic ticks design notes
 hpet.txt
        - High Precision Event Timer Driver for Linux
-hpet_example.c
-       - sample hpet timer test program
 hrtimers.txt
        - subsystem for high-resolution kernel timers
-Makefile
-       - Build and link hpet_example
 NO_HZ.txt
        - Summary of the different methods for the scheduler clock-interrupts management.
 timekeeping.txt
diff --git a/Documentation/timers/Makefile b/Documentation/timers/Makefile
deleted file mode 100644 (file)
index 6c09ee6..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-$(CONFIG_X86) := hpet_example
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
index a484d2c..895345e 100644 (file)
@@ -25,4 +25,4 @@ arch/x86/kernel/hpet.c.
 
 The driver provides a userspace API which resembles the API found in the
 RTC driver framework.  An example user space program is provided in
-file:Documentation/timers/hpet_example.c
+file:samples/timers/hpet_example.c
diff --git a/Documentation/timers/hpet_example.c b/Documentation/timers/hpet_example.c
deleted file mode 100644 (file)
index 3ab4993..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <memory.h>
-#include <malloc.h>
-#include <time.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <linux/hpet.h>
-
-
-extern void hpet_open_close(int, const char **);
-extern void hpet_info(int, const char **);
-extern void hpet_poll(int, const char **);
-extern void hpet_fasync(int, const char **);
-extern void hpet_read(int, const char **);
-
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-
-struct hpet_command {
-       char            *command;
-       void            (*func)(int argc, const char ** argv);
-} hpet_command[] = {
-       {
-               "open-close",
-               hpet_open_close
-       },
-       {
-               "info",
-               hpet_info
-       },
-       {
-               "poll",
-               hpet_poll
-       },
-       {
-               "fasync",
-               hpet_fasync
-       },
-};
-
-int
-main(int argc, const char ** argv)
-{
-       unsigned int    i;
-
-       argc--;
-       argv++;
-
-       if (!argc) {
-               fprintf(stderr, "-hpet: requires command\n");
-               return -1;
-       }
-
-
-       for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
-               if (!strcmp(argv[0], hpet_command[i].command)) {
-                       argc--;
-                       argv++;
-                       fprintf(stderr, "-hpet: executing %s\n",
-                               hpet_command[i].command);
-                       hpet_command[i].func(argc, argv);
-                       return 0;
-               }
-
-       fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
-
-       return -1;
-}
-
-void
-hpet_open_close(int argc, const char **argv)
-{
-       int     fd;
-
-       if (argc != 1) {
-               fprintf(stderr, "hpet_open_close: device-name\n");
-               return;
-       }
-
-       fd = open(argv[0], O_RDONLY);
-       if (fd < 0)
-               fprintf(stderr, "hpet_open_close: open failed\n");
-       else
-               close(fd);
-
-       return;
-}
-
-void
-hpet_info(int argc, const char **argv)
-{
-       struct hpet_info        info;
-       int                     fd;
-
-       if (argc != 1) {
-               fprintf(stderr, "hpet_info: device-name\n");
-               return;
-       }
-
-       fd = open(argv[0], O_RDONLY);
-       if (fd < 0) {
-               fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
-               return;
-       }
-
-       if (ioctl(fd, HPET_INFO, &info) < 0) {
-               fprintf(stderr, "hpet_info: failed to get info\n");
-               goto out;
-       }
-
-       fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
-               info.hi_ireqfreq, info.hi_flags);
-       fprintf(stderr, "hi_hpet %d hi_timer %d\n",
-               info.hi_hpet, info.hi_timer);
-
-out:
-       close(fd);
-       return;
-}
-
-void
-hpet_poll(int argc, const char **argv)
-{
-       unsigned long           freq;
-       int                     iterations, i, fd;
-       struct pollfd           pfd;
-       struct hpet_info        info;
-       struct timeval          stv, etv;
-       struct timezone         tz;
-       long                    usec;
-
-       if (argc != 3) {
-               fprintf(stderr, "hpet_poll: device-name freq iterations\n");
-               return;
-       }
-
-       freq = atoi(argv[1]);
-       iterations = atoi(argv[2]);
-
-       fd = open(argv[0], O_RDONLY);
-
-       if (fd < 0) {
-               fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
-               return;
-       }
-
-       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
-               fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
-               goto out;
-       }
-
-       if (ioctl(fd, HPET_INFO, &info) < 0) {
-               fprintf(stderr, "hpet_poll: failed to get info\n");
-               goto out;
-       }
-
-       fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
-
-       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
-               fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
-               goto out;
-       }
-
-       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
-               fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
-               goto out;
-       }
-
-       pfd.fd = fd;
-       pfd.events = POLLIN;
-
-       for (i = 0; i < iterations; i++) {
-               pfd.revents = 0;
-               gettimeofday(&stv, &tz);
-               if (poll(&pfd, 1, -1) < 0)
-                       fprintf(stderr, "hpet_poll: poll failed\n");
-               else {
-                       long    data;
-
-                       gettimeofday(&etv, &tz);
-                       usec = stv.tv_sec * 1000000 + stv.tv_usec;
-                       usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
-
-                       fprintf(stderr,
-                               "hpet_poll: expired time = 0x%lx\n", usec);
-
-                       fprintf(stderr, "hpet_poll: revents = 0x%x\n",
-                               pfd.revents);
-
-                       if (read(fd, &data, sizeof(data)) != sizeof(data)) {
-                               fprintf(stderr, "hpet_poll: read failed\n");
-                       }
-                       else
-                               fprintf(stderr, "hpet_poll: data 0x%lx\n",
-                                       data);
-               }
-       }
-
-out:
-       close(fd);
-       return;
-}
-
-static int hpet_sigio_count;
-
-static void
-hpet_sigio(int val)
-{
-       fprintf(stderr, "hpet_sigio: called\n");
-       hpet_sigio_count++;
-}
-
-void
-hpet_fasync(int argc, const char **argv)
-{
-       unsigned long           freq;
-       int                     iterations, i, fd, value;
-       sig_t                   oldsig;
-       struct hpet_info        info;
-
-       hpet_sigio_count = 0;
-       fd = -1;
-
-       if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
-               fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
-               return;
-       }
-
-       if (argc != 3) {
-               fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
-               goto out;
-       }
-
-       fd = open(argv[0], O_RDONLY);
-
-       if (fd < 0) {
-               fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
-               return;
-       }
-
-
-       if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
-               ((value = fcntl(fd, F_GETFL)) == 1) ||
-               (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
-               fprintf(stderr, "hpet_fasync: fcntl failed\n");
-               goto out;
-       }
-
-       freq = atoi(argv[1]);
-       iterations = atoi(argv[2]);
-
-       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
-               fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
-               goto out;
-       }
-
-       if (ioctl(fd, HPET_INFO, &info) < 0) {
-               fprintf(stderr, "hpet_fasync: failed to get info\n");
-               goto out;
-       }
-
-       fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
-
-       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
-               fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
-               goto out;
-       }
-
-       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
-               fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
-               goto out;
-       }
-
-       for (i = 0; i < iterations; i++) {
-               (void) pause();
-               fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
-       }
-
-out:
-       signal(SIGIO, oldsig);
-
-       if (fd >= 0)
-               close(fd);
-
-       return;
-}
diff --git a/Documentation/vDSO/.gitignore b/Documentation/vDSO/.gitignore
deleted file mode 100644 (file)
index 133bf9e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-vdso_test
-vdso_standalone_test_x86
diff --git a/Documentation/vDSO/Makefile b/Documentation/vDSO/Makefile
deleted file mode 100644 (file)
index b12e987..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-ifndef CROSS_COMPILE
-# vdso_test won't build for glibc < 2.16, so disable it
-# hostprogs-y := vdso_test
-hostprogs-$(CONFIG_X86) := vdso_standalone_test_x86
-vdso_standalone_test_x86-objs := vdso_standalone_test_x86.o parse_vdso.o
-vdso_test-objs := parse_vdso.o vdso_test.o
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS := -I$(objtree)/usr/include -std=gnu99
-HOSTCFLAGS_vdso_standalone_test_x86.o := -fno-asynchronous-unwind-tables -fno-stack-protector
-HOSTLOADLIBES_vdso_standalone_test_x86 := -nostdlib
-ifeq ($(CONFIG_X86_32),y)
-HOSTLOADLIBES_vdso_standalone_test_x86 += -lgcc_s
-endif
-endif
diff --git a/Documentation/vDSO/parse_vdso.c b/Documentation/vDSO/parse_vdso.c
deleted file mode 100644 (file)
index 1dbb4b8..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * parse_vdso.c: Linux reference vDSO parser
- * Written by Andrew Lutomirski, 2011-2014.
- *
- * This code is meant to be linked in to various programs that run on Linux.
- * As such, it is available with as few restrictions as possible.  This file
- * is licensed under the Creative Commons Zero License, version 1.0,
- * available at http://creativecommons.org/publicdomain/zero/1.0/legalcode
- *
- * The vDSO is a regular ELF DSO that the kernel maps into user space when
- * it starts a program.  It works equally well in statically and dynamically
- * linked binaries.
- *
- * This code is tested on x86.  In principle it should work on any
- * architecture that has a vDSO.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <limits.h>
-#include <elf.h>
-
-/*
- * To use this vDSO parser, first call one of the vdso_init_* functions.
- * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
- * to vdso_init_from_sysinfo_ehdr.  Otherwise pass auxv to vdso_init_from_auxv.
- * Then call vdso_sym for each symbol you want.  For example, to look up
- * gettimeofday on x86_64, use:
- *
- *     <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
- * or
- *     <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
- *
- * vdso_sym will return 0 if the symbol doesn't exist or if the init function
- * failed or was not called.  vdso_sym is a little slow, so its return value
- * should be cached.
- *
- * vdso_sym is threadsafe; the init functions are not.
- *
- * These are the prototypes:
- */
-extern void vdso_init_from_auxv(void *auxv);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void *vdso_sym(const char *version, const char *name);
-
-
-/* And here's the code. */
-#ifndef ELF_BITS
-# if ULONG_MAX > 0xffffffffUL
-#  define ELF_BITS 64
-# else
-#  define ELF_BITS 32
-# endif
-#endif
-
-#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
-#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
-#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
-
-static struct vdso_info
-{
-       bool valid;
-
-       /* Load information */
-       uintptr_t load_addr;
-       uintptr_t load_offset;  /* load_addr - recorded vaddr */
-
-       /* Symbol table */
-       ELF(Sym) *symtab;
-       const char *symstrings;
-       ELF(Word) *bucket, *chain;
-       ELF(Word) nbucket, nchain;
-
-       /* Version table */
-       ELF(Versym) *versym;
-       ELF(Verdef) *verdef;
-} vdso_info;
-
-/* Straight from the ELF specification. */
-static unsigned long elf_hash(const unsigned char *name)
-{
-       unsigned long h = 0, g;
-       while (*name)
-       {
-               h = (h << 4) + *name++;
-               if (g = h & 0xf0000000)
-                       h ^= g >> 24;
-               h &= ~g;
-       }
-       return h;
-}
-
-void vdso_init_from_sysinfo_ehdr(uintptr_t base)
-{
-       size_t i;
-       bool found_vaddr = false;
-
-       vdso_info.valid = false;
-
-       vdso_info.load_addr = base;
-
-       ELF(Ehdr) *hdr = (ELF(Ehdr)*)base;
-       if (hdr->e_ident[EI_CLASS] !=
-           (ELF_BITS == 32 ? ELFCLASS32 : ELFCLASS64)) {
-               return;  /* Wrong ELF class -- check ELF_BITS */
-       }
-
-       ELF(Phdr) *pt = (ELF(Phdr)*)(vdso_info.load_addr + hdr->e_phoff);
-       ELF(Dyn) *dyn = 0;
-
-       /*
-        * We need two things from the segment table: the load offset
-        * and the dynamic table.
-        */
-       for (i = 0; i < hdr->e_phnum; i++)
-       {
-               if (pt[i].p_type == PT_LOAD && !found_vaddr) {
-                       found_vaddr = true;
-                       vdso_info.load_offset = base
-                               + (uintptr_t)pt[i].p_offset
-                               - (uintptr_t)pt[i].p_vaddr;
-               } else if (pt[i].p_type == PT_DYNAMIC) {
-                       dyn = (ELF(Dyn)*)(base + pt[i].p_offset);
-               }
-       }
-
-       if (!found_vaddr || !dyn)
-               return;  /* Failed */
-
-       /*
-        * Fish out the useful bits of the dynamic table.
-        */
-       ELF(Word) *hash = 0;
-       vdso_info.symstrings = 0;
-       vdso_info.symtab = 0;
-       vdso_info.versym = 0;
-       vdso_info.verdef = 0;
-       for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
-               switch (dyn[i].d_tag) {
-               case DT_STRTAB:
-                       vdso_info.symstrings = (const char *)
-                               ((uintptr_t)dyn[i].d_un.d_ptr
-                                + vdso_info.load_offset);
-                       break;
-               case DT_SYMTAB:
-                       vdso_info.symtab = (ELF(Sym) *)
-                               ((uintptr_t)dyn[i].d_un.d_ptr
-                                + vdso_info.load_offset);
-                       break;
-               case DT_HASH:
-                       hash = (ELF(Word) *)
-                               ((uintptr_t)dyn[i].d_un.d_ptr
-                                + vdso_info.load_offset);
-                       break;
-               case DT_VERSYM:
-                       vdso_info.versym = (ELF(Versym) *)
-                               ((uintptr_t)dyn[i].d_un.d_ptr
-                                + vdso_info.load_offset);
-                       break;
-               case DT_VERDEF:
-                       vdso_info.verdef = (ELF(Verdef) *)
-                               ((uintptr_t)dyn[i].d_un.d_ptr
-                                + vdso_info.load_offset);
-                       break;
-               }
-       }
-       if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
-               return;  /* Failed */
-
-       if (!vdso_info.verdef)
-               vdso_info.versym = 0;
-
-       /* Parse the hash table header. */
-       vdso_info.nbucket = hash[0];
-       vdso_info.nchain = hash[1];
-       vdso_info.bucket = &hash[2];
-       vdso_info.chain = &hash[vdso_info.nbucket + 2];
-
-       /* That's all we need. */
-       vdso_info.valid = true;
-}
-
-static bool vdso_match_version(ELF(Versym) ver,
-                              const char *name, ELF(Word) hash)
-{
-       /*
-        * This is a helper function to check if the version indexed by
-        * ver matches name (which hashes to hash).
-        *
-        * The version definition table is a mess, and I don't know how
-        * to do this in better than linear time without allocating memory
-        * to build an index.  I also don't know why the table has
-        * variable size entries in the first place.
-        *
-        * For added fun, I can't find a comprehensible specification of how
-        * to parse all the weird flags in the table.
-        *
-        * So I just parse the whole table every time.
-        */
-
-       /* First step: find the version definition */
-       ver &= 0x7fff;  /* Apparently bit 15 means "hidden" */
-       ELF(Verdef) *def = vdso_info.verdef;
-       while(true) {
-               if ((def->vd_flags & VER_FLG_BASE) == 0
-                   && (def->vd_ndx & 0x7fff) == ver)
-                       break;
-
-               if (def->vd_next == 0)
-                       return false;  /* No definition. */
-
-               def = (ELF(Verdef) *)((char *)def + def->vd_next);
-       }
-
-       /* Now figure out whether it matches. */
-       ELF(Verdaux) *aux = (ELF(Verdaux)*)((char *)def + def->vd_aux);
-       return def->vd_hash == hash
-               && !strcmp(name, vdso_info.symstrings + aux->vda_name);
-}
-
-void *vdso_sym(const char *version, const char *name)
-{
-       unsigned long ver_hash;
-       if (!vdso_info.valid)
-               return 0;
-
-       ver_hash = elf_hash(version);
-       ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
-
-       for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
-               ELF(Sym) *sym = &vdso_info.symtab[chain];
-
-               /* Check for a defined global or weak function w/ right name. */
-               if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
-                       continue;
-               if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
-                   ELF64_ST_BIND(sym->st_info) != STB_WEAK)
-                       continue;
-               if (sym->st_shndx == SHN_UNDEF)
-                       continue;
-               if (strcmp(name, vdso_info.symstrings + sym->st_name))
-                       continue;
-
-               /* Check symbol version. */
-               if (vdso_info.versym
-                   && !vdso_match_version(vdso_info.versym[chain],
-                                          version, ver_hash))
-                       continue;
-
-               return (void *)(vdso_info.load_offset + sym->st_value);
-       }
-
-       return 0;
-}
-
-void vdso_init_from_auxv(void *auxv)
-{
-       ELF(auxv_t) *elf_auxv = auxv;
-       for (int i = 0; elf_auxv[i].a_type != AT_NULL; i++)
-       {
-               if (elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
-                       vdso_init_from_sysinfo_ehdr(elf_auxv[i].a_un.a_val);
-                       return;
-               }
-       }
-
-       vdso_info.valid = false;
-}
diff --git a/Documentation/vDSO/vdso_standalone_test_x86.c b/Documentation/vDSO/vdso_standalone_test_x86.c
deleted file mode 100644 (file)
index 93b0ebf..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * vdso_test.c: Sample code to test parse_vdso.c on x86
- * Copyright (c) 2011-2014 Andy Lutomirski
- * Subject to the GNU General Public License, version 2
- *
- * You can amuse yourself by compiling with:
- * gcc -std=gnu99 -nostdlib
- *     -Os -fno-asynchronous-unwind-tables -flto -lgcc_s
- *      vdso_standalone_test_x86.c parse_vdso.c
- * to generate a small binary.  On x86_64, you can omit -lgcc_s
- * if you want the binary to be completely standalone.
- */
-
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdint.h>
-
-extern void *vdso_sym(const char *version, const char *name);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void vdso_init_from_auxv(void *auxv);
-
-/* We need a libc functions... */
-int strcmp(const char *a, const char *b)
-{
-       /* This implementation is buggy: it never returns -1. */
-       while (*a || *b) {
-               if (*a != *b)
-                       return 1;
-               if (*a == 0 || *b == 0)
-                       return 1;
-               a++;
-               b++;
-       }
-
-       return 0;
-}
-
-/* ...and two syscalls.  This is x86-specific. */
-static inline long x86_syscall3(long nr, long a0, long a1, long a2)
-{
-       long ret;
-#ifdef __x86_64__
-       asm volatile ("syscall" : "=a" (ret) : "a" (nr),
-                     "D" (a0), "S" (a1), "d" (a2) :
-                     "cc", "memory", "rcx",
-                     "r8", "r9", "r10", "r11" );
-#else
-       asm volatile ("int $0x80" : "=a" (ret) : "a" (nr),
-                     "b" (a0), "c" (a1), "d" (a2) :
-                     "cc", "memory" );
-#endif
-       return ret;
-}
-
-static inline long linux_write(int fd, const void *data, size_t len)
-{
-       return x86_syscall3(__NR_write, fd, (long)data, (long)len);
-}
-
-static inline void linux_exit(int code)
-{
-       x86_syscall3(__NR_exit, code, 0, 0);
-}
-
-void to_base10(char *lastdig, time_t n)
-{
-       while (n) {
-               *lastdig = (n % 10) + '0';
-               n /= 10;
-               lastdig--;
-       }
-}
-
-__attribute__((externally_visible)) void c_main(void **stack)
-{
-       /* Parse the stack */
-       long argc = (long)*stack;
-       stack += argc + 2;
-
-       /* Now we're pointing at the environment.  Skip it. */
-       while(*stack)
-               stack++;
-       stack++;
-
-       /* Now we're pointing at auxv.  Initialize the vDSO parser. */
-       vdso_init_from_auxv((void *)stack);
-
-       /* Find gettimeofday. */
-       typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-       gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
-
-       if (!gtod)
-               linux_exit(1);
-
-       struct timeval tv;
-       long ret = gtod(&tv, 0);
-
-       if (ret == 0) {
-               char buf[] = "The time is                     .000000\n";
-               to_base10(buf + 31, tv.tv_sec);
-               to_base10(buf + 38, tv.tv_usec);
-               linux_write(1, buf, sizeof(buf) - 1);
-       } else {
-               linux_exit(ret);
-       }
-
-       linux_exit(0);
-}
-
-/*
- * This is the real entry point.  It passes the initial stack into
- * the C entry point.
- */
-asm (
-       ".text\n"
-       ".global _start\n"
-       ".type _start,@function\n"
-       "_start:\n\t"
-#ifdef __x86_64__
-       "mov %rsp,%rdi\n\t"
-       "jmp c_main"
-#else
-       "push %esp\n\t"
-       "call c_main\n\t"
-       "int $3"
-#endif
-       );
diff --git a/Documentation/vDSO/vdso_test.c b/Documentation/vDSO/vdso_test.c
deleted file mode 100644 (file)
index 8daeb7d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * vdso_test.c: Sample code to test parse_vdso.c
- * Copyright (c) 2014 Andy Lutomirski
- * Subject to the GNU General Public License, version 2
- *
- * Compile with:
- * gcc -std=gnu99 vdso_test.c parse_vdso.c
- *
- * Tested on x86, 32-bit and 64-bit.  It may work on other architectures, too.
- */
-
-#include <stdint.h>
-#include <elf.h>
-#include <stdio.h>
-#include <sys/auxv.h>
-#include <sys/time.h>
-
-extern void *vdso_sym(const char *version, const char *name);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void vdso_init_from_auxv(void *auxv);
-
-int main(int argc, char **argv)
-{
-       unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
-       if (!sysinfo_ehdr) {
-               printf("AT_SYSINFO_EHDR is not present!\n");
-               return 0;
-       }
-
-       vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
-
-       /* Find gettimeofday. */
-       typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-       gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
-
-       if (!gtod) {
-               printf("Could not find __vdso_gettimeofday\n");
-               return 1;
-       }
-
-       struct timeval tv;
-       long ret = gtod(&tv, 0);
-
-       if (ret == 0) {
-               printf("The time is %lld.%06lld\n",
-                      (long long)tv.tv_sec, (long long)tv.tv_usec);
-       } else {
-               printf("__vdso_gettimeofday failed\n");
-       }
-
-       return 0;
-}
diff --git a/Documentation/watchdog/Makefile b/Documentation/watchdog/Makefile
deleted file mode 100644 (file)
index 6018f45..0000000
+++ /dev/null
@@ -1 +0,0 @@
-subdir-y := src
diff --git a/Documentation/watchdog/src/.gitignore b/Documentation/watchdog/src/.gitignore
deleted file mode 100644 (file)
index ac90997..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-watchdog-simple
-watchdog-test
diff --git a/Documentation/watchdog/src/Makefile b/Documentation/watchdog/src/Makefile
deleted file mode 100644 (file)
index 4a892c3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := watchdog-simple watchdog-test
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c
deleted file mode 100644 (file)
index ba45803..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-int main(void)
-{
-       int fd = open("/dev/watchdog", O_WRONLY);
-       int ret = 0;
-       if (fd == -1) {
-               perror("watchdog");
-               exit(EXIT_FAILURE);
-       }
-       while (1) {
-               ret = write(fd, "\0", 1);
-               if (ret != 1) {
-                       ret = -1;
-                       break;
-               }
-               sleep(10);
-       }
-       close(fd);
-       return ret;
-}
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
deleted file mode 100644 (file)
index 6983d05..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Watchdog Driver Test Program
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-
-int fd;
-const char v = 'V';
-
-/*
- * This function simply sends an IOCTL to the driver, which in turn ticks
- * the PC Watchdog card to reset its internal timer so it doesn't trigger
- * a computer reset.
- */
-static void keep_alive(void)
-{
-    int dummy;
-
-    printf(".");
-    ioctl(fd, WDIOC_KEEPALIVE, &dummy);
-}
-
-/*
- * The main program.  Run the program with "-d" to disable the card,
- * or "-e" to enable the card.
- */
-
-static void term(int sig)
-{
-    int ret = write(fd, &v, 1);
-
-    close(fd);
-    if (ret < 0)
-       printf("\nStopping watchdog ticks failed (%d)...\n", errno);
-    else
-       printf("\nStopping watchdog ticks...\n");
-    exit(0);
-}
-
-int main(int argc, char *argv[])
-{
-    int flags;
-    unsigned int ping_rate = 1;
-    int ret;
-
-    setbuf(stdout, NULL);
-
-    fd = open("/dev/watchdog", O_WRONLY);
-
-    if (fd == -1) {
-       printf("Watchdog device not enabled.\n");
-       exit(-1);
-    }
-
-    if (argc > 1) {
-       if (!strncasecmp(argv[1], "-d", 2)) {
-           flags = WDIOS_DISABLECARD;
-           ioctl(fd, WDIOC_SETOPTIONS, &flags);
-           printf("Watchdog card disabled.\n");
-           goto end;
-       } else if (!strncasecmp(argv[1], "-e", 2)) {
-           flags = WDIOS_ENABLECARD;
-           ioctl(fd, WDIOC_SETOPTIONS, &flags);
-           printf("Watchdog card enabled.\n");
-           goto end;
-       } else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
-           flags = atoi(argv[2]);
-           ioctl(fd, WDIOC_SETTIMEOUT, &flags);
-           printf("Watchdog timeout set to %u seconds.\n", flags);
-           goto end;
-       } else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
-           ping_rate = strtoul(argv[2], NULL, 0);
-           printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
-       } else {
-           printf("-d to disable, -e to enable, -t <n> to set " \
-               "the timeout,\n-p <n> to set the ping rate, and \n");
-           printf("run by itself to tick the card.\n");
-           goto end;
-       }
-    }
-
-    printf("Watchdog Ticking Away!\n");
-
-    signal(SIGINT, term);
-
-    while(1) {
-       keep_alive();
-       sleep(ping_rate);
-    }
-end:
-    ret = write(fd, &v, 1);
-    if (ret < 0)
-       printf("Stopping watchdog ticks failed (%d)...\n", errno);
-    close(fd);
-    return 0;
-}
index b3a701f..0e62ba3 100644 (file)
@@ -37,7 +37,7 @@ activates as soon as /dev/watchdog is opened and will reboot unless
 the watchdog is pinged within a certain time, this time is called the
 timeout or margin.  The simplest way to ping the watchdog is to write
 some data to the device.  So a very simple watchdog daemon would look
-like this source file:  see Documentation/watchdog/src/watchdog-simple.c
+like this source file:  see samples/watchdog/watchdog-simple.c
 
 A more advanced driver could for example check that a HTTP server is
 still responding before doing the write call to ping the watchdog.
index 061c2e3..ed2f0b8 100644 (file)
@@ -47,4 +47,4 @@ The external event interfaces on the WDT boards are not currently supported.
 Minor numbers are however allocated for it.
 
 
-Example Watchdog Driver:  see Documentation/watchdog/src/watchdog-simple.c
+Example Watchdog Driver:  see samples/watchdog/watchdog-simple.c
index a452c40..5f5e5ca 100644 (file)
@@ -6442,6 +6442,7 @@ F:        include/linux/mei_cl_bus.h
 F:     drivers/misc/mei/*
 F:     drivers/watchdog/mei_wdt.c
 F:     Documentation/misc-devices/mei/*
+F:     samples/mei/*
 
 INTEL MIC DRIVERS (mic)
 M:     Sudeep Dutt <sudeep.dutt@intel.com>
@@ -9383,6 +9384,7 @@ W:        http://lists.infradead.org/mailman/listinfo/linux-pcmcia
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia.git
 S:     Maintained
 F:     Documentation/pcmcia/
+F:     tools/pcmcia/
 F:     drivers/pcmcia/
 F:     include/pcmcia/
 
index fa2c3bd..d8c784d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -936,9 +936,6 @@ vmlinux_prereq: $(vmlinux-deps) FORCE
 ifdef CONFIG_HEADERS_CHECK
        $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
 endif
-ifdef CONFIG_BUILD_DOCSRC
-       $(Q)$(MAKE) $(build)=Documentation
-endif
 ifdef CONFIG_GDB_SCRIPTS
        $(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py
 endif
index 29b3436..367523a 100644 (file)
@@ -27,7 +27,7 @@ config VIDEO_FIXED_MINOR_RANGES
 
 config VIDEO_PCI_SKELETON
        tristate "Skeleton PCI V4L2 driver"
-       depends on PCI && BUILD_DOCSRC
+       depends on PCI
        depends on VIDEO_V4L2 && VIDEOBUF2_CORE
        depends on VIDEOBUF2_MEMOPS && VIDEOBUF2_DMA_CONTIG
        ---help---
index 39d07e7..33bc56c 100644 (file)
@@ -1857,15 +1857,6 @@ config PROVIDE_OHCI1394_DMA_INIT
 
          See Documentation/debugging-via-ohci1394.txt for more information.
 
-config BUILD_DOCSRC
-       bool "Build targets in Documentation/ tree"
-       depends on HEADERS_CHECK
-       help
-         This option attempts to build objects from the source files in the
-         kernel Documentation/ tree.
-
-         Say N if you are unsure.
-
 config DMA_API_DEBUG
        bool "Enable debugging of DMA-API usage"
        depends on HAVE_DMA_API_DEBUG
index 85c405f..a6d2a43 100644 (file)
@@ -99,4 +99,10 @@ config SAMPLE_SECCOMP
          Build samples of seccomp filters using various methods of
          BPF filter construction.
 
+config SAMPLE_BLACKFIN_GPTIMERS
+       tristate "Build blackfin gptimers sample code -- loadable modules only"
+       depends on BLACKFIN && BFIN_GPTIMERS && m
+       help
+         Build samples of blackfin gptimers sample module.
+
 endif # SAMPLES
index 1a20169..e17d66d 100644 (file)
@@ -2,4 +2,4 @@
 
 obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ trace_events/ livepatch/ \
                           hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
-                          configfs/ connector/ v4l/ trace_printk/
+                          configfs/ connector/ v4l/ trace_printk/ blackfin/
diff --git a/samples/auxdisplay/.gitignore b/samples/auxdisplay/.gitignore
new file mode 100644 (file)
index 0000000..7af2228
--- /dev/null
@@ -0,0 +1 @@
+cfag12864b-example
diff --git a/samples/auxdisplay/Makefile b/samples/auxdisplay/Makefile
new file mode 100644 (file)
index 0000000..05e471f
--- /dev/null
@@ -0,0 +1,9 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS := -I../../usr/include
+
+PROGS := cfag12864b-example
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
diff --git a/samples/auxdisplay/cfag12864b-example.c b/samples/auxdisplay/cfag12864b-example.c
new file mode 100644 (file)
index 0000000..e7823ff
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ *    Filename: cfag12864b-example.c
+ *     Version: 0.1.0
+ * Description: cfag12864b LCD userspace example program
+ *     License: GPLv2
+ *
+ *      Author: Copyright (C) Miguel Ojeda Sandonis
+ *        Date: 2006-10-31
+ *
+ *  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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * ------------------------
+ * start of cfag12864b code
+ * ------------------------
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define CFAG12864B_WIDTH               (128)
+#define CFAG12864B_HEIGHT              (64)
+#define CFAG12864B_SIZE                        (128 * 64 / 8)
+#define CFAG12864B_BPB                 (8)
+#define CFAG12864B_ADDRESS(x, y)       ((y) * CFAG12864B_WIDTH / \
+                                       CFAG12864B_BPB + (x) / CFAG12864B_BPB)
+#define CFAG12864B_BIT(n)              (((unsigned char) 1) << (n))
+
+#undef CFAG12864B_DOCHECK
+#ifdef CFAG12864B_DOCHECK
+       #define CFAG12864B_CHECK(x, y)          ((x) < CFAG12864B_WIDTH && \
+                                               (y) < CFAG12864B_HEIGHT)
+#else
+       #define CFAG12864B_CHECK(x, y)          (1)
+#endif
+
+int cfag12864b_fd;
+unsigned char * cfag12864b_mem;
+unsigned char cfag12864b_buffer[CFAG12864B_SIZE];
+
+/*
+ * init a cfag12864b framebuffer device
+ *
+ * No error:       return = 0
+ * Unable to open: return = -1
+ * Unable to mmap: return = -2
+ */
+static int cfag12864b_init(char *path)
+{
+       cfag12864b_fd = open(path, O_RDWR);
+       if (cfag12864b_fd == -1)
+               return -1;
+
+       cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE,
+               MAP_SHARED, cfag12864b_fd, 0);
+       if (cfag12864b_mem == MAP_FAILED) {
+               close(cfag12864b_fd);
+               return -2;
+       }
+
+       return 0;
+}
+
+/*
+ * exit a cfag12864b framebuffer device
+ */
+static void cfag12864b_exit(void)
+{
+       munmap(cfag12864b_mem, CFAG12864B_SIZE);
+       close(cfag12864b_fd);
+}
+
+/*
+ * set (x, y) pixel
+ */
+static void cfag12864b_set(unsigned char x, unsigned char y)
+{
+       if (CFAG12864B_CHECK(x, y))
+               cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |=
+                       CFAG12864B_BIT(x % CFAG12864B_BPB);
+}
+
+/*
+ * unset (x, y) pixel
+ */
+static void cfag12864b_unset(unsigned char x, unsigned char y)
+{
+       if (CFAG12864B_CHECK(x, y))
+               cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &=
+                       ~CFAG12864B_BIT(x % CFAG12864B_BPB);
+}
+
+/*
+ * is set (x, y) pixel?
+ *
+ * Pixel off: return = 0
+ * Pixel on:  return = 1
+ */
+static unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
+{
+       if (CFAG12864B_CHECK(x, y))
+               if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &
+                       CFAG12864B_BIT(x % CFAG12864B_BPB))
+                       return 1;
+
+       return 0;
+}
+
+/*
+ * not (x, y) pixel
+ */
+static void cfag12864b_not(unsigned char x, unsigned char y)
+{
+       if (cfag12864b_isset(x, y))
+               cfag12864b_unset(x, y);
+       else
+               cfag12864b_set(x, y);
+}
+
+/*
+ * fill (set all pixels)
+ */
+static void cfag12864b_fill(void)
+{
+       unsigned short i;
+
+       for (i = 0; i < CFAG12864B_SIZE; i++)
+               cfag12864b_buffer[i] = 0xFF;
+}
+
+/*
+ * clear (unset all pixels)
+ */
+static void cfag12864b_clear(void)
+{
+       unsigned short i;
+
+       for (i = 0; i < CFAG12864B_SIZE; i++)
+               cfag12864b_buffer[i] = 0;
+}
+
+/*
+ * format a [128*64] matrix
+ *
+ * Pixel off: src[i] = 0
+ * Pixel on:  src[i] > 0
+ */
+static void cfag12864b_format(unsigned char * matrix)
+{
+       unsigned char i, j, n;
+
+       for (i = 0; i < CFAG12864B_HEIGHT; i++)
+       for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) {
+               cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB +
+                       j] = 0;
+               for (n = 0; n < CFAG12864B_BPB; n++)
+                       if (matrix[i * CFAG12864B_WIDTH +
+                               j * CFAG12864B_BPB + n])
+                               cfag12864b_buffer[i * CFAG12864B_WIDTH /
+                                       CFAG12864B_BPB + j] |=
+                                       CFAG12864B_BIT(n);
+       }
+}
+
+/*
+ * blit buffer to lcd
+ */
+static void cfag12864b_blit(void)
+{
+       memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE);
+}
+
+/*
+ * ----------------------
+ * end of cfag12864b code
+ * ----------------------
+ */
+
+#include <stdio.h>
+
+#define EXAMPLES       6
+
+static void example(unsigned char n)
+{
+       unsigned short i, j;
+       unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT];
+
+       if (n > EXAMPLES)
+               return;
+
+       printf("Example %i/%i - ", n, EXAMPLES);
+
+       switch (n) {
+       case 1:
+               printf("Draw points setting bits");
+               cfag12864b_clear();
+               for (i = 0; i < CFAG12864B_WIDTH; i += 2)
+                       for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
+                               cfag12864b_set(i, j);
+               break;
+
+       case 2:
+               printf("Clear the LCD");
+               cfag12864b_clear();
+               break;
+
+       case 3:
+               printf("Draw rows formatting a [128*64] matrix");
+               memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT);
+               for (i = 0; i < CFAG12864B_WIDTH; i++)
+                       for (j = 0; j < CFAG12864B_HEIGHT; j += 2)
+                               matrix[j * CFAG12864B_WIDTH + i] = 1;
+               cfag12864b_format(matrix);
+               break;
+
+       case 4:
+               printf("Fill the lcd");
+               cfag12864b_fill();
+               break;
+
+       case 5:
+               printf("Draw columns unsetting bits");
+               for (i = 0; i < CFAG12864B_WIDTH; i += 2)
+                       for (j = 0; j < CFAG12864B_HEIGHT; j++)
+                               cfag12864b_unset(i, j);
+               break;
+
+       case 6:
+               printf("Do negative not-ing all bits");
+               for (i = 0; i < CFAG12864B_WIDTH; i++)
+                       for (j = 0; j < CFAG12864B_HEIGHT; j ++)
+                               cfag12864b_not(i, j);
+               break;
+       }
+
+       puts(" - [Press Enter]");
+}
+
+int main(int argc, char *argv[])
+{
+       unsigned char n;
+
+       if (argc != 2) {
+               printf(
+                       "Sintax:  %s fbdev\n"
+                       "Usually: /dev/fb0, /dev/fb1...\n", argv[0]);
+               return -1;
+       }
+
+       if (cfag12864b_init(argv[1])) {
+               printf("Can't init %s fbdev\n", argv[1]);
+               return -2;
+       }
+
+       for (n = 1; n <= EXAMPLES; n++) {
+               example(n);
+               cfag12864b_blit();
+               while (getchar() != '\n');
+       }
+
+       cfag12864b_exit();
+
+       return 0;
+}
diff --git a/samples/blackfin/Makefile b/samples/blackfin/Makefile
new file mode 100644 (file)
index 0000000..89b86cf
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMPLE_BLACKFIN_GPTIMERS) += gptimers-example.o
diff --git a/samples/blackfin/gptimers-example.c b/samples/blackfin/gptimers-example.c
new file mode 100644 (file)
index 0000000..283eba9
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Simple gptimers example
+ *     http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gptimers
+ *
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/gptimers.h>
+#include <asm/portmux.h>
+
+/* ... random driver includes ... */
+
+#define DRIVER_NAME "gptimer_example"
+
+#ifdef IRQ_TIMER5
+#define SAMPLE_IRQ_TIMER IRQ_TIMER5
+#else
+#define SAMPLE_IRQ_TIMER IRQ_TIMER2
+#endif
+
+struct gptimer_data {
+       uint32_t period, width;
+};
+static struct gptimer_data data;
+
+/* ... random driver state ... */
+
+static irqreturn_t gptimer_example_irq(int irq, void *dev_id)
+{
+       struct gptimer_data *data = dev_id;
+
+       /* make sure it was our timer which caused the interrupt */
+       if (!get_gptimer_intr(TIMER5_id))
+               return IRQ_NONE;
+
+       /* read the width/period values that were captured for the waveform */
+       data->width = get_gptimer_pwidth(TIMER5_id);
+       data->period = get_gptimer_period(TIMER5_id);
+
+       /* acknowledge the interrupt */
+       clear_gptimer_intr(TIMER5_id);
+
+       /* tell the upper layers we took care of things */
+       return IRQ_HANDLED;
+}
+
+/* ... random driver code ... */
+
+static int __init gptimer_example_init(void)
+{
+       int ret;
+
+       /* grab the peripheral pins */
+       ret = peripheral_request(P_TMR5, DRIVER_NAME);
+       if (ret) {
+               printk(KERN_NOTICE DRIVER_NAME ": peripheral request failed\n");
+               return ret;
+       }
+
+       /* grab the IRQ for the timer */
+       ret = request_irq(SAMPLE_IRQ_TIMER, gptimer_example_irq,
+                       IRQF_SHARED, DRIVER_NAME, &data);
+       if (ret) {
+               printk(KERN_NOTICE DRIVER_NAME ": IRQ request failed\n");
+               peripheral_free(P_TMR5);
+               return ret;
+       }
+
+       /* setup the timer and enable it */
+       set_gptimer_config(TIMER5_id,
+                       WDTH_CAP | PULSE_HI | PERIOD_CNT | IRQ_ENA);
+       enable_gptimers(TIMER5bit);
+
+       return 0;
+}
+module_init(gptimer_example_init);
+
+static void __exit gptimer_example_exit(void)
+{
+       disable_gptimers(TIMER5bit);
+       free_irq(SAMPLE_IRQ_TIMER, &data);
+       peripheral_free(P_TMR5);
+}
+module_exit(gptimer_example_exit);
+
+MODULE_LICENSE("BSD");
diff --git a/samples/mei/.gitignore b/samples/mei/.gitignore
new file mode 100644 (file)
index 0000000..f356b81
--- /dev/null
@@ -0,0 +1 @@
+mei-amt-version
diff --git a/samples/mei/Makefile b/samples/mei/Makefile
new file mode 100644 (file)
index 0000000..7aac216
--- /dev/null
@@ -0,0 +1,9 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS := -I../../usr/include
+
+PROGS := mei-amt-version
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
diff --git a/samples/mei/TODO b/samples/mei/TODO
new file mode 100644 (file)
index 0000000..6b3625d
--- /dev/null
@@ -0,0 +1,2 @@
+TODO:
+       - Cleanup and split the timer function
diff --git a/samples/mei/mei-amt-version.c b/samples/mei/mei-amt-version.c
new file mode 100644 (file)
index 0000000..57d0d87
--- /dev/null
@@ -0,0 +1,479 @@
+/******************************************************************************
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Intel MEI Interface Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *     Intel Corporation.
+ *     linux-mei@linux.intel.com
+ *     http://www.intel.com
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <bits/wordsize.h>
+#include <linux/mei.h>
+
+/*****************************************************************************
+ * Intel Management Engine Interface
+ *****************************************************************************/
+
+#define mei_msg(_me, fmt, ARGS...) do {         \
+       if (_me->verbose)                       \
+               fprintf(stderr, fmt, ##ARGS);   \
+} while (0)
+
+#define mei_err(_me, fmt, ARGS...) do {         \
+       fprintf(stderr, "Error: " fmt, ##ARGS); \
+} while (0)
+
+struct mei {
+       uuid_le guid;
+       bool initialized;
+       bool verbose;
+       unsigned int buf_size;
+       unsigned char prot_ver;
+       int fd;
+};
+
+static void mei_deinit(struct mei *cl)
+{
+       if (cl->fd != -1)
+               close(cl->fd);
+       cl->fd = -1;
+       cl->buf_size = 0;
+       cl->prot_ver = 0;
+       cl->initialized = false;
+}
+
+static bool mei_init(struct mei *me, const uuid_le *guid,
+               unsigned char req_protocol_version, bool verbose)
+{
+       int result;
+       struct mei_client *cl;
+       struct mei_connect_client_data data;
+
+       me->verbose = verbose;
+
+       me->fd = open("/dev/mei", O_RDWR);
+       if (me->fd == -1) {
+               mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
+               goto err;
+       }
+       memcpy(&me->guid, guid, sizeof(*guid));
+       memset(&data, 0, sizeof(data));
+       me->initialized = true;
+
+       memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
+       result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
+       if (result) {
+               mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
+               goto err;
+       }
+       cl = &data.out_client_properties;
+       mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
+       mei_msg(me, "protocol_version %d\n", cl->protocol_version);
+
+       if ((req_protocol_version > 0) &&
+            (cl->protocol_version != req_protocol_version)) {
+               mei_err(me, "Intel MEI protocol version not supported\n");
+               goto err;
+       }
+
+       me->buf_size = cl->max_msg_length;
+       me->prot_ver = cl->protocol_version;
+
+       return true;
+err:
+       mei_deinit(me);
+       return false;
+}
+
+static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
+                       ssize_t len, unsigned long timeout)
+{
+       ssize_t rc;
+
+       mei_msg(me, "call read length = %zd\n", len);
+
+       rc = read(me->fd, buffer, len);
+       if (rc < 0) {
+               mei_err(me, "read failed with status %zd %s\n",
+                               rc, strerror(errno));
+               mei_deinit(me);
+       } else {
+               mei_msg(me, "read succeeded with result %zd\n", rc);
+       }
+       return rc;
+}
+
+static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer,
+                       ssize_t len, unsigned long timeout)
+{
+       struct timeval tv;
+       ssize_t written;
+       ssize_t rc;
+       fd_set set;
+
+       tv.tv_sec = timeout / 1000;
+       tv.tv_usec = (timeout % 1000) * 1000000;
+
+       mei_msg(me, "call write length = %zd\n", len);
+
+       written = write(me->fd, buffer, len);
+       if (written < 0) {
+               rc = -errno;
+               mei_err(me, "write failed with status %zd %s\n",
+                       written, strerror(errno));
+               goto out;
+       }
+
+       FD_ZERO(&set);
+       FD_SET(me->fd, &set);
+       rc = select(me->fd + 1 , &set, NULL, NULL, &tv);
+       if (rc > 0 && FD_ISSET(me->fd, &set)) {
+               mei_msg(me, "write success\n");
+       } else if (rc == 0) {
+               mei_err(me, "write failed on timeout with status\n");
+               goto out;
+       } else { /* rc < 0 */
+               mei_err(me, "write failed on select with status %zd\n", rc);
+               goto out;
+       }
+
+       rc = written;
+out:
+       if (rc < 0)
+               mei_deinit(me);
+
+       return rc;
+}
+
+/***************************************************************************
+ * Intel Advanced Management Technology ME Client
+ ***************************************************************************/
+
+#define AMT_MAJOR_VERSION 1
+#define AMT_MINOR_VERSION 1
+
+#define AMT_STATUS_SUCCESS                0x0
+#define AMT_STATUS_INTERNAL_ERROR         0x1
+#define AMT_STATUS_NOT_READY              0x2
+#define AMT_STATUS_INVALID_AMT_MODE       0x3
+#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
+
+#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE  0x4000
+#define AMT_STATUS_SDK_RESOURCES      0x1004
+
+
+#define AMT_BIOS_VERSION_LEN   65
+#define AMT_VERSIONS_NUMBER    50
+#define AMT_UNICODE_STRING_LEN 20
+
+struct amt_unicode_string {
+       uint16_t length;
+       char string[AMT_UNICODE_STRING_LEN];
+} __attribute__((packed));
+
+struct amt_version_type {
+       struct amt_unicode_string description;
+       struct amt_unicode_string version;
+} __attribute__((packed));
+
+struct amt_version {
+       uint8_t major;
+       uint8_t minor;
+} __attribute__((packed));
+
+struct amt_code_versions {
+       uint8_t bios[AMT_BIOS_VERSION_LEN];
+       uint32_t count;
+       struct amt_version_type versions[AMT_VERSIONS_NUMBER];
+} __attribute__((packed));
+
+/***************************************************************************
+ * Intel Advanced Management Technology Host Interface
+ ***************************************************************************/
+
+struct amt_host_if_msg_header {
+       struct amt_version version;
+       uint16_t _reserved;
+       uint32_t command;
+       uint32_t length;
+} __attribute__((packed));
+
+struct amt_host_if_resp_header {
+       struct amt_host_if_msg_header header;
+       uint32_t status;
+       unsigned char data[0];
+} __attribute__((packed));
+
+const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,  \
+                               0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
+
+#define AMT_HOST_IF_CODE_VERSIONS_REQUEST  0x0400001A
+#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
+
+const struct amt_host_if_msg_header CODE_VERSION_REQ = {
+       .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
+       ._reserved = 0,
+       .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
+       .length = 0
+};
+
+
+struct amt_host_if {
+       struct mei mei_cl;
+       unsigned long send_timeout;
+       bool initialized;
+};
+
+
+static bool amt_host_if_init(struct amt_host_if *acmd,
+                     unsigned long send_timeout, bool verbose)
+{
+       acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
+       acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose);
+       return acmd->initialized;
+}
+
+static void amt_host_if_deinit(struct amt_host_if *acmd)
+{
+       mei_deinit(&acmd->mei_cl);
+       acmd->initialized = false;
+}
+
+static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
+{
+       uint32_t status = AMT_STATUS_SUCCESS;
+       struct amt_code_versions *code_ver;
+       size_t code_ver_len;
+       uint32_t ver_type_cnt;
+       uint32_t len;
+       uint32_t i;
+
+       code_ver = (struct amt_code_versions *)resp->data;
+       /* length - sizeof(status) */
+       code_ver_len = resp->header.length - sizeof(uint32_t);
+       ver_type_cnt = code_ver_len -
+                       sizeof(code_ver->bios) -
+                       sizeof(code_ver->count);
+       if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
+               status = AMT_STATUS_INTERNAL_ERROR;
+               goto out;
+       }
+
+       for (i = 0; i < code_ver->count; i++) {
+               len = code_ver->versions[i].description.length;
+
+               if (len > AMT_UNICODE_STRING_LEN) {
+                       status = AMT_STATUS_INTERNAL_ERROR;
+                       goto out;
+               }
+
+               len = code_ver->versions[i].version.length;
+               if (code_ver->versions[i].version.string[len] != '\0' ||
+                   len != strlen(code_ver->versions[i].version.string)) {
+                       status = AMT_STATUS_INTERNAL_ERROR;
+                       goto out;
+               }
+       }
+out:
+       return status;
+}
+
+static uint32_t amt_verify_response_header(uint32_t command,
+                               const struct amt_host_if_msg_header *resp_hdr,
+                               uint32_t response_size)
+{
+       if (response_size < sizeof(struct amt_host_if_resp_header)) {
+               return AMT_STATUS_INTERNAL_ERROR;
+       } else if (response_size != (resp_hdr->length +
+                               sizeof(struct amt_host_if_msg_header))) {
+               return AMT_STATUS_INTERNAL_ERROR;
+       } else if (resp_hdr->command != command) {
+               return AMT_STATUS_INTERNAL_ERROR;
+       } else if (resp_hdr->_reserved != 0) {
+               return AMT_STATUS_INTERNAL_ERROR;
+       } else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
+                  resp_hdr->version.minor < AMT_MINOR_VERSION) {
+               return AMT_STATUS_INTERNAL_ERROR;
+       }
+       return AMT_STATUS_SUCCESS;
+}
+
+static uint32_t amt_host_if_call(struct amt_host_if *acmd,
+                       const unsigned char *command, ssize_t command_sz,
+                       uint8_t **read_buf, uint32_t rcmd,
+                       unsigned int expected_sz)
+{
+       uint32_t in_buf_sz;
+       uint32_t out_buf_sz;
+       ssize_t written;
+       uint32_t status;
+       struct amt_host_if_resp_header *msg_hdr;
+
+       in_buf_sz = acmd->mei_cl.buf_size;
+       *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
+       if (*read_buf == NULL)
+               return AMT_STATUS_SDK_RESOURCES;
+       memset(*read_buf, 0, in_buf_sz);
+       msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
+
+       written = mei_send_msg(&acmd->mei_cl,
+                               command, command_sz, acmd->send_timeout);
+       if (written != command_sz)
+               return AMT_STATUS_INTERNAL_ERROR;
+
+       out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
+       if (out_buf_sz <= 0)
+               return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
+
+       status = msg_hdr->status;
+       if (status != AMT_STATUS_SUCCESS)
+               return status;
+
+       status = amt_verify_response_header(rcmd,
+                               &msg_hdr->header, out_buf_sz);
+       if (status != AMT_STATUS_SUCCESS)
+               return status;
+
+       if (expected_sz && expected_sz != out_buf_sz)
+               return AMT_STATUS_INTERNAL_ERROR;
+
+       return AMT_STATUS_SUCCESS;
+}
+
+
+static uint32_t amt_get_code_versions(struct amt_host_if *cmd,
+                              struct amt_code_versions *versions)
+{
+       struct amt_host_if_resp_header *response = NULL;
+       uint32_t status;
+
+       status = amt_host_if_call(cmd,
+                       (const unsigned char *)&CODE_VERSION_REQ,
+                       sizeof(CODE_VERSION_REQ),
+                       (uint8_t **)&response,
+                       AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
+
+       if (status != AMT_STATUS_SUCCESS)
+               goto out;
+
+       status = amt_verify_code_versions(response);
+       if (status != AMT_STATUS_SUCCESS)
+               goto out;
+
+       memcpy(versions, response->data, sizeof(struct amt_code_versions));
+out:
+       if (response != NULL)
+               free(response);
+
+       return status;
+}
+
+/************************** end of amt_host_if_command ***********************/
+int main(int argc, char **argv)
+{
+       struct amt_code_versions ver;
+       struct amt_host_if acmd;
+       unsigned int i;
+       uint32_t status;
+       int ret;
+       bool verbose;
+
+       verbose = (argc > 1 && strcmp(argv[1], "-v") == 0);
+
+       if (!amt_host_if_init(&acmd, 5000, verbose)) {
+               ret = 1;
+               goto out;
+       }
+
+       status = amt_get_code_versions(&acmd, &ver);
+
+       amt_host_if_deinit(&acmd);
+
+       switch (status) {
+       case AMT_STATUS_HOST_IF_EMPTY_RESPONSE:
+               printf("Intel AMT: DISABLED\n");
+               ret = 0;
+               break;
+       case AMT_STATUS_SUCCESS:
+               printf("Intel AMT: ENABLED\n");
+               for (i = 0; i < ver.count; i++) {
+                       printf("%s:\t%s\n", ver.versions[i].description.string,
+                               ver.versions[i].version.string);
+               }
+               ret = 0;
+               break;
+       default:
+               printf("An error has occurred\n");
+               ret = 1;
+               break;
+       }
+
+out:
+       return ret;
+}
diff --git a/samples/mic/mpssd/.gitignore b/samples/mic/mpssd/.gitignore
new file mode 100644 (file)
index 0000000..8b7c72f
--- /dev/null
@@ -0,0 +1 @@
+mpssd
diff --git a/samples/mic/mpssd/Makefile b/samples/mic/mpssd/Makefile
new file mode 100644 (file)
index 0000000..3e3ef91
--- /dev/null
@@ -0,0 +1,27 @@
+ifndef CROSS_COMPILE
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+
+PROGS := mpssd
+CC = $(CROSS_COMPILE)gcc
+CFLAGS := -I../../../usr/include -I../../../tools/include
+
+ifdef DEBUG
+CFLAGS += -DDEBUG=$(DEBUG)
+endif
+
+all: $(PROGS)
+mpssd: mpssd.c sysfs.c
+       $(CC) $(CFLAGS) mpssd.c sysfs.c -o mpssd -lpthread
+
+install:
+       install mpssd /usr/sbin/mpssd
+       install micctrl /usr/sbin/micctrl
+
+clean:
+       rm -fr $(PROGS)
+
+endif
+endif
diff --git a/samples/mic/mpssd/micctrl b/samples/mic/mpssd/micctrl
new file mode 100755 (executable)
index 0000000..8f2629b
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/bash
+# Intel MIC Platform Software Stack (MPSS)
+#
+# Copyright(c) 2013 Intel Corporation.
+#
+# 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.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Intel MIC User Space Tools.
+#
+# micctrl - Controls MIC boot/start/stop.
+#
+# chkconfig: 2345 95 05
+# description: start MPSS stack processing.
+#
+### BEGIN INIT INFO
+# Provides: micctrl
+### END INIT INFO
+
+# Source function library.
+. /etc/init.d/functions
+
+sysfs="/sys/class/mic"
+
+_status()
+{
+       f=$sysfs/$1
+       echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
+}
+
+status()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _status $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _status `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_reset()
+{
+       f=$sysfs/$1
+       echo reset > $f/state
+}
+
+reset()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _reset $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _reset `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_boot()
+{
+       f=$sysfs/$1
+       echo "linux" > $f/bootmode
+       echo "mic/uos.img" > $f/firmware
+       echo "mic/$1.image" > $f/ramdisk
+       echo "boot" > $f/state
+}
+
+boot()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _boot $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _boot `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_shutdown()
+{
+       f=$sysfs/$1
+       echo shutdown > $f/state
+}
+
+shutdown()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _shutdown $1
+               return $?
+       fi
+       for f in $sysfs/*
+       do
+               _shutdown `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+_wait()
+{
+       f=$sysfs/$1
+       while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
+       do
+               sleep 1
+               echo -e "Waiting for $1 to go offline"
+       done
+}
+
+wait()
+{
+       if [ "`echo $1 | head -c3`" == "mic" ]; then
+               _wait $1
+               return $?
+       fi
+       # Wait for the cards to go offline
+       for f in $sysfs/*
+       do
+               _wait `basename $f`
+               RETVAL=$?
+               [ $RETVAL -ne 0 ] && return $RETVAL
+       done
+       return 0
+}
+
+if [ ! -d "$sysfs" ]; then
+       echo -e $"Module unloaded "
+       exit 3
+fi
+
+case $1 in
+       -s)
+               status $2
+               ;;
+       -r)
+               reset $2
+               ;;
+       -b)
+               boot $2
+               ;;
+       -S)
+               shutdown $2
+               ;;
+       -w)
+               wait $2
+               ;;
+       *)
+               echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
+               exit 2
+esac
+
+exit $?
diff --git a/samples/mic/mpssd/mpss b/samples/mic/mpssd/mpss
new file mode 100755 (executable)
index 0000000..5fcf9fa
--- /dev/null
@@ -0,0 +1,200 @@
+#!/bin/bash
+# Intel MIC Platform Software Stack (MPSS)
+#
+# Copyright(c) 2013 Intel Corporation.
+#
+# 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.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Intel MIC User Space Tools.
+#
+# mpss Start mpssd.
+#
+# chkconfig: 2345 95 05
+# description: start MPSS stack processing.
+#
+### BEGIN INIT INFO
+# Provides: mpss
+# Required-Start:
+# Required-Stop:
+# Short-Description: MPSS stack control
+# Description: MPSS stack control
+### END INIT INFO
+
+# Source function library.
+. /etc/init.d/functions
+
+exec=/usr/sbin/mpssd
+sysfs="/sys/class/mic"
+mic_modules="mic_host mic_x100_dma scif vop"
+
+start()
+{
+       [ -x $exec ] || exit 5
+
+       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
+               echo -e $"MPSSD already running! "
+               success
+               echo
+               return 0
+       fi
+
+       echo -e $"Starting MPSS Stack"
+       echo -e $"Loading MIC drivers:" $mic_modules
+
+       modprobe -a $mic_modules
+       RETVAL=$?
+       if [ $RETVAL -ne 0 ]; then
+               failure
+               echo
+               return $RETVAL
+       fi
+
+       # Start the daemon
+       echo -n $"Starting MPSSD "
+       $exec
+       RETVAL=$?
+       if [ $RETVAL -ne 0 ]; then
+               failure
+               echo
+               return $RETVAL
+       fi
+       success
+       echo
+
+       sleep 5
+
+       # Boot the cards
+       micctrl -b
+
+       # Wait till ping works
+       for f in $sysfs/*
+       do
+               count=100
+               ipaddr=`cat $f/cmdline`
+               ipaddr=${ipaddr#*address,}
+               ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
+               while [ $count -ge 0 ]
+               do
+                       echo -e "Pinging "`basename $f`" "
+                       ping -c 1 $ipaddr &> /dev/null
+                       RETVAL=$?
+                       if [ $RETVAL -eq 0 ]; then
+                               success
+                               break
+                       fi
+                       sleep 1
+                       count=`expr $count - 1`
+               done
+               [ $RETVAL -ne 0 ] && failure || success
+               echo
+       done
+       return $RETVAL
+}
+
+stop()
+{
+       echo -e $"Shutting down MPSS Stack: "
+
+       # Bail out if module is unloaded
+       if [ ! -d "$sysfs" ]; then
+               echo -n $"Module unloaded "
+               success
+               echo
+               return 0
+       fi
+
+       # Shut down the cards.
+       micctrl -S
+
+       # Wait for the cards to go offline
+       for f in $sysfs/*
+       do
+               while [ "`cat $f/state`" != "ready" ]
+               do
+                       sleep 1
+                       echo -e "Waiting for "`basename $f`" to become ready"
+               done
+       done
+
+       # Display the status of the cards
+       micctrl -s
+
+       # Kill MPSSD now
+       echo -n $"Killing MPSSD"
+       killall -9 mpssd 2>/dev/null
+       RETVAL=$?
+       [ $RETVAL -ne 0 ] && failure || success
+       echo
+       return $RETVAL
+}
+
+restart()
+{
+       stop
+       sleep 5
+       start
+}
+
+status()
+{
+       micctrl -s
+       if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
+               echo "mpssd is running"
+       else
+               echo "mpssd is stopped"
+       fi
+       return 0
+}
+
+unload()
+{
+       if [ ! -d "$sysfs" ]; then
+               echo -n $"No MIC_HOST Module: "
+               success
+               echo
+               return
+       fi
+
+       stop
+
+       sleep 5
+       echo -n $"Removing MIC drivers:" $mic_modules
+       modprobe -r $mic_modules
+       RETVAL=$?
+       [ $RETVAL -ne 0 ] && failure || success
+       echo
+       return $RETVAL
+}
+
+case $1 in
+       start)
+               start
+               ;;
+       stop)
+               stop
+               ;;
+       restart)
+               restart
+               ;;
+       status)
+               status
+               ;;
+       unload)
+               unload
+               ;;
+       *)
+               echo $"Usage: $0 {start|stop|restart|status|unload}"
+               exit 2
+esac
+
+exit $?
diff --git a/samples/mic/mpssd/mpssd.c b/samples/mic/mpssd/mpssd.c
new file mode 100644 (file)
index 0000000..49db1de
--- /dev/null
@@ -0,0 +1,1826 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <poll.h>
+#include <features.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <linux/virtio_ring.h>
+#include <linux/virtio_net.h>
+#include <linux/virtio_console.h>
+#include <linux/virtio_blk.h>
+#include <linux/version.h>
+#include "mpssd.h"
+#include <linux/mic_ioctl.h>
+#include <linux/mic_common.h>
+#include <tools/endian.h>
+
+static void *init_mic(void *arg);
+
+static FILE *logfp;
+static struct mic_info mic_list;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define min_t(type, x, y) ({                           \
+               type __min1 = (x);                      \
+               type __min2 = (y);                      \
+               __min1 < __min2 ? __min1 : __min2; })
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_DOWN(addr, size)  ((addr)&(~((size)-1)))
+#define _ALIGN_UP(addr, size)    _ALIGN_DOWN(addr + size - 1, size)
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)        _ALIGN(addr, PAGE_SIZE)
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+#define GSO_ENABLED            1
+#define MAX_GSO_SIZE           (64 * 1024)
+#define ETH_H_LEN              14
+#define MAX_NET_PKT_SIZE       (_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
+#define MIC_DEVICE_PAGE_END    0x1000
+
+#ifndef VIRTIO_NET_HDR_F_DATA_VALID
+#define VIRTIO_NET_HDR_F_DATA_VALID    2       /* Csum is valid */
+#endif
+
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[2];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_console_config cons_config;
+} virtcons_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_CONSOLE,
+               .num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
+               .feature_len = sizeof(virtcons_dev_page.host_features),
+               .config_len = sizeof(virtcons_dev_page.cons_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .vqconfig[1] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+};
+
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[2];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_net_config net_config;
+} virtnet_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_NET,
+               .num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
+               .feature_len = sizeof(virtnet_dev_page.host_features),
+               .config_len = sizeof(virtnet_dev_page.net_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .vqconfig[1] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+#if GSO_ENABLED
+       .host_features = htole32(
+               1 << VIRTIO_NET_F_CSUM |
+               1 << VIRTIO_NET_F_GSO |
+               1 << VIRTIO_NET_F_GUEST_TSO4 |
+               1 << VIRTIO_NET_F_GUEST_TSO6 |
+               1 << VIRTIO_NET_F_GUEST_ECN),
+#else
+               .host_features = 0,
+#endif
+};
+
+static const char *mic_config_dir = "/etc/mpss";
+static const char *virtblk_backend = "VIRTBLK_BACKEND";
+static struct {
+       struct mic_device_desc dd;
+       struct mic_vqconfig vqconfig[1];
+       __u32 host_features, guest_acknowledgements;
+       struct virtio_blk_config blk_config;
+} virtblk_dev_page = {
+       .dd = {
+               .type = VIRTIO_ID_BLOCK,
+               .num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
+               .feature_len = sizeof(virtblk_dev_page.host_features),
+               .config_len = sizeof(virtblk_dev_page.blk_config),
+       },
+       .vqconfig[0] = {
+               .num = htole16(MIC_VRING_ENTRIES),
+       },
+       .host_features =
+               htole32(1<<VIRTIO_BLK_F_SEG_MAX),
+       .blk_config = {
+               .seg_max = htole32(MIC_VRING_ENTRIES - 2),
+               .capacity = htole64(0),
+        }
+};
+
+static char *myname;
+
+static int
+tap_configure(struct mic_info *mic, char *dev)
+{
+       pid_t pid;
+       char *ifargv[7];
+       char ipaddr[IFNAMSIZ];
+       int ret = 0;
+
+       pid = fork();
+       if (pid == 0) {
+               ifargv[0] = "ip";
+               ifargv[1] = "link";
+               ifargv[2] = "set";
+               ifargv[3] = dev;
+               ifargv[4] = "up";
+               ifargv[5] = NULL;
+               mpsslog("Configuring %s\n", dev);
+               ret = execvp("ip", ifargv);
+               if (ret < 0) {
+                       mpsslog("%s execvp failed errno %s\n",
+                               mic->name, strerror(errno));
+                       return ret;
+               }
+       }
+       if (pid < 0) {
+               mpsslog("%s fork failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       ret = waitpid(pid, NULL, 0);
+       if (ret < 0) {
+               mpsslog("%s waitpid failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id + 1);
+
+       pid = fork();
+       if (pid == 0) {
+               ifargv[0] = "ip";
+               ifargv[1] = "addr";
+               ifargv[2] = "add";
+               ifargv[3] = ipaddr;
+               ifargv[4] = "dev";
+               ifargv[5] = dev;
+               ifargv[6] = NULL;
+               mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
+               ret = execvp("ip", ifargv);
+               if (ret < 0) {
+                       mpsslog("%s execvp failed errno %s\n",
+                               mic->name, strerror(errno));
+                       return ret;
+               }
+       }
+       if (pid < 0) {
+               mpsslog("%s fork failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+
+       ret = waitpid(pid, NULL, 0);
+       if (ret < 0) {
+               mpsslog("%s waitpid failed errno %s\n",
+                       mic->name, strerror(errno));
+               return ret;
+       }
+       mpsslog("MIC name %s %s %d DONE!\n",
+               mic->name, __func__, __LINE__);
+       return 0;
+}
+
+static int tun_alloc(struct mic_info *mic, char *dev)
+{
+       struct ifreq ifr;
+       int fd, err;
+#if GSO_ENABLED
+       unsigned offload;
+#endif
+       fd = open("/dev/net/tun", O_RDWR);
+       if (fd < 0) {
+               mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
+               goto done;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+
+       ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+       if (*dev)
+               strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+
+       err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+       if (err < 0) {
+               mpsslog("%s %s %d TUNSETIFF failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               close(fd);
+               return err;
+       }
+#if GSO_ENABLED
+       offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
+
+       err = ioctl(fd, TUNSETOFFLOAD, offload);
+       if (err < 0) {
+               mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               close(fd);
+               return err;
+       }
+#endif
+       strcpy(dev, ifr.ifr_name);
+       mpsslog("Created TAP %s\n", dev);
+done:
+       return fd;
+}
+
+#define NET_FD_VIRTIO_NET 0
+#define NET_FD_TUN 1
+#define MAX_NET_FD 2
+
+static void set_dp(struct mic_info *mic, int type, void *dp)
+{
+       switch (type) {
+       case VIRTIO_ID_CONSOLE:
+               mic->mic_console.console_dp = dp;
+               return;
+       case VIRTIO_ID_NET:
+               mic->mic_net.net_dp = dp;
+               return;
+       case VIRTIO_ID_BLOCK:
+               mic->mic_virtblk.block_dp = dp;
+               return;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       assert(0);
+}
+
+static void *get_dp(struct mic_info *mic, int type)
+{
+       switch (type) {
+       case VIRTIO_ID_CONSOLE:
+               return mic->mic_console.console_dp;
+       case VIRTIO_ID_NET:
+               return mic->mic_net.net_dp;
+       case VIRTIO_ID_BLOCK:
+               return mic->mic_virtblk.block_dp;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       assert(0);
+       return NULL;
+}
+
+static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
+{
+       struct mic_device_desc *d;
+       int i;
+       void *dp = get_dp(mic, type);
+
+       for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
+               i += mic_total_desc_size(d)) {
+               d = dp + i;
+
+               /* End of list */
+               if (d->type == 0)
+                       break;
+
+               if (d->type == -1)
+                       continue;
+
+               mpsslog("%s %s d-> type %d d %p\n",
+                       mic->name, __func__, d->type, d);
+
+               if (d->type == (__u8)type)
+                       return d;
+       }
+       mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+       return NULL;
+}
+
+/* See comments in vhost.c for explanation of next_desc() */
+static unsigned next_desc(struct vring_desc *desc)
+{
+       unsigned int next;
+
+       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
+               return -1U;
+       next = le16toh(desc->next);
+       return next;
+}
+
+/* Sum up all the IOVEC length */
+static ssize_t
+sum_iovec_len(struct mic_copy_desc *copy)
+{
+       ssize_t sum = 0;
+       unsigned int i;
+
+       for (i = 0; i < copy->iovcnt; i++)
+               sum += copy->iov[i].iov_len;
+       return sum;
+}
+
+static inline void verify_out_len(struct mic_info *mic,
+       struct mic_copy_desc *copy)
+{
+       if (copy->out_len != sum_iovec_len(copy)) {
+               mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
+                       mic->name, __func__, __LINE__,
+                       copy->out_len, sum_iovec_len(copy));
+               assert(copy->out_len == sum_iovec_len(copy));
+       }
+}
+
+/* Display an iovec */
+static void
+disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
+          const char *s, int line)
+{
+       unsigned int i;
+
+       for (i = 0; i < copy->iovcnt; i++)
+               mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
+                       mic->name, s, line, i,
+                       copy->iov[i].iov_base, copy->iov[i].iov_len);
+}
+
+static inline __u16 read_avail_idx(struct mic_vring *vr)
+{
+       return ACCESS_ONCE(vr->info->avail_idx);
+}
+
+static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
+                               struct mic_copy_desc *copy, ssize_t len)
+{
+       copy->vr_idx = tx ? 0 : 1;
+       copy->update_used = true;
+       if (type == VIRTIO_ID_NET)
+               copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
+       else
+               copy->iov[0].iov_len = len;
+}
+
+/* Central API which triggers the copies */
+static int
+mic_virtio_copy(struct mic_info *mic, int fd,
+               struct mic_vring *vr, struct mic_copy_desc *copy)
+{
+       int ret;
+
+       ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
+       if (ret) {
+               mpsslog("%s %s %d errno %s ret %d\n",
+                       mic->name, __func__, __LINE__,
+                       strerror(errno), ret);
+       }
+       return ret;
+}
+
+static inline unsigned _vring_size(unsigned int num, unsigned long align)
+{
+       return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
+                               + align - 1) & ~(align - 1))
+               + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
+/*
+ * This initialization routine requires at least one
+ * vring i.e. vr0. vr1 is optional.
+ */
+static void *
+init_vr(struct mic_info *mic, int fd, int type,
+       struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
+{
+       int vr_size;
+       char *va;
+
+       vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
+                                        MIC_VIRTIO_RING_ALIGN) +
+                            sizeof(struct _mic_vring_info));
+       va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
+               PROT_READ, MAP_SHARED, fd, 0);
+       if (MAP_FAILED == va) {
+               mpsslog("%s %s %d mmap failed errno %s\n",
+                       mic->name, __func__, __LINE__,
+                       strerror(errno));
+               goto done;
+       }
+       set_dp(mic, type, va);
+       vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
+       vr0->info = vr0->va +
+               _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
+       vring_init(&vr0->vr,
+                  MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
+       mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
+               __func__, mic->name, vr0->va, vr0->info, vr_size,
+               _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
+       mpsslog("magic 0x%x expected 0x%x\n",
+               le32toh(vr0->info->magic), MIC_MAGIC + type);
+       assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
+       if (vr1) {
+               vr1->va = (struct mic_vring *)
+                       &va[MIC_DEVICE_PAGE_END + vr_size];
+               vr1->info = vr1->va + _vring_size(MIC_VRING_ENTRIES,
+                       MIC_VIRTIO_RING_ALIGN);
+               vring_init(&vr1->vr,
+                          MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
+               mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
+                       __func__, mic->name, vr1->va, vr1->info, vr_size,
+                       _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
+               mpsslog("magic 0x%x expected 0x%x\n",
+                       le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
+               assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
+       }
+done:
+       return va;
+}
+
+static int
+wait_for_card_driver(struct mic_info *mic, int fd, int type)
+{
+       struct pollfd pollfd;
+       int err;
+       struct mic_device_desc *desc = get_device_desc(mic, type);
+       __u8 prev_status;
+
+       if (!desc)
+               return -ENODEV;
+       prev_status = desc->status;
+       pollfd.fd = fd;
+       mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
+               mic->name, __func__, type, desc->status);
+
+       while (1) {
+               pollfd.events = POLLIN;
+               pollfd.revents = 0;
+               err = poll(&pollfd, 1, -1);
+               if (err < 0) {
+                       mpsslog("%s %s poll failed %s\n",
+                               mic->name, __func__, strerror(errno));
+                       continue;
+               }
+
+               if (pollfd.revents) {
+                       if (desc->status != prev_status) {
+                               mpsslog("%s %s Waiting... desc-> type %d "
+                                       "status 0x%x\n",
+                                       mic->name, __func__, type,
+                                       desc->status);
+                               prev_status = desc->status;
+                       }
+                       if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
+                               mpsslog("%s %s poll.revents %d\n",
+                                       mic->name, __func__, pollfd.revents);
+                               mpsslog("%s %s desc-> type %d status 0x%x\n",
+                                       mic->name, __func__, type,
+                                       desc->status);
+                               break;
+                       }
+               }
+       }
+       return 0;
+}
+
+/* Spin till we have some descriptors */
+static void
+spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
+{
+       __u16 avail_idx = read_avail_idx(vr);
+
+       while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
+#ifdef DEBUG
+               mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
+                       mic->name, __func__,
+                       le16toh(vr->vr.avail->idx), vr->info->avail_idx);
+#endif
+               sched_yield();
+       }
+}
+
+static void *
+virtio_net(void *arg)
+{
+       static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
+       static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
+       struct iovec vnet_iov[2][2] = {
+               { { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
+                 { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
+               { { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
+                 { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
+       };
+       struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
+       struct mic_info *mic = (struct mic_info *)arg;
+       char if_name[IFNAMSIZ];
+       struct pollfd net_poll[MAX_NET_FD];
+       struct mic_vring tx_vr, rx_vr;
+       struct mic_copy_desc copy;
+       struct mic_device_desc *desc;
+       int err;
+
+       snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
+       mic->mic_net.tap_fd = tun_alloc(mic, if_name);
+       if (mic->mic_net.tap_fd < 0)
+               goto done;
+
+       if (tap_configure(mic, if_name))
+               goto done;
+       mpsslog("MIC name %s id %d\n", mic->name, mic->id);
+
+       net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
+       net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
+       net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
+       net_poll[NET_FD_TUN].events = POLLIN;
+
+       if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
+                                 VIRTIO_ID_NET, &tx_vr, &rx_vr,
+               virtnet_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               goto done;
+       }
+
+       copy.iovcnt = 2;
+       desc = get_device_desc(mic, VIRTIO_ID_NET);
+
+       while (1) {
+               ssize_t len;
+
+               net_poll[NET_FD_VIRTIO_NET].revents = 0;
+               net_poll[NET_FD_TUN].revents = 0;
+
+               /* Start polling for data from tap and virtio net */
+               err = poll(net_poll, 2, -1);
+               if (err < 0) {
+                       mpsslog("%s poll failed %s\n",
+                               __func__, strerror(errno));
+                       continue;
+               }
+               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+                       err = wait_for_card_driver(mic,
+                                                  mic->mic_net.virtio_net_fd,
+                                                  VIRTIO_ID_NET);
+                       if (err) {
+                               mpsslog("%s %s %d Exiting...\n",
+                                       mic->name, __func__, __LINE__);
+                               break;
+                       }
+               }
+               /*
+                * Check if there is data to be read from TUN and write to
+                * virtio net fd if there is.
+                */
+               if (net_poll[NET_FD_TUN].revents & POLLIN) {
+                       copy.iov = iov0;
+                       len = readv(net_poll[NET_FD_TUN].fd,
+                               copy.iov, copy.iovcnt);
+                       if (len > 0) {
+                               struct virtio_net_hdr *hdr
+                                       = (struct virtio_net_hdr *)vnet_hdr[0];
+
+                               /* Disable checksums on the card since we are on
+                                  a reliable PCIe link */
+                               hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
+#ifdef DEBUG
+                               mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
+                                       __func__, __LINE__, hdr->flags);
+                               mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
+                                       copy.out_len, hdr->gso_type);
+#endif
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read from tap 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       len);
+#endif
+                               spin_for_descriptors(mic, &tx_vr);
+                               txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
+                                            len);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_net.virtio_net_fd, &tx_vr,
+                                       &copy);
+                               if (err < 0) {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                               }
+                               if (!err)
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d wrote to net 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       sum_iovec_len(&copy));
+#endif
+                               /* Reinitialize IOV for next run */
+                               iov0[1].iov_len = MAX_NET_PKT_SIZE;
+                       } else if (len < 0) {
+                               disp_iovec(mic, &copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read failed %s ", mic->name,
+                                       __func__, __LINE__, strerror(errno));
+                               mpsslog("cnt %d sum %zd\n",
+                                       copy.iovcnt, sum_iovec_len(&copy));
+                       }
+               }
+
+               /*
+                * Check if there is data to be read from virtio net and
+                * write to TUN if there is.
+                */
+               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
+                       while (rx_vr.info->avail_idx !=
+                               le16toh(rx_vr.vr.avail->idx)) {
+                               copy.iov = iov1;
+                               txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
+                                            MAX_NET_PKT_SIZE
+                                       + sizeof(struct virtio_net_hdr));
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_net.virtio_net_fd, &rx_vr,
+                                       &copy);
+                               if (!err) {
+#ifdef DEBUG
+                                       struct virtio_net_hdr *hdr
+                                               = (struct virtio_net_hdr *)
+                                                       vnet_hdr[1];
+
+                                       mpsslog("%s %s %d hdr->flags 0x%x, ",
+                                               mic->name, __func__, __LINE__,
+                                               hdr->flags);
+                                       mpsslog("out_len %d gso_type 0x%x\n",
+                                               copy.out_len,
+                                               hdr->gso_type);
+#endif
+                                       /* Set the correct output iov_len */
+                                       iov1[1].iov_len = copy.out_len -
+                                               sizeof(struct virtio_net_hdr);
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                                       disp_iovec(mic, copy, __func__,
+                                                  __LINE__);
+                                       mpsslog("%s %s %d ",
+                                               mic->name, __func__, __LINE__);
+                                       mpsslog("read from net 0x%lx\n",
+                                               sum_iovec_len(copy));
+#endif
+                                       len = writev(net_poll[NET_FD_TUN].fd,
+                                               copy.iov, copy.iovcnt);
+                                       if (len != sum_iovec_len(&copy)) {
+                                               mpsslog("Tun write failed %s ",
+                                                       strerror(errno));
+                                               mpsslog("len 0x%zx ", len);
+                                               mpsslog("read_len 0x%zx\n",
+                                                       sum_iovec_len(&copy));
+                                       } else {
+#ifdef DEBUG
+                                               disp_iovec(mic, &copy, __func__,
+                                                          __LINE__);
+                                               mpsslog("%s %s %d ",
+                                                       mic->name, __func__,
+                                                       __LINE__);
+                                               mpsslog("wrote to tap 0x%lx\n",
+                                                       len);
+#endif
+                                       }
+                               } else {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                                       break;
+                               }
+                       }
+               }
+               if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+       }
+done:
+       pthread_exit(NULL);
+}
+
+/* virtio_console */
+#define VIRTIO_CONSOLE_FD 0
+#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
+#define MAX_CONSOLE_FD (MONITOR_FD + 1)  /* must be the last one + 1 */
+#define MAX_BUFFER_SIZE PAGE_SIZE
+
+static void *
+virtio_console(void *arg)
+{
+       static __u8 vcons_buf[2][PAGE_SIZE];
+       struct iovec vcons_iov[2] = {
+               { .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
+               { .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
+       };
+       struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
+       struct mic_info *mic = (struct mic_info *)arg;
+       int err;
+       struct pollfd console_poll[MAX_CONSOLE_FD];
+       int pty_fd;
+       char *pts_name;
+       ssize_t len;
+       struct mic_vring tx_vr, rx_vr;
+       struct mic_copy_desc copy;
+       struct mic_device_desc *desc;
+
+       pty_fd = posix_openpt(O_RDWR);
+       if (pty_fd < 0) {
+               mpsslog("can't open a pseudoterminal master device: %s\n",
+                       strerror(errno));
+               goto _return;
+       }
+       pts_name = ptsname(pty_fd);
+       if (pts_name == NULL) {
+               mpsslog("can't get pts name\n");
+               goto _close_pty;
+       }
+       printf("%s console message goes to %s\n", mic->name, pts_name);
+       mpsslog("%s console message goes to %s\n", mic->name, pts_name);
+       err = grantpt(pty_fd);
+       if (err < 0) {
+               mpsslog("can't grant access: %s %s\n",
+                       pts_name, strerror(errno));
+               goto _close_pty;
+       }
+       err = unlockpt(pty_fd);
+       if (err < 0) {
+               mpsslog("can't unlock a pseudoterminal: %s %s\n",
+                       pts_name, strerror(errno));
+               goto _close_pty;
+       }
+       console_poll[MONITOR_FD].fd = pty_fd;
+       console_poll[MONITOR_FD].events = POLLIN;
+
+       console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
+       console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
+
+       if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
+                                 VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
+               virtcons_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               goto _close_pty;
+       }
+
+       copy.iovcnt = 1;
+       desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
+
+       for (;;) {
+               console_poll[MONITOR_FD].revents = 0;
+               console_poll[VIRTIO_CONSOLE_FD].revents = 0;
+               err = poll(console_poll, MAX_CONSOLE_FD, -1);
+               if (err < 0) {
+                       mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
+                               strerror(errno));
+                       continue;
+               }
+               if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+                       err = wait_for_card_driver(mic,
+                                       mic->mic_console.virtio_console_fd,
+                                       VIRTIO_ID_CONSOLE);
+                       if (err) {
+                               mpsslog("%s %s %d Exiting...\n",
+                                       mic->name, __func__, __LINE__);
+                               break;
+                       }
+               }
+
+               if (console_poll[MONITOR_FD].revents & POLLIN) {
+                       copy.iov = iov0;
+                       len = readv(pty_fd, copy.iov, copy.iovcnt);
+                       if (len > 0) {
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read from tap 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       len);
+#endif
+                               spin_for_descriptors(mic, &tx_vr);
+                               txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
+                                            &copy, len);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_console.virtio_console_fd,
+                                       &tx_vr, &copy);
+                               if (err < 0) {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                               }
+                               if (!err)
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                               disp_iovec(mic, copy, __func__, __LINE__);
+                               mpsslog("%s %s %d wrote to net 0x%lx\n",
+                                       mic->name, __func__, __LINE__,
+                                       sum_iovec_len(copy));
+#endif
+                               /* Reinitialize IOV for next run */
+                               iov0->iov_len = PAGE_SIZE;
+                       } else if (len < 0) {
+                               disp_iovec(mic, &copy, __func__, __LINE__);
+                               mpsslog("%s %s %d read failed %s ",
+                                       mic->name, __func__, __LINE__,
+                                       strerror(errno));
+                               mpsslog("cnt %d sum %zd\n",
+                                       copy.iovcnt, sum_iovec_len(&copy));
+                       }
+               }
+
+               if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
+                       while (rx_vr.info->avail_idx !=
+                               le16toh(rx_vr.vr.avail->idx)) {
+                               copy.iov = iov1;
+                               txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
+                                            &copy, PAGE_SIZE);
+
+                               err = mic_virtio_copy(mic,
+                                       mic->mic_console.virtio_console_fd,
+                                       &rx_vr, &copy);
+                               if (!err) {
+                                       /* Set the correct output iov_len */
+                                       iov1->iov_len = copy.out_len;
+                                       verify_out_len(mic, &copy);
+#ifdef DEBUG
+                                       disp_iovec(mic, copy, __func__,
+                                                  __LINE__);
+                                       mpsslog("%s %s %d ",
+                                               mic->name, __func__, __LINE__);
+                                       mpsslog("read from net 0x%lx\n",
+                                               sum_iovec_len(copy));
+#endif
+                                       len = writev(pty_fd,
+                                               copy.iov, copy.iovcnt);
+                                       if (len != sum_iovec_len(&copy)) {
+                                               mpsslog("Tun write failed %s ",
+                                                       strerror(errno));
+                                               mpsslog("len 0x%zx ", len);
+                                               mpsslog("read_len 0x%zx\n",
+                                                       sum_iovec_len(&copy));
+                                       } else {
+#ifdef DEBUG
+                                               disp_iovec(mic, copy, __func__,
+                                                          __LINE__);
+                                               mpsslog("%s %s %d ",
+                                                       mic->name, __func__,
+                                                       __LINE__);
+                                               mpsslog("wrote to tap 0x%lx\n",
+                                                       len);
+#endif
+                                       }
+                               } else {
+                                       mpsslog("%s %s %d mic_virtio_copy %s\n",
+                                               mic->name, __func__, __LINE__,
+                                               strerror(errno));
+                                       break;
+                               }
+                       }
+               }
+               if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+                       mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+       }
+_close_pty:
+       close(pty_fd);
+_return:
+       pthread_exit(NULL);
+}
+
+static void
+add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
+{
+       char path[PATH_MAX];
+       int fd, err;
+
+       snprintf(path, PATH_MAX, "/dev/vop_virtio%d", mic->id);
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               mpsslog("Could not open %s %s\n", path, strerror(errno));
+               return;
+       }
+
+       err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
+       if (err < 0) {
+               mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
+               close(fd);
+               return;
+       }
+       switch (dd->type) {
+       case VIRTIO_ID_NET:
+               mic->mic_net.virtio_net_fd = fd;
+               mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
+               break;
+       case VIRTIO_ID_CONSOLE:
+               mic->mic_console.virtio_console_fd = fd;
+               mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
+               break;
+       case VIRTIO_ID_BLOCK:
+               mic->mic_virtblk.virtio_block_fd = fd;
+               mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
+               break;
+       }
+}
+
+static bool
+set_backend_file(struct mic_info *mic)
+{
+       FILE *config;
+       char buff[PATH_MAX], *line, *evv, *p;
+
+       snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
+       config = fopen(buff, "r");
+       if (config == NULL)
+               return false;
+       do {  /* look for "virtblk_backend=XXXX" */
+               line = fgets(buff, PATH_MAX, config);
+               if (line == NULL)
+                       break;
+               if (*line == '#')
+                       continue;
+               p = strchr(line, '\n');
+               if (p)
+                       *p = '\0';
+       } while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
+       fclose(config);
+       if (line == NULL)
+               return false;
+       evv = strchr(line, '=');
+       if (evv == NULL)
+               return false;
+       mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
+       if (mic->mic_virtblk.backend_file == NULL) {
+               mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
+               return false;
+       }
+       strcpy(mic->mic_virtblk.backend_file, evv + 1);
+       return true;
+}
+
+#define SECTOR_SIZE 512
+static bool
+set_backend_size(struct mic_info *mic)
+{
+       mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
+               SEEK_END);
+       if (mic->mic_virtblk.backend_size < 0) {
+               mpsslog("%s: can't seek: %s\n",
+                       mic->name, mic->mic_virtblk.backend_file);
+               return false;
+       }
+       virtblk_dev_page.blk_config.capacity =
+               mic->mic_virtblk.backend_size / SECTOR_SIZE;
+       if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
+               virtblk_dev_page.blk_config.capacity++;
+
+       virtblk_dev_page.blk_config.capacity =
+               htole64(virtblk_dev_page.blk_config.capacity);
+
+       return true;
+}
+
+static bool
+open_backend(struct mic_info *mic)
+{
+       if (!set_backend_file(mic))
+               goto _error_exit;
+       mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
+       if (mic->mic_virtblk.backend < 0) {
+               mpsslog("%s: can't open: %s\n", mic->name,
+                       mic->mic_virtblk.backend_file);
+               goto _error_free;
+       }
+       if (!set_backend_size(mic))
+               goto _error_close;
+       mic->mic_virtblk.backend_addr = mmap(NULL,
+               mic->mic_virtblk.backend_size,
+               PROT_READ|PROT_WRITE, MAP_SHARED,
+               mic->mic_virtblk.backend, 0L);
+       if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
+               mpsslog("%s: can't map: %s %s\n",
+                       mic->name, mic->mic_virtblk.backend_file,
+                       strerror(errno));
+               goto _error_close;
+       }
+       return true;
+
+ _error_close:
+       close(mic->mic_virtblk.backend);
+ _error_free:
+       free(mic->mic_virtblk.backend_file);
+ _error_exit:
+       return false;
+}
+
+static void
+close_backend(struct mic_info *mic)
+{
+       munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
+       close(mic->mic_virtblk.backend);
+       free(mic->mic_virtblk.backend_file);
+}
+
+static bool
+start_virtblk(struct mic_info *mic, struct mic_vring *vring)
+{
+       if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
+               mpsslog("%s: blk_config is not 8 byte aligned.\n",
+                       mic->name);
+               return false;
+       }
+       add_virtio_device(mic, &virtblk_dev_page.dd);
+       if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
+                                 VIRTIO_ID_BLOCK, vring, NULL,
+                                 virtblk_dev_page.dd.num_vq)) {
+               mpsslog("%s init_vr failed %s\n",
+                       mic->name, strerror(errno));
+               return false;
+       }
+       return true;
+}
+
+static void
+stop_virtblk(struct mic_info *mic)
+{
+       int vr_size, ret;
+
+       vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
+                                        MIC_VIRTIO_RING_ALIGN) +
+                            sizeof(struct _mic_vring_info));
+       ret = munmap(mic->mic_virtblk.block_dp,
+               MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
+       if (ret < 0)
+               mpsslog("%s munmap errno %d\n", mic->name, errno);
+       close(mic->mic_virtblk.virtio_block_fd);
+}
+
+static __u8
+header_error_check(struct vring_desc *desc)
+{
+       if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
+               mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
+               mpsslog("%s() %d: alone\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
+               mpsslog("%s() %d: not read\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int
+read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
+{
+       struct iovec iovec;
+       struct mic_copy_desc copy;
+
+       iovec.iov_len = sizeof(*hdr);
+       iovec.iov_base = hdr;
+       copy.iov = &iovec;
+       copy.iovcnt = 1;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = false;  /* do not update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+static int
+transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
+{
+       struct mic_copy_desc copy;
+
+       copy.iov = iovec;
+       copy.iovcnt = iovcnt;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = false;  /* do not update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+static __u8
+status_error_check(struct vring_desc *desc)
+{
+       if (le32toh(desc->len) != sizeof(__u8)) {
+               mpsslog("%s() %d: length is not sizeof(status)\n",
+                       __func__, __LINE__);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int
+write_status(int fd, __u8 *status)
+{
+       struct iovec iovec;
+       struct mic_copy_desc copy;
+
+       iovec.iov_base = status;
+       iovec.iov_len = sizeof(*status);
+       copy.iov = &iovec;
+       copy.iovcnt = 1;
+       copy.vr_idx = 0;  /* only one vring on virtio_block */
+       copy.update_used = true; /* Update used index */
+       return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+}
+
+#ifndef VIRTIO_BLK_T_GET_ID
+#define VIRTIO_BLK_T_GET_ID    8
+#endif
+
+static void *
+virtio_block(void *arg)
+{
+       struct mic_info *mic = (struct mic_info *)arg;
+       int ret;
+       struct pollfd block_poll;
+       struct mic_vring vring;
+       __u16 avail_idx;
+       __u32 desc_idx;
+       struct vring_desc *desc;
+       struct iovec *iovec, *piov;
+       __u8 status;
+       __u32 buffer_desc_idx;
+       struct virtio_blk_outhdr hdr;
+       void *fos;
+
+       for (;;) {  /* forever */
+               if (!open_backend(mic)) { /* No virtblk */
+                       for (mic->mic_virtblk.signaled = 0;
+                               !mic->mic_virtblk.signaled;)
+                               sleep(1);
+                       continue;
+               }
+
+               /* backend file is specified. */
+               if (!start_virtblk(mic, &vring))
+                       goto _close_backend;
+               iovec = malloc(sizeof(*iovec) *
+                       le32toh(virtblk_dev_page.blk_config.seg_max));
+               if (!iovec) {
+                       mpsslog("%s: can't alloc iovec: %s\n",
+                               mic->name, strerror(ENOMEM));
+                       goto _stop_virtblk;
+               }
+
+               block_poll.fd = mic->mic_virtblk.virtio_block_fd;
+               block_poll.events = POLLIN;
+               for (mic->mic_virtblk.signaled = 0;
+                    !mic->mic_virtblk.signaled;) {
+                       block_poll.revents = 0;
+                                       /* timeout in 1 sec to see signaled */
+                       ret = poll(&block_poll, 1, 1000);
+                       if (ret < 0) {
+                               mpsslog("%s %d: poll failed: %s\n",
+                                       __func__, __LINE__,
+                                       strerror(errno));
+                               continue;
+                       }
+
+                       if (!(block_poll.revents & POLLIN)) {
+#ifdef DEBUG
+                               mpsslog("%s %d: block_poll.revents=0x%x\n",
+                                       __func__, __LINE__, block_poll.revents);
+#endif
+                               continue;
+                       }
+
+                       /* POLLIN */
+                       while (vring.info->avail_idx !=
+                               le16toh(vring.vr.avail->idx)) {
+                               /* read header element */
+                               avail_idx =
+                                       vring.info->avail_idx &
+                                       (vring.vr.num - 1);
+                               desc_idx = le16toh(
+                                       vring.vr.avail->ring[avail_idx]);
+                               desc = &vring.vr.desc[desc_idx];
+#ifdef DEBUG
+                               mpsslog("%s() %d: avail_idx=%d ",
+                                       __func__, __LINE__,
+                                       vring.info->avail_idx);
+                               mpsslog("vring.vr.num=%d desc=%p\n",
+                                       vring.vr.num, desc);
+#endif
+                               status = header_error_check(desc);
+                               ret = read_header(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                       &hdr, desc_idx);
+                               if (ret < 0) {
+                                       mpsslog("%s() %d %s: ret=%d %s\n",
+                                               __func__, __LINE__,
+                                               mic->name, ret,
+                                               strerror(errno));
+                                       break;
+                               }
+                               /* buffer element */
+                               piov = iovec;
+                               status = 0;
+                               fos = mic->mic_virtblk.backend_addr +
+                                       (hdr.sector * SECTOR_SIZE);
+                               buffer_desc_idx = next_desc(desc);
+                               desc_idx = buffer_desc_idx;
+                               for (desc = &vring.vr.desc[buffer_desc_idx];
+                                    desc->flags & VRING_DESC_F_NEXT;
+                                    desc_idx = next_desc(desc),
+                                            desc = &vring.vr.desc[desc_idx]) {
+                                       piov->iov_len = desc->len;
+                                       piov->iov_base = fos;
+                                       piov++;
+                                       fos += desc->len;
+                               }
+                               /* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
+                               if (hdr.type & ~(VIRTIO_BLK_T_OUT |
+                                       VIRTIO_BLK_T_GET_ID)) {
+                                       /*
+                                         VIRTIO_BLK_T_IN - does not do
+                                         anything. Probably for documenting.
+                                         VIRTIO_BLK_T_SCSI_CMD - for
+                                         virtio_scsi.
+                                         VIRTIO_BLK_T_FLUSH - turned off in
+                                         config space.
+                                         VIRTIO_BLK_T_BARRIER - defined but not
+                                         used in anywhere.
+                                       */
+                                       mpsslog("%s() %d: type %x ",
+                                               __func__, __LINE__,
+                                               hdr.type);
+                                       mpsslog("is not supported\n");
+                                       status = -ENOTSUP;
+
+                               } else {
+                                       ret = transfer_blocks(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                               iovec,
+                                               piov - iovec);
+                                       if (ret < 0 &&
+                                           status != 0)
+                                               status = ret;
+                               }
+                               /* write status and update used pointer */
+                               if (status != 0)
+                                       status = status_error_check(desc);
+                               ret = write_status(
+                                       mic->mic_virtblk.virtio_block_fd,
+                                       &status);
+#ifdef DEBUG
+                               mpsslog("%s() %d: write status=%d on desc=%p\n",
+                                       __func__, __LINE__,
+                                       status, desc);
+#endif
+                       }
+               }
+               free(iovec);
+_stop_virtblk:
+               stop_virtblk(mic);
+_close_backend:
+               close_backend(mic);
+       }  /* forever */
+
+       pthread_exit(NULL);
+}
+
+static void
+reset(struct mic_info *mic)
+{
+#define RESET_TIMEOUT 120
+       int i = RESET_TIMEOUT;
+       setsysfs(mic->name, "state", "reset");
+       while (i) {
+               char *state;
+               state = readsysfs(mic->name, "state");
+               if (!state)
+                       goto retry;
+               mpsslog("%s: %s %d state %s\n",
+                       mic->name, __func__, __LINE__, state);
+
+               if (!strcmp(state, "ready")) {
+                       free(state);
+                       break;
+               }
+               free(state);
+retry:
+               sleep(1);
+               i--;
+       }
+}
+
+static int
+get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
+{
+       if (!strcmp(shutdown_status, "nop"))
+               return MIC_NOP;
+       if (!strcmp(shutdown_status, "crashed"))
+               return MIC_CRASHED;
+       if (!strcmp(shutdown_status, "halted"))
+               return MIC_HALTED;
+       if (!strcmp(shutdown_status, "poweroff"))
+               return MIC_POWER_OFF;
+       if (!strcmp(shutdown_status, "restart"))
+               return MIC_RESTART;
+       mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
+       /* Invalid state */
+       assert(0);
+};
+
+static int get_mic_state(struct mic_info *mic)
+{
+       char *state = NULL;
+       enum mic_states mic_state;
+
+       while (!state) {
+               state = readsysfs(mic->name, "state");
+               sleep(1);
+       }
+       mpsslog("%s: %s %d state %s\n",
+               mic->name, __func__, __LINE__, state);
+
+       if (!strcmp(state, "ready")) {
+               mic_state = MIC_READY;
+       } else if (!strcmp(state, "booting")) {
+               mic_state = MIC_BOOTING;
+       } else if (!strcmp(state, "online")) {
+               mic_state = MIC_ONLINE;
+       } else if (!strcmp(state, "shutting_down")) {
+               mic_state = MIC_SHUTTING_DOWN;
+       } else if (!strcmp(state, "reset_failed")) {
+               mic_state = MIC_RESET_FAILED;
+       } else if (!strcmp(state, "resetting")) {
+               mic_state = MIC_RESETTING;
+       } else {
+               mpsslog("%s: BUG invalid state %s\n", mic->name, state);
+               assert(0);
+       }
+
+       free(state);
+       return mic_state;
+};
+
+static void mic_handle_shutdown(struct mic_info *mic)
+{
+#define SHUTDOWN_TIMEOUT 60
+       int i = SHUTDOWN_TIMEOUT;
+       char *shutdown_status;
+       while (i) {
+               shutdown_status = readsysfs(mic->name, "shutdown_status");
+               if (!shutdown_status) {
+                       sleep(1);
+                       continue;
+               }
+               mpsslog("%s: %s %d shutdown_status %s\n",
+                       mic->name, __func__, __LINE__, shutdown_status);
+               switch (get_mic_shutdown_status(mic, shutdown_status)) {
+               case MIC_RESTART:
+                       mic->restart = 1;
+               case MIC_HALTED:
+               case MIC_POWER_OFF:
+               case MIC_CRASHED:
+                       free(shutdown_status);
+                       goto reset;
+               default:
+                       break;
+               }
+               free(shutdown_status);
+               sleep(1);
+               i--;
+       }
+reset:
+       if (!i)
+               mpsslog("%s: %s %d timing out waiting for shutdown_status %s\n",
+                       mic->name, __func__, __LINE__, shutdown_status);
+       reset(mic);
+}
+
+static int open_state_fd(struct mic_info *mic)
+{
+       char pathname[PATH_MAX];
+       int fd;
+
+       snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
+                MICSYSFSDIR, mic->name, "state");
+
+       fd = open(pathname, O_RDONLY);
+       if (fd < 0)
+               mpsslog("%s: opening file %s failed %s\n",
+                       mic->name, pathname, strerror(errno));
+       return fd;
+}
+
+static int block_till_state_change(int fd, struct mic_info *mic)
+{
+       struct pollfd ufds[1];
+       char value[PAGE_SIZE];
+       int ret;
+
+       ufds[0].fd = fd;
+       ufds[0].events = POLLERR | POLLPRI;
+       ret = poll(ufds, 1, -1);
+       if (ret < 0) {
+               mpsslog("%s: %s %d poll failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               return ret;
+       }
+
+       ret = lseek(fd, 0, SEEK_SET);
+       if (ret < 0) {
+               mpsslog("%s: %s %d Failed to seek to 0: %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               return ret;
+       }
+
+       ret = read(fd, value, sizeof(value));
+       if (ret < 0) {
+               mpsslog("%s: %s %d Failed to read sysfs entry: %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static void *
+mic_config(void *arg)
+{
+       struct mic_info *mic = (struct mic_info *)arg;
+       int fd, ret, stat = 0;
+
+       fd = open_state_fd(mic);
+       if (fd < 0) {
+               mpsslog("%s: %s %d open state fd failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               goto exit;
+       }
+
+       do {
+               ret = block_till_state_change(fd, mic);
+               if (ret < 0) {
+                       mpsslog("%s: %s %d block_till_state_change error %s\n",
+                               mic->name, __func__, __LINE__, strerror(errno));
+                       goto close_exit;
+               }
+
+               switch (get_mic_state(mic)) {
+               case MIC_SHUTTING_DOWN:
+                       mic_handle_shutdown(mic);
+                       break;
+               case MIC_READY:
+               case MIC_RESET_FAILED:
+                       ret = kill(mic->pid, SIGTERM);
+                       mpsslog("%s: %s %d kill pid %d ret %d\n",
+                               mic->name, __func__, __LINE__,
+                               mic->pid, ret);
+                       if (!ret) {
+                               ret = waitpid(mic->pid, &stat,
+                                             WIFSIGNALED(stat));
+                               mpsslog("%s: %s %d waitpid ret %d pid %d\n",
+                                       mic->name, __func__, __LINE__,
+                                       ret, mic->pid);
+                       }
+                       if (mic->boot_on_resume) {
+                               setsysfs(mic->name, "state", "boot");
+                               mic->boot_on_resume = 0;
+                       }
+                       goto close_exit;
+               default:
+                       break;
+               }
+       } while (1);
+
+close_exit:
+       close(fd);
+exit:
+       init_mic(mic);
+       pthread_exit(NULL);
+}
+
+static void
+set_cmdline(struct mic_info *mic)
+{
+       char buffer[PATH_MAX];
+       int len;
+
+       len = snprintf(buffer, PATH_MAX,
+               "clocksource=tsc highres=off nohz=off ");
+       len += snprintf(buffer + len, PATH_MAX - len,
+               "cpufreq_on;corec6_off;pc3_off;pc6_off ");
+       len += snprintf(buffer + len, PATH_MAX - len,
+               "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
+               mic->id + 1);
+
+       setsysfs(mic->name, "cmdline", buffer);
+       mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
+       snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id + 1);
+       mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
+}
+
+static void
+set_log_buf_info(struct mic_info *mic)
+{
+       int fd;
+       off_t len;
+       char system_map[] = "/lib/firmware/mic/System.map";
+       char *map, *temp, log_buf[17] = {'\0'};
+
+       fd = open(system_map, O_RDONLY);
+       if (fd < 0) {
+               mpsslog("%s: Opening System.map failed: %d\n",
+                       mic->name, errno);
+               return;
+       }
+       len = lseek(fd, 0, SEEK_END);
+       if (len < 0) {
+               mpsslog("%s: Reading System.map size failed: %d\n",
+                       mic->name, errno);
+               close(fd);
+               return;
+       }
+       map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (map == MAP_FAILED) {
+               mpsslog("%s: mmap of System.map failed: %d\n",
+                       mic->name, errno);
+               close(fd);
+               return;
+       }
+       temp = strstr(map, "__log_buf");
+       if (!temp) {
+               mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
+               munmap(map, len);
+               close(fd);
+               return;
+       }
+       strncpy(log_buf, temp - 19, 16);
+       setsysfs(mic->name, "log_buf_addr", log_buf);
+       mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
+       temp = strstr(map, "log_buf_len");
+       if (!temp) {
+               mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
+               munmap(map, len);
+               close(fd);
+               return;
+       }
+       strncpy(log_buf, temp - 19, 16);
+       setsysfs(mic->name, "log_buf_len", log_buf);
+       mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
+       munmap(map, len);
+       close(fd);
+}
+
+static void
+change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
+{
+       struct mic_info *mic;
+
+       for (mic = mic_list.next; mic != NULL; mic = mic->next)
+               mic->mic_virtblk.signaled = 1/* true */;
+}
+
+static void
+set_mic_boot_params(struct mic_info *mic)
+{
+       set_log_buf_info(mic);
+       set_cmdline(mic);
+}
+
+static void *
+init_mic(void *arg)
+{
+       struct mic_info *mic = (struct mic_info *)arg;
+       struct sigaction ignore = {
+               .sa_flags = 0,
+               .sa_handler = SIG_IGN
+       };
+       struct sigaction act = {
+               .sa_flags = SA_SIGINFO,
+               .sa_sigaction = change_virtblk_backend,
+       };
+       char buffer[PATH_MAX];
+       int err, fd;
+
+       /*
+        * Currently, one virtio block device is supported for each MIC card
+        * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
+        * The signal informs the virtio block backend about a change in the
+        * configuration file which specifies the virtio backend file name on
+        * the host. Virtio block backend then re-reads the configuration file
+        * and switches to the new block device. This signalling mechanism may
+        * not be required once multiple virtio block devices are supported by
+        * the MIC daemon.
+        */
+       sigaction(SIGUSR1, &ignore, NULL);
+retry:
+       fd = open_state_fd(mic);
+       if (fd < 0) {
+               mpsslog("%s: %s %d open state fd failed %s\n",
+                       mic->name, __func__, __LINE__, strerror(errno));
+               sleep(2);
+               goto retry;
+       }
+
+       if (mic->restart) {
+               snprintf(buffer, PATH_MAX, "boot");
+               setsysfs(mic->name, "state", buffer);
+               mpsslog("%s restarting mic %d\n",
+                       mic->name, mic->restart);
+               mic->restart = 0;
+       }
+
+       while (1) {
+               while (block_till_state_change(fd, mic)) {
+                       mpsslog("%s: %s %d block_till_state_change error %s\n",
+                               mic->name, __func__, __LINE__, strerror(errno));
+                       sleep(2);
+                       continue;
+               }
+
+               if (get_mic_state(mic) == MIC_BOOTING)
+                       break;
+       }
+
+       mic->pid = fork();
+       switch (mic->pid) {
+       case 0:
+               add_virtio_device(mic, &virtcons_dev_page.dd);
+               add_virtio_device(mic, &virtnet_dev_page.dd);
+               err = pthread_create(&mic->mic_console.console_thread, NULL,
+                       virtio_console, mic);
+               if (err)
+                       mpsslog("%s virtcons pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               err = pthread_create(&mic->mic_net.net_thread, NULL,
+                       virtio_net, mic);
+               if (err)
+                       mpsslog("%s virtnet pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
+                       virtio_block, mic);
+               if (err)
+                       mpsslog("%s virtblk pthread_create failed %s\n",
+                               mic->name, strerror(err));
+               sigemptyset(&act.sa_mask);
+               err = sigaction(SIGUSR1, &act, NULL);
+               if (err)
+                       mpsslog("%s sigaction SIGUSR1 failed %s\n",
+                               mic->name, strerror(errno));
+               while (1)
+                       sleep(60);
+       case -1:
+               mpsslog("fork failed MIC name %s id %d errno %d\n",
+                       mic->name, mic->id, errno);
+               break;
+       default:
+               err = pthread_create(&mic->config_thread, NULL,
+                                    mic_config, mic);
+               if (err)
+                       mpsslog("%s mic_config pthread_create failed %s\n",
+                               mic->name, strerror(err));
+       }
+
+       return NULL;
+}
+
+static void
+start_daemon(void)
+{
+       struct mic_info *mic;
+       int err;
+
+       for (mic = mic_list.next; mic; mic = mic->next) {
+               set_mic_boot_params(mic);
+               err = pthread_create(&mic->init_thread, NULL, init_mic, mic);
+               if (err)
+                       mpsslog("%s init_mic pthread_create failed %s\n",
+                               mic->name, strerror(err));
+       }
+
+       while (1)
+               sleep(60);
+}
+
+static int
+init_mic_list(void)
+{
+       struct mic_info *mic = &mic_list;
+       struct dirent *file;
+       DIR *dp;
+       int cnt = 0;
+
+       dp = opendir(MICSYSFSDIR);
+       if (!dp)
+               return 0;
+
+       while ((file = readdir(dp)) != NULL) {
+               if (!strncmp(file->d_name, "mic", 3)) {
+                       mic->next = calloc(1, sizeof(struct mic_info));
+                       if (mic->next) {
+                               mic = mic->next;
+                               mic->id = atoi(&file->d_name[3]);
+                               mic->name = malloc(strlen(file->d_name) + 16);
+                               if (mic->name)
+                                       strcpy(mic->name, file->d_name);
+                               mpsslog("MIC name %s id %d\n", mic->name,
+                                       mic->id);
+                               cnt++;
+                       }
+               }
+       }
+
+       closedir(dp);
+       return cnt;
+}
+
+void
+mpsslog(char *format, ...)
+{
+       va_list args;
+       char buffer[4096];
+       char ts[52], *ts1;
+       time_t t;
+
+       if (logfp == NULL)
+               return;
+
+       va_start(args, format);
+       vsprintf(buffer, format, args);
+       va_end(args);
+
+       time(&t);
+       ts1 = ctime_r(&t, ts);
+       ts1[strlen(ts1) - 1] = '\0';
+       fprintf(logfp, "%s: %s", ts1, buffer);
+
+       fflush(logfp);
+}
+
+int
+main(int argc, char *argv[])
+{
+       int cnt;
+       pid_t pid;
+
+       myname = argv[0];
+
+       logfp = fopen(LOGFILE_NAME, "a+");
+       if (!logfp) {
+               fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
+               exit(1);
+       }
+       pid = fork();
+       switch (pid) {
+       case 0:
+               break;
+       case -1:
+               exit(2);
+       default:
+               exit(0);
+       }
+
+       mpsslog("MIC Daemon start\n");
+
+       cnt = init_mic_list();
+       if (cnt == 0) {
+               mpsslog("MIC module not loaded\n");
+               exit(3);
+       }
+       mpsslog("MIC found %d devices\n", cnt);
+
+       start_daemon();
+
+       exit(0);
+}
diff --git a/samples/mic/mpssd/mpssd.h b/samples/mic/mpssd/mpssd.h
new file mode 100644 (file)
index 0000000..8bd6494
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+#ifndef _MPSSD_H_
+#define _MPSSD_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <signal.h>
+#include <limits.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_tun.h>
+#include <linux/virtio_ids.h>
+
+#define MICSYSFSDIR "/sys/class/mic"
+#define LOGFILE_NAME "/var/log/mpssd"
+#define PAGE_SIZE 4096
+
+struct mic_console_info {
+       pthread_t       console_thread;
+       int             virtio_console_fd;
+       void            *console_dp;
+};
+
+struct mic_net_info {
+       pthread_t       net_thread;
+       int             virtio_net_fd;
+       int             tap_fd;
+       void            *net_dp;
+};
+
+struct mic_virtblk_info {
+       pthread_t       block_thread;
+       int             virtio_block_fd;
+       void            *block_dp;
+       volatile sig_atomic_t   signaled;
+       char            *backend_file;
+       int             backend;
+       void            *backend_addr;
+       long            backend_size;
+};
+
+struct mic_info {
+       int             id;
+       char            *name;
+       pthread_t       config_thread;
+       pthread_t       init_thread;
+       pid_t           pid;
+       struct mic_console_info mic_console;
+       struct mic_net_info     mic_net;
+       struct mic_virtblk_info mic_virtblk;
+       int             restart;
+       int             boot_on_resume;
+       struct mic_info *next;
+};
+
+__attribute__((format(printf, 1, 2)))
+void mpsslog(char *format, ...);
+char *readsysfs(char *dir, char *entry);
+int setsysfs(char *dir, char *entry, char *value);
+#endif
diff --git a/samples/mic/mpssd/sysfs.c b/samples/mic/mpssd/sysfs.c
new file mode 100644 (file)
index 0000000..8dd3269
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC User Space Tools.
+ */
+
+#include "mpssd.h"
+
+#define PAGE_SIZE 4096
+
+char *
+readsysfs(char *dir, char *entry)
+{
+       char filename[PATH_MAX];
+       char value[PAGE_SIZE];
+       char *string = NULL;
+       int fd;
+       int len;
+
+       if (dir == NULL)
+               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+       else
+               snprintf(filename, PATH_MAX,
+                        "%s/%s/%s", MICSYSFSDIR, dir, entry);
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               mpsslog("Failed to open sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               return NULL;
+       }
+
+       len = read(fd, value, sizeof(value));
+       if (len < 0) {
+               mpsslog("Failed to read sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               goto readsys_ret;
+       }
+       if (len == 0)
+               goto readsys_ret;
+
+       value[len - 1] = '\0';
+
+       string = malloc(strlen(value) + 1);
+       if (string)
+               strcpy(string, value);
+
+readsys_ret:
+       close(fd);
+       return string;
+}
+
+int
+setsysfs(char *dir, char *entry, char *value)
+{
+       char filename[PATH_MAX];
+       char *oldvalue;
+       int fd, ret = 0;
+
+       if (dir == NULL)
+               snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+       else
+               snprintf(filename, PATH_MAX, "%s/%s/%s",
+                        MICSYSFSDIR, dir, entry);
+
+       oldvalue = readsysfs(dir, entry);
+
+       fd = open(filename, O_RDWR);
+       if (fd < 0) {
+               ret = errno;
+               mpsslog("Failed to open sysfs entry '%s': %s\n",
+                       filename, strerror(errno));
+               goto done;
+       }
+
+       if (!oldvalue || strcmp(value, oldvalue)) {
+               if (write(fd, value, strlen(value)) < 0) {
+                       ret = errno;
+                       mpsslog("Failed to write new sysfs entry '%s': %s\n",
+                               filename, strerror(errno));
+               }
+       }
+       close(fd);
+done:
+       if (oldvalue)
+               free(oldvalue);
+       return ret;
+}
diff --git a/samples/timers/.gitignore b/samples/timers/.gitignore
new file mode 100644 (file)
index 0000000..c5c45d7
--- /dev/null
@@ -0,0 +1 @@
+hpet_example
diff --git a/samples/timers/Makefile b/samples/timers/Makefile
new file mode 100644 (file)
index 0000000..a5c3c4a
--- /dev/null
@@ -0,0 +1,15 @@
+ifndef CROSS_COMPILE
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+CC := $(CROSS_COMPILE)gcc
+PROGS := hpet_example
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
+
+endif
+endif
diff --git a/samples/timers/hpet_example.c b/samples/timers/hpet_example.c
new file mode 100644 (file)
index 0000000..3ab4993
--- /dev/null
@@ -0,0 +1,294 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <memory.h>
+#include <malloc.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <linux/hpet.h>
+
+
+extern void hpet_open_close(int, const char **);
+extern void hpet_info(int, const char **);
+extern void hpet_poll(int, const char **);
+extern void hpet_fasync(int, const char **);
+extern void hpet_read(int, const char **);
+
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+
+struct hpet_command {
+       char            *command;
+       void            (*func)(int argc, const char ** argv);
+} hpet_command[] = {
+       {
+               "open-close",
+               hpet_open_close
+       },
+       {
+               "info",
+               hpet_info
+       },
+       {
+               "poll",
+               hpet_poll
+       },
+       {
+               "fasync",
+               hpet_fasync
+       },
+};
+
+int
+main(int argc, const char ** argv)
+{
+       unsigned int    i;
+
+       argc--;
+       argv++;
+
+       if (!argc) {
+               fprintf(stderr, "-hpet: requires command\n");
+               return -1;
+       }
+
+
+       for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
+               if (!strcmp(argv[0], hpet_command[i].command)) {
+                       argc--;
+                       argv++;
+                       fprintf(stderr, "-hpet: executing %s\n",
+                               hpet_command[i].command);
+                       hpet_command[i].func(argc, argv);
+                       return 0;
+               }
+
+       fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
+
+       return -1;
+}
+
+void
+hpet_open_close(int argc, const char **argv)
+{
+       int     fd;
+
+       if (argc != 1) {
+               fprintf(stderr, "hpet_open_close: device-name\n");
+               return;
+       }
+
+       fd = open(argv[0], O_RDONLY);
+       if (fd < 0)
+               fprintf(stderr, "hpet_open_close: open failed\n");
+       else
+               close(fd);
+
+       return;
+}
+
+void
+hpet_info(int argc, const char **argv)
+{
+       struct hpet_info        info;
+       int                     fd;
+
+       if (argc != 1) {
+               fprintf(stderr, "hpet_info: device-name\n");
+               return;
+       }
+
+       fd = open(argv[0], O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
+               return;
+       }
+
+       if (ioctl(fd, HPET_INFO, &info) < 0) {
+               fprintf(stderr, "hpet_info: failed to get info\n");
+               goto out;
+       }
+
+       fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
+               info.hi_ireqfreq, info.hi_flags);
+       fprintf(stderr, "hi_hpet %d hi_timer %d\n",
+               info.hi_hpet, info.hi_timer);
+
+out:
+       close(fd);
+       return;
+}
+
+void
+hpet_poll(int argc, const char **argv)
+{
+       unsigned long           freq;
+       int                     iterations, i, fd;
+       struct pollfd           pfd;
+       struct hpet_info        info;
+       struct timeval          stv, etv;
+       struct timezone         tz;
+       long                    usec;
+
+       if (argc != 3) {
+               fprintf(stderr, "hpet_poll: device-name freq iterations\n");
+               return;
+       }
+
+       freq = atoi(argv[1]);
+       iterations = atoi(argv[2]);
+
+       fd = open(argv[0], O_RDONLY);
+
+       if (fd < 0) {
+               fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
+               return;
+       }
+
+       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+               fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_INFO, &info) < 0) {
+               fprintf(stderr, "hpet_poll: failed to get info\n");
+               goto out;
+       }
+
+       fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
+
+       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+               fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+               fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
+               goto out;
+       }
+
+       pfd.fd = fd;
+       pfd.events = POLLIN;
+
+       for (i = 0; i < iterations; i++) {
+               pfd.revents = 0;
+               gettimeofday(&stv, &tz);
+               if (poll(&pfd, 1, -1) < 0)
+                       fprintf(stderr, "hpet_poll: poll failed\n");
+               else {
+                       long    data;
+
+                       gettimeofday(&etv, &tz);
+                       usec = stv.tv_sec * 1000000 + stv.tv_usec;
+                       usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
+
+                       fprintf(stderr,
+                               "hpet_poll: expired time = 0x%lx\n", usec);
+
+                       fprintf(stderr, "hpet_poll: revents = 0x%x\n",
+                               pfd.revents);
+
+                       if (read(fd, &data, sizeof(data)) != sizeof(data)) {
+                               fprintf(stderr, "hpet_poll: read failed\n");
+                       }
+                       else
+                               fprintf(stderr, "hpet_poll: data 0x%lx\n",
+                                       data);
+               }
+       }
+
+out:
+       close(fd);
+       return;
+}
+
+static int hpet_sigio_count;
+
+static void
+hpet_sigio(int val)
+{
+       fprintf(stderr, "hpet_sigio: called\n");
+       hpet_sigio_count++;
+}
+
+void
+hpet_fasync(int argc, const char **argv)
+{
+       unsigned long           freq;
+       int                     iterations, i, fd, value;
+       sig_t                   oldsig;
+       struct hpet_info        info;
+
+       hpet_sigio_count = 0;
+       fd = -1;
+
+       if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
+               fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
+               return;
+       }
+
+       if (argc != 3) {
+               fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
+               goto out;
+       }
+
+       fd = open(argv[0], O_RDONLY);
+
+       if (fd < 0) {
+               fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
+               return;
+       }
+
+
+       if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
+               ((value = fcntl(fd, F_GETFL)) == 1) ||
+               (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
+               fprintf(stderr, "hpet_fasync: fcntl failed\n");
+               goto out;
+       }
+
+       freq = atoi(argv[1]);
+       iterations = atoi(argv[2]);
+
+       if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+               fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_INFO, &info) < 0) {
+               fprintf(stderr, "hpet_fasync: failed to get info\n");
+               goto out;
+       }
+
+       fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
+
+       if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+               fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
+               goto out;
+       }
+
+       if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+               fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
+               goto out;
+       }
+
+       for (i = 0; i < iterations; i++) {
+               (void) pause();
+               fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
+       }
+
+out:
+       signal(SIGIO, oldsig);
+
+       if (fd >= 0)
+               close(fd);
+
+       return;
+}
diff --git a/samples/watchdog/.gitignore b/samples/watchdog/.gitignore
new file mode 100644 (file)
index 0000000..ff0ebb5
--- /dev/null
@@ -0,0 +1 @@
+watchdog-simple
diff --git a/samples/watchdog/Makefile b/samples/watchdog/Makefile
new file mode 100644 (file)
index 0000000..9b53d89
--- /dev/null
@@ -0,0 +1,8 @@
+CC := $(CROSS_COMPILE)gcc
+PROGS := watchdog-simple
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
+
diff --git a/samples/watchdog/watchdog-simple.c b/samples/watchdog/watchdog-simple.c
new file mode 100644 (file)
index 0000000..ba45803
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main(void)
+{
+       int fd = open("/dev/watchdog", O_WRONLY);
+       int ret = 0;
+       if (fd == -1) {
+               perror("watchdog");
+               exit(EXIT_FAILURE);
+       }
+       while (1) {
+               ret = write(fd, "\0", 1);
+               if (ret != 1) {
+                       ret = -1;
+                       break;
+               }
+               sleep(10);
+       }
+       close(fd);
+       return ret;
+}
diff --git a/tools/accounting/.gitignore b/tools/accounting/.gitignore
new file mode 100644 (file)
index 0000000..8648520
--- /dev/null
@@ -0,0 +1 @@
+getdelays
diff --git a/tools/accounting/Makefile b/tools/accounting/Makefile
new file mode 100644 (file)
index 0000000..647c94a
--- /dev/null
@@ -0,0 +1,9 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS := -I../../usr/include
+
+PROGS := getdelays
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
diff --git a/tools/accounting/getdelays.c b/tools/accounting/getdelays.c
new file mode 100644 (file)
index 0000000..b5ca536
--- /dev/null
@@ -0,0 +1,550 @@
+/* getdelays.c
+ *
+ * Utility to get per-pid and per-tgid delay accounting statistics
+ * Also illustrates usage of the taskstats interface
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2005
+ * Copyright (C) Balbir Singh, IBM Corp. 2006
+ * Copyright (c) Jay Lan, SGI. 2006
+ *
+ * Compile with
+ *     gcc -I/usr/src/linux/include getdelays.c -o getdelays
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <poll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#include <linux/genetlink.h>
+#include <linux/taskstats.h>
+#include <linux/cgroupstats.h>
+
+/*
+ * Generic macros for dealing with netlink sockets. Might be duplicated
+ * elsewhere. It is recommended that commercial grade applications use
+ * libnl or libnetlink and use the interfaces provided by the library
+ */
+#define GENLMSG_DATA(glh)      ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
+#define GENLMSG_PAYLOAD(glh)   (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
+#define NLA_DATA(na)           ((void *)((char*)(na) + NLA_HDRLEN))
+#define NLA_PAYLOAD(len)       (len - NLA_HDRLEN)
+
+#define err(code, fmt, arg...)                 \
+       do {                                    \
+               fprintf(stderr, fmt, ##arg);    \
+               exit(code);                     \
+       } while (0)
+
+int done;
+int rcvbufsz;
+char name[100];
+int dbg;
+int print_delays;
+int print_io_accounting;
+int print_task_context_switch_counts;
+
+#define PRINTF(fmt, arg...) {                  \
+           if (dbg) {                          \
+               printf(fmt, ##arg);             \
+           }                                   \
+       }
+
+/* Maximum size of response requested or message sent */
+#define MAX_MSG_SIZE   1024
+/* Maximum number of cpus expected to be specified in a cpumask */
+#define MAX_CPUS       32
+
+struct msgtemplate {
+       struct nlmsghdr n;
+       struct genlmsghdr g;
+       char buf[MAX_MSG_SIZE];
+};
+
+char cpumask[100+6*MAX_CPUS];
+
+static void usage(void)
+{
+       fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] "
+                       "[-m cpumask] [-t tgid] [-p pid]\n");
+       fprintf(stderr, "  -d: print delayacct stats\n");
+       fprintf(stderr, "  -i: print IO accounting (works only with -p)\n");
+       fprintf(stderr, "  -l: listen forever\n");
+       fprintf(stderr, "  -v: debug on\n");
+       fprintf(stderr, "  -C: container path\n");
+}
+
+/*
+ * Create a raw netlink socket and bind
+ */
+static int create_nl_socket(int protocol)
+{
+       int fd;
+       struct sockaddr_nl local;
+
+       fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+       if (fd < 0)
+               return -1;
+
+       if (rcvbufsz)
+               if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+                               &rcvbufsz, sizeof(rcvbufsz)) < 0) {
+                       fprintf(stderr, "Unable to set socket rcv buf size to %d\n",
+                               rcvbufsz);
+                       goto error;
+               }
+
+       memset(&local, 0, sizeof(local));
+       local.nl_family = AF_NETLINK;
+
+       if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
+               goto error;
+
+       return fd;
+error:
+       close(fd);
+       return -1;
+}
+
+
+static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+            __u8 genl_cmd, __u16 nla_type,
+            void *nla_data, int nla_len)
+{
+       struct nlattr *na;
+       struct sockaddr_nl nladdr;
+       int r, buflen;
+       char *buf;
+
+       struct msgtemplate msg;
+
+       msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+       msg.n.nlmsg_type = nlmsg_type;
+       msg.n.nlmsg_flags = NLM_F_REQUEST;
+       msg.n.nlmsg_seq = 0;
+       msg.n.nlmsg_pid = nlmsg_pid;
+       msg.g.cmd = genl_cmd;
+       msg.g.version = 0x1;
+       na = (struct nlattr *) GENLMSG_DATA(&msg);
+       na->nla_type = nla_type;
+       na->nla_len = nla_len + 1 + NLA_HDRLEN;
+       memcpy(NLA_DATA(na), nla_data, nla_len);
+       msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
+
+       buf = (char *) &msg;
+       buflen = msg.n.nlmsg_len ;
+       memset(&nladdr, 0, sizeof(nladdr));
+       nladdr.nl_family = AF_NETLINK;
+       while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
+                          sizeof(nladdr))) < buflen) {
+               if (r > 0) {
+                       buf += r;
+                       buflen -= r;
+               } else if (errno != EAGAIN)
+                       return -1;
+       }
+       return 0;
+}
+
+
+/*
+ * Probe the controller in genetlink to find the family id
+ * for the TASKSTATS family
+ */
+static int get_family_id(int sd)
+{
+       struct {
+               struct nlmsghdr n;
+               struct genlmsghdr g;
+               char buf[256];
+       } ans;
+
+       int id = 0, rc;
+       struct nlattr *na;
+       int rep_len;
+
+       strcpy(name, TASKSTATS_GENL_NAME);
+       rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
+                       CTRL_ATTR_FAMILY_NAME, (void *)name,
+                       strlen(TASKSTATS_GENL_NAME)+1);
+       if (rc < 0)
+               return 0;       /* sendto() failure? */
+
+       rep_len = recv(sd, &ans, sizeof(ans), 0);
+       if (ans.n.nlmsg_type == NLMSG_ERROR ||
+           (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
+               return 0;
+
+       na = (struct nlattr *) GENLMSG_DATA(&ans);
+       na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
+       if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
+               id = *(__u16 *) NLA_DATA(na);
+       }
+       return id;
+}
+
+#define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
+
+static void print_delayacct(struct taskstats *t)
+{
+       printf("\n\nCPU   %15s%15s%15s%15s%15s\n"
+              "      %15llu%15llu%15llu%15llu%15.3fms\n"
+              "IO    %15s%15s%15s\n"
+              "      %15llu%15llu%15llums\n"
+              "SWAP  %15s%15s%15s\n"
+              "      %15llu%15llu%15llums\n"
+              "RECLAIM  %12s%15s%15s\n"
+              "      %15llu%15llu%15llums\n",
+              "count", "real total", "virtual total",
+              "delay total", "delay average",
+              (unsigned long long)t->cpu_count,
+              (unsigned long long)t->cpu_run_real_total,
+              (unsigned long long)t->cpu_run_virtual_total,
+              (unsigned long long)t->cpu_delay_total,
+              average_ms((double)t->cpu_delay_total, t->cpu_count),
+              "count", "delay total", "delay average",
+              (unsigned long long)t->blkio_count,
+              (unsigned long long)t->blkio_delay_total,
+              average_ms(t->blkio_delay_total, t->blkio_count),
+              "count", "delay total", "delay average",
+              (unsigned long long)t->swapin_count,
+              (unsigned long long)t->swapin_delay_total,
+              average_ms(t->swapin_delay_total, t->swapin_count),
+              "count", "delay total", "delay average",
+              (unsigned long long)t->freepages_count,
+              (unsigned long long)t->freepages_delay_total,
+              average_ms(t->freepages_delay_total, t->freepages_count));
+}
+
+static void task_context_switch_counts(struct taskstats *t)
+{
+       printf("\n\nTask   %15s%15s\n"
+              "       %15llu%15llu\n",
+              "voluntary", "nonvoluntary",
+              (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw);
+}
+
+static void print_cgroupstats(struct cgroupstats *c)
+{
+       printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, "
+               "uninterruptible %llu\n", (unsigned long long)c->nr_sleeping,
+               (unsigned long long)c->nr_io_wait,
+               (unsigned long long)c->nr_running,
+               (unsigned long long)c->nr_stopped,
+               (unsigned long long)c->nr_uninterruptible);
+}
+
+
+static void print_ioacct(struct taskstats *t)
+{
+       printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
+               t->ac_comm,
+               (unsigned long long)t->read_bytes,
+               (unsigned long long)t->write_bytes,
+               (unsigned long long)t->cancelled_write_bytes);
+}
+
+int main(int argc, char *argv[])
+{
+       int c, rc, rep_len, aggr_len, len2;
+       int cmd_type = TASKSTATS_CMD_ATTR_UNSPEC;
+       __u16 id;
+       __u32 mypid;
+
+       struct nlattr *na;
+       int nl_sd = -1;
+       int len = 0;
+       pid_t tid = 0;
+       pid_t rtid = 0;
+
+       int fd = 0;
+       int count = 0;
+       int write_file = 0;
+       int maskset = 0;
+       char *logfile = NULL;
+       int loop = 0;
+       int containerset = 0;
+       char *containerpath = NULL;
+       int cfd = 0;
+       int forking = 0;
+       sigset_t sigset;
+
+       struct msgtemplate msg;
+
+       while (!forking) {
+               c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:");
+               if (c < 0)
+                       break;
+
+               switch (c) {
+               case 'd':
+                       printf("print delayacct stats ON\n");
+                       print_delays = 1;
+                       break;
+               case 'i':
+                       printf("printing IO accounting\n");
+                       print_io_accounting = 1;
+                       break;
+               case 'q':
+                       printf("printing task/process context switch rates\n");
+                       print_task_context_switch_counts = 1;
+                       break;
+               case 'C':
+                       containerset = 1;
+                       containerpath = optarg;
+                       break;
+               case 'w':
+                       logfile = strdup(optarg);
+                       printf("write to file %s\n", logfile);
+                       write_file = 1;
+                       break;
+               case 'r':
+                       rcvbufsz = atoi(optarg);
+                       printf("receive buf size %d\n", rcvbufsz);
+                       if (rcvbufsz < 0)
+                               err(1, "Invalid rcv buf size\n");
+                       break;
+               case 'm':
+                       strncpy(cpumask, optarg, sizeof(cpumask));
+                       cpumask[sizeof(cpumask) - 1] = '\0';
+                       maskset = 1;
+                       printf("cpumask %s maskset %d\n", cpumask, maskset);
+                       break;
+               case 't':
+                       tid = atoi(optarg);
+                       if (!tid)
+                               err(1, "Invalid tgid\n");
+                       cmd_type = TASKSTATS_CMD_ATTR_TGID;
+                       break;
+               case 'p':
+                       tid = atoi(optarg);
+                       if (!tid)
+                               err(1, "Invalid pid\n");
+                       cmd_type = TASKSTATS_CMD_ATTR_PID;
+                       break;
+               case 'c':
+
+                       /* Block SIGCHLD for sigwait() later */
+                       if (sigemptyset(&sigset) == -1)
+                               err(1, "Failed to empty sigset");
+                       if (sigaddset(&sigset, SIGCHLD))
+                               err(1, "Failed to set sigchld in sigset");
+                       sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+                       /* fork/exec a child */
+                       tid = fork();
+                       if (tid < 0)
+                               err(1, "Fork failed\n");
+                       if (tid == 0)
+                               if (execvp(argv[optind - 1],
+                                   &argv[optind - 1]) < 0)
+                                       exit(-1);
+
+                       /* Set the command type and avoid further processing */
+                       cmd_type = TASKSTATS_CMD_ATTR_PID;
+                       forking = 1;
+                       break;
+               case 'v':
+                       printf("debug on\n");
+                       dbg = 1;
+                       break;
+               case 'l':
+                       printf("listen forever\n");
+                       loop = 1;
+                       break;
+               default:
+                       usage();
+                       exit(-1);
+               }
+       }
+
+       if (write_file) {
+               fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
+                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+               if (fd == -1) {
+                       perror("Cannot open output file\n");
+                       exit(1);
+               }
+       }
+
+       nl_sd = create_nl_socket(NETLINK_GENERIC);
+       if (nl_sd < 0)
+               err(1, "error creating Netlink socket\n");
+
+
+       mypid = getpid();
+       id = get_family_id(nl_sd);
+       if (!id) {
+               fprintf(stderr, "Error getting family id, errno %d\n", errno);
+               goto err;
+       }
+       PRINTF("family id %d\n", id);
+
+       if (maskset) {
+               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+                             TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+                             &cpumask, strlen(cpumask) + 1);
+               PRINTF("Sent register cpumask, retval %d\n", rc);
+               if (rc < 0) {
+                       fprintf(stderr, "error sending register cpumask\n");
+                       goto err;
+               }
+       }
+
+       if (tid && containerset) {
+               fprintf(stderr, "Select either -t or -C, not both\n");
+               goto err;
+       }
+
+       /*
+        * If we forked a child, wait for it to exit. Cannot use waitpid()
+        * as all the delicious data would be reaped as part of the wait
+        */
+       if (tid && forking) {
+               int sig_received;
+               sigwait(&sigset, &sig_received);
+       }
+
+       if (tid) {
+               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+                             cmd_type, &tid, sizeof(__u32));
+               PRINTF("Sent pid/tgid, retval %d\n", rc);
+               if (rc < 0) {
+                       fprintf(stderr, "error sending tid/tgid cmd\n");
+                       goto done;
+               }
+       }
+
+       if (containerset) {
+               cfd = open(containerpath, O_RDONLY);
+               if (cfd < 0) {
+                       perror("error opening container file");
+                       goto err;
+               }
+               rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET,
+                             CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32));
+               if (rc < 0) {
+                       perror("error sending cgroupstats command");
+                       goto err;
+               }
+       }
+       if (!maskset && !tid && !containerset) {
+               usage();
+               goto err;
+       }
+
+       do {
+               rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
+               PRINTF("received %d bytes\n", rep_len);
+
+               if (rep_len < 0) {
+                       fprintf(stderr, "nonfatal reply error: errno %d\n",
+                               errno);
+                       continue;
+               }
+               if (msg.n.nlmsg_type == NLMSG_ERROR ||
+                   !NLMSG_OK((&msg.n), rep_len)) {
+                       struct nlmsgerr *err = NLMSG_DATA(&msg);
+                       fprintf(stderr, "fatal reply error,  errno %d\n",
+                               err->error);
+                       goto done;
+               }
+
+               PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d\n",
+                      sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
+
+
+               rep_len = GENLMSG_PAYLOAD(&msg.n);
+
+               na = (struct nlattr *) GENLMSG_DATA(&msg);
+               len = 0;
+               while (len < rep_len) {
+                       len += NLA_ALIGN(na->nla_len);
+                       switch (na->nla_type) {
+                       case TASKSTATS_TYPE_AGGR_TGID:
+                               /* Fall through */
+                       case TASKSTATS_TYPE_AGGR_PID:
+                               aggr_len = NLA_PAYLOAD(na->nla_len);
+                               len2 = 0;
+                               /* For nested attributes, na follows */
+                               na = (struct nlattr *) NLA_DATA(na);
+                               done = 0;
+                               while (len2 < aggr_len) {
+                                       switch (na->nla_type) {
+                                       case TASKSTATS_TYPE_PID:
+                                               rtid = *(int *) NLA_DATA(na);
+                                               if (print_delays)
+                                                       printf("PID\t%d\n", rtid);
+                                               break;
+                                       case TASKSTATS_TYPE_TGID:
+                                               rtid = *(int *) NLA_DATA(na);
+                                               if (print_delays)
+                                                       printf("TGID\t%d\n", rtid);
+                                               break;
+                                       case TASKSTATS_TYPE_STATS:
+                                               count++;
+                                               if (print_delays)
+                                                       print_delayacct((struct taskstats *) NLA_DATA(na));
+                                               if (print_io_accounting)
+                                                       print_ioacct((struct taskstats *) NLA_DATA(na));
+                                               if (print_task_context_switch_counts)
+                                                       task_context_switch_counts((struct taskstats *) NLA_DATA(na));
+                                               if (fd) {
+                                                       if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
+                                                               err(1,"write error\n");
+                                                       }
+                                               }
+                                               if (!loop)
+                                                       goto done;
+                                               break;
+                                       case TASKSTATS_TYPE_NULL:
+                                               break;
+                                       default:
+                                               fprintf(stderr, "Unknown nested"
+                                                       " nla_type %d\n",
+                                                       na->nla_type);
+                                               break;
+                                       }
+                                       len2 += NLA_ALIGN(na->nla_len);
+                                       na = (struct nlattr *)((char *)na +
+                                                              NLA_ALIGN(na->nla_len));
+                               }
+                               break;
+
+                       case CGROUPSTATS_TYPE_CGROUP_STATS:
+                               print_cgroupstats(NLA_DATA(na));
+                               break;
+                       default:
+                               fprintf(stderr, "Unknown nla_type %d\n",
+                                       na->nla_type);
+                       case TASKSTATS_TYPE_NULL:
+                               break;
+                       }
+                       na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
+               }
+       } while (loop);
+done:
+       if (maskset) {
+               rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+                             TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+                             &cpumask, strlen(cpumask) + 1);
+               printf("Sent deregister mask, retval %d\n", rc);
+               if (rc < 0)
+                       err(rc, "error sending deregister cpumask\n");
+       }
+err:
+       close(nl_sd);
+       if (fd)
+               close(fd);
+       if (cfd)
+               close(cfd);
+       return 0;
+}
diff --git a/tools/laptop/dslm/.gitignore b/tools/laptop/dslm/.gitignore
new file mode 100644 (file)
index 0000000..9fc984e
--- /dev/null
@@ -0,0 +1 @@
+dslm
diff --git a/tools/laptop/dslm/Makefile b/tools/laptop/dslm/Makefile
new file mode 100644 (file)
index 0000000..ff613b3
--- /dev/null
@@ -0,0 +1,9 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS := -I../../usr/include
+
+PROGS := dslm
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
diff --git a/tools/laptop/dslm/dslm.c b/tools/laptop/dslm/dslm.c
new file mode 100644 (file)
index 0000000..d5dd2d4
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * dslm.c
+ * Simple Disk Sleep Monitor
+ *  by Bartek Kania
+ * Licensed under the GPL
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/hdreg.h>
+
+#ifdef DEBUG
+#define D(x) x
+#else
+#define D(x)
+#endif
+
+int endit = 0;
+
+/* Check if the disk is in powersave-mode
+ * Most of the code is stolen from hdparm.
+ * 1 = active, 0 = standby/sleep, -1 = unknown */
+static int check_powermode(int fd)
+{
+    unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
+    int state;
+
+    if (ioctl(fd, HDIO_DRIVE_CMD, &args)
+       && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
+       && ioctl(fd, HDIO_DRIVE_CMD, &args)) {
+       if (errno != EIO || args[0] != 0 || args[1] != 0) {
+           state = -1; /* "unknown"; */
+       } else
+           state = 0; /* "sleeping"; */
+    } else {
+       state = (args[2] == 255) ? 1 : 0;
+    }
+    D(printf(" drive state is:  %d\n", state));
+
+    return state;
+}
+
+static char *state_name(int i)
+{
+    if (i == -1) return "unknown";
+    if (i == 0) return "sleeping";
+    if (i == 1) return "active";
+
+    return "internal error";
+}
+
+static char *myctime(time_t time)
+{
+    char *ts = ctime(&time);
+    ts[strlen(ts) - 1] = 0;
+
+    return ts;
+}
+
+static void measure(int fd)
+{
+    time_t start_time;
+    int last_state;
+    time_t last_time;
+    int curr_state;
+    time_t curr_time = 0;
+    time_t time_diff;
+    time_t active_time = 0;
+    time_t sleep_time = 0;
+    time_t unknown_time = 0;
+    time_t total_time = 0;
+    int changes = 0;
+    float tmp;
+
+    printf("Starting measurements\n");
+
+    last_state = check_powermode(fd);
+    start_time = last_time = time(0);
+    printf("  System is in state %s\n\n", state_name(last_state));
+
+    while(!endit) {
+       sleep(1);
+       curr_state = check_powermode(fd);
+
+       if (curr_state != last_state || endit) {
+           changes++;
+           curr_time = time(0);
+           time_diff = curr_time - last_time;
+
+           if (last_state == 1) active_time += time_diff;
+           else if (last_state == 0) sleep_time += time_diff;
+           else unknown_time += time_diff;
+
+           last_state = curr_state;
+           last_time = curr_time;
+
+           printf("%s: State-change to %s\n", myctime(curr_time),
+                  state_name(curr_state));
+       }
+    }
+    changes--; /* Compensate for SIGINT */
+
+    total_time = time(0) - start_time;
+    printf("\nTotal running time:  %lus\n", curr_time - start_time);
+    printf(" State changed %d times\n", changes);
+
+    tmp = (float)sleep_time / (float)total_time * 100;
+    printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
+    tmp = (float)active_time / (float)total_time * 100;
+    printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
+    tmp = (float)unknown_time / (float)total_time * 100;
+    printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
+}
+
+static void ender(int s)
+{
+    endit = 1;
+}
+
+static void usage(void)
+{
+    puts("usage: dslm [-w <time>] <disk>");
+    exit(0);
+}
+
+int main(int argc, char **argv)
+{
+    int fd;
+    char *disk = 0;
+    int settle_time = 60;
+
+    /* Parse the simple command-line */
+    if (argc == 2)
+       disk = argv[1];
+    else if (argc == 4) {
+       settle_time = atoi(argv[2]);
+       disk = argv[3];
+    } else
+       usage();
+
+    if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
+       printf("Can't open %s, because: %s\n", disk, strerror(errno));
+       exit(-1);
+    }
+
+    if (settle_time) {
+       printf("Waiting %d seconds for the system to settle down to "
+              "'normal'\n", settle_time);
+       sleep(settle_time);
+    } else
+       puts("Not waiting for system to settle down");
+
+    signal(SIGINT, ender);
+
+    measure(fd);
+
+    close(fd);
+
+    return 0;
+}
diff --git a/tools/pcmcia/.gitignore b/tools/pcmcia/.gitignore
new file mode 100644 (file)
index 0000000..53d0813
--- /dev/null
@@ -0,0 +1 @@
+crc32hash
diff --git a/tools/pcmcia/Makefile b/tools/pcmcia/Makefile
new file mode 100644 (file)
index 0000000..81a7498
--- /dev/null
@@ -0,0 +1,9 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS := -I../../usr/include
+
+PROGS := crc32hash
+
+all: $(PROGS)
+
+clean:
+       rm -fr $(PROGS)
diff --git a/tools/pcmcia/crc32hash.c b/tools/pcmcia/crc32hash.c
new file mode 100644 (file)
index 0000000..44f8bee
--- /dev/null
@@ -0,0 +1,32 @@
+/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */
+/* Usage example:
+$ ./crc32hash "Dual Speed"
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+static unsigned int crc32(unsigned char const *p, unsigned int len)
+{
+       int i;
+       unsigned int crc = 0;
+       while (len--) {
+               crc ^= *p++;
+               for (i = 0; i < 8; i++)
+                       crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+       }
+       return crc;
+}
+
+int main(int argc, char **argv) {
+       unsigned int result;
+       if (argc != 2) {
+               printf("no string passed as argument\n");
+               return -1;
+       }
+       result = crc32((unsigned char const *)argv[1], strlen(argv[1]));
+       printf("0x%x\n", result);
+       return 0;
+}
diff --git a/tools/testing/selftests/filesystems/.gitignore b/tools/testing/selftests/filesystems/.gitignore
new file mode 100644 (file)
index 0000000..31d6e42
--- /dev/null
@@ -0,0 +1 @@
+dnotify_test
diff --git a/tools/testing/selftests/filesystems/Makefile b/tools/testing/selftests/filesystems/Makefile
new file mode 100644 (file)
index 0000000..0ab1130
--- /dev/null
@@ -0,0 +1,7 @@
+TEST_PROGS := dnotify_test
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/filesystems/dnotify_test.c b/tools/testing/selftests/filesystems/dnotify_test.c
new file mode 100644 (file)
index 0000000..8b37b4a
--- /dev/null
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE    /* needed to get the defines */
+#include <fcntl.h>     /* in glibc 2.2 this has the needed
+                                  values defined */
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static volatile int event_fd;
+
+static void handler(int sig, siginfo_t *si, void *data)
+{
+       event_fd = si->si_fd;
+}
+
+int main(void)
+{
+       struct sigaction act;
+       int fd;
+
+       act.sa_sigaction = handler;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = SA_SIGINFO;
+       sigaction(SIGRTMIN + 1, &act, NULL);
+
+       fd = open(".", O_RDONLY);
+       fcntl(fd, F_SETSIG, SIGRTMIN + 1);
+       fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
+       /* we will now be notified if any of the files
+          in "." is modified or new files are created */
+       while (1) {
+               pause();
+               printf("Got event on fd=%d\n", event_fd);
+       }
+}
index e87dbe2..7ff002e 100755 (executable)
@@ -24,7 +24,7 @@
 
 # Test for a color capable console
 if [ -z "$USE_COLOR" ]; then
-    tput setf 7
+    tput setf 7 || tput setaf 7
     if [ $? -eq 0 ]; then
         USE_COLOR=1
         tput sgr0
index 4126312..88bcb17 100755 (executable)
@@ -23,7 +23,7 @@
 
 # Test for a color capable shell and pass the result to the subdir scripts
 USE_COLOR=0
-tput setf 7
+tput setf 7 || tput setaf 7
 if [ $? -eq 0 ]; then
     USE_COLOR=1
     tput sgr0
diff --git a/tools/testing/selftests/ia64/.gitignore b/tools/testing/selftests/ia64/.gitignore
new file mode 100644 (file)
index 0000000..ab806ed
--- /dev/null
@@ -0,0 +1 @@
+aliasing-test
diff --git a/tools/testing/selftests/ia64/Makefile b/tools/testing/selftests/ia64/Makefile
new file mode 100644 (file)
index 0000000..2b3de2d
--- /dev/null
@@ -0,0 +1,8 @@
+TEST_PROGS := aliasing-test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/ia64/aliasing-test.c b/tools/testing/selftests/ia64/aliasing-test.c
new file mode 100644 (file)
index 0000000..62a190d
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Exercise /dev/mem mmap cases that have been troublesome in the past
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ *     Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <linux/pci.h>
+
+int sum;
+
+static int map_mem(char *path, off_t offset, size_t length, int touch)
+{
+       int fd, rc;
+       void *addr;
+       int *c;
+
+       fd = open(path, O_RDWR);
+       if (fd == -1) {
+               perror(path);
+               return -1;
+       }
+
+       if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
+               rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
+               if (rc == -1)
+                       perror("PCIIOC_MMAP_IS_MEM ioctl");
+       }
+
+       addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
+       if (addr == MAP_FAILED)
+               return 1;
+
+       if (touch) {
+               c = (int *) addr;
+               while (c < (int *) (addr + length))
+                       sum += *c++;
+       }
+
+       rc = munmap(addr, length);
+       if (rc == -1) {
+               perror("munmap");
+               return -1;
+       }
+
+       close(fd);
+       return 0;
+}
+
+static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
+{
+       struct dirent **namelist;
+       char *name, *path2;
+       int i, n, r, rc = 0, result = 0;
+       struct stat buf;
+
+       n = scandir(path, &namelist, 0, alphasort);
+       if (n < 0) {
+               perror("scandir");
+               return -1;
+       }
+
+       for (i = 0; i < n; i++) {
+               name = namelist[i]->d_name;
+
+               if (fnmatch(".", name, 0) == 0)
+                       goto skip;
+               if (fnmatch("..", name, 0) == 0)
+                       goto skip;
+
+               path2 = malloc(strlen(path) + strlen(name) + 3);
+               strcpy(path2, path);
+               strcat(path2, "/");
+               strcat(path2, name);
+
+               if (fnmatch(file, name, 0) == 0) {
+                       rc = map_mem(path2, offset, length, touch);
+                       if (rc == 0)
+                               fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
+                       else if (rc > 0)
+                               fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
+                       else {
+                               fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
+                               return rc;
+                       }
+               } else {
+                       r = lstat(path2, &buf);
+                       if (r == 0 && S_ISDIR(buf.st_mode)) {
+                               rc = scan_tree(path2, file, offset, length, touch);
+                               if (rc < 0)
+                                       return rc;
+                       }
+               }
+
+               result |= rc;
+               free(path2);
+
+skip:
+               free(namelist[i]);
+       }
+       free(namelist);
+       return result;
+}
+
+char buf[1024];
+
+static int read_rom(char *path)
+{
+       int fd, rc;
+       size_t size = 0;
+
+       fd = open(path, O_RDWR);
+       if (fd == -1) {
+               perror(path);
+               return -1;
+       }
+
+       rc = write(fd, "1", 2);
+       if (rc <= 0) {
+               close(fd);
+               perror("write");
+               return -1;
+       }
+
+       do {
+               rc = read(fd, buf, sizeof(buf));
+               if (rc > 0)
+                       size += rc;
+       } while (rc > 0);
+
+       close(fd);
+       return size;
+}
+
+static int scan_rom(char *path, char *file)
+{
+       struct dirent **namelist;
+       char *name, *path2;
+       int i, n, r, rc = 0, result = 0;
+       struct stat buf;
+
+       n = scandir(path, &namelist, 0, alphasort);
+       if (n < 0) {
+               perror("scandir");
+               return -1;
+       }
+
+       for (i = 0; i < n; i++) {
+               name = namelist[i]->d_name;
+
+               if (fnmatch(".", name, 0) == 0)
+                       goto skip;
+               if (fnmatch("..", name, 0) == 0)
+                       goto skip;
+
+               path2 = malloc(strlen(path) + strlen(name) + 3);
+               strcpy(path2, path);
+               strcat(path2, "/");
+               strcat(path2, name);
+
+               if (fnmatch(file, name, 0) == 0) {
+                       rc = read_rom(path2);
+
+                       /*
+                        * It's OK if the ROM is unreadable.  Maybe there
+                        * is no ROM, or some other error occurred.  The
+                        * important thing is that no MCA happened.
+                        */
+                       if (rc > 0)
+                               fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
+                       else {
+                               fprintf(stderr, "PASS: %s not readable\n", path2);
+                               return rc;
+                       }
+               } else {
+                       r = lstat(path2, &buf);
+                       if (r == 0 && S_ISDIR(buf.st_mode)) {
+                               rc = scan_rom(path2, file);
+                               if (rc < 0)
+                                       return rc;
+                       }
+               }
+
+               result |= rc;
+               free(path2);
+
+skip:
+               free(namelist[i]);
+       }
+       free(namelist);
+       return result;
+}
+
+int main(void)
+{
+       int rc;
+
+       if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
+               fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
+       else
+               fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
+
+       /*
+        * It's not safe to blindly read the VGA frame buffer.  If you know
+        * how to poke the card the right way, it should respond, but it's
+        * not safe in general.  Many machines, e.g., Intel chipsets, cover
+        * up a non-responding card by just returning -1, but others will
+        * report the failure as a machine check.
+        */
+       if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
+               fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
+       else
+               fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
+
+       if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
+               fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
+       else
+               fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
+
+       /*
+        * Often you can map all the individual pieces above (0-0xA0000,
+        * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
+        * thing at once.  This is because the individual pieces use different
+        * attributes, and there's no single attribute supported over the
+        * whole region.
+        */
+       rc = map_mem("/dev/mem", 0, 1024*1024, 0);
+       if (rc == 0)
+               fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
+       else if (rc > 0)
+               fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
+       else
+               fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
+
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
+
+       scan_rom("/sys/devices", "rom");
+
+       scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
+       scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
+
+       return rc;
+}
diff --git a/tools/testing/selftests/networking/timestamping/.gitignore b/tools/testing/selftests/networking/timestamping/.gitignore
new file mode 100644 (file)
index 0000000..9e69e98
--- /dev/null
@@ -0,0 +1,3 @@
+timestamping
+txtimestamp
+hwtstamp_config
diff --git a/tools/testing/selftests/networking/timestamping/Makefile b/tools/testing/selftests/networking/timestamping/Makefile
new file mode 100644 (file)
index 0000000..ccbb9ed
--- /dev/null
@@ -0,0 +1,8 @@
+TEST_PROGS := hwtstamp_config timestamping txtimestamp
+
+all: $(TEST_PROGS)
+
+include ../../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/networking/timestamping/hwtstamp_config.c b/tools/testing/selftests/networking/timestamping/hwtstamp_config.c
new file mode 100644 (file)
index 0000000..e8b685a
--- /dev/null
@@ -0,0 +1,134 @@
+/* Test program for SIOC{G,S}HWTSTAMP
+ * Copyright 2013 Solarflare Communications
+ * Author: Ben Hutchings
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <linux/if.h>
+#include <linux/net_tstamp.h>
+#include <linux/sockios.h>
+
+static int
+lookup_value(const char **names, int size, const char *name)
+{
+       int value;
+
+       for (value = 0; value < size; value++)
+               if (names[value] && strcasecmp(names[value], name) == 0)
+                       return value;
+
+       return -1;
+}
+
+static const char *
+lookup_name(const char **names, int size, int value)
+{
+       return (value >= 0 && value < size) ? names[value] : NULL;
+}
+
+static void list_names(FILE *f, const char **names, int size)
+{
+       int value;
+
+       for (value = 0; value < size; value++)
+               if (names[value])
+                       fprintf(f, "    %s\n", names[value]);
+}
+
+static const char *tx_types[] = {
+#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
+       TX_TYPE(OFF),
+       TX_TYPE(ON),
+       TX_TYPE(ONESTEP_SYNC)
+#undef TX_TYPE
+};
+#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
+
+static const char *rx_filters[] = {
+#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
+       RX_FILTER(NONE),
+       RX_FILTER(ALL),
+       RX_FILTER(SOME),
+       RX_FILTER(PTP_V1_L4_EVENT),
+       RX_FILTER(PTP_V1_L4_SYNC),
+       RX_FILTER(PTP_V1_L4_DELAY_REQ),
+       RX_FILTER(PTP_V2_L4_EVENT),
+       RX_FILTER(PTP_V2_L4_SYNC),
+       RX_FILTER(PTP_V2_L4_DELAY_REQ),
+       RX_FILTER(PTP_V2_L2_EVENT),
+       RX_FILTER(PTP_V2_L2_SYNC),
+       RX_FILTER(PTP_V2_L2_DELAY_REQ),
+       RX_FILTER(PTP_V2_EVENT),
+       RX_FILTER(PTP_V2_SYNC),
+       RX_FILTER(PTP_V2_DELAY_REQ),
+#undef RX_FILTER
+};
+#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
+
+static void usage(void)
+{
+       fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
+             "tx_type is any of (case-insensitive):\n",
+             stderr);
+       list_names(stderr, tx_types, N_TX_TYPES);
+       fputs("rx_filter is any of (case-insensitive):\n", stderr);
+       list_names(stderr, rx_filters, N_RX_FILTERS);
+}
+
+int main(int argc, char **argv)
+{
+       struct ifreq ifr;
+       struct hwtstamp_config config;
+       const char *name;
+       int sock;
+
+       if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
+               usage();
+               return 2;
+       }
+
+       if (argc == 4) {
+               config.flags = 0;
+               config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
+               config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
+               if (config.tx_type < 0 || config.rx_filter < 0) {
+                       usage();
+                       return 2;
+               }
+       }
+
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0) {
+               perror("socket");
+               return 1;
+       }
+
+       strcpy(ifr.ifr_name, argv[1]);
+       ifr.ifr_data = (caddr_t)&config;
+
+       if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
+               perror("ioctl");
+               return 1;
+       }
+
+       printf("flags = %#x\n", config.flags);
+       name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
+       if (name)
+               printf("tx_type = %s\n", name);
+       else
+               printf("tx_type = %d\n", config.tx_type);
+       name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
+       if (name)
+               printf("rx_filter = %s\n", name);
+       else
+               printf("rx_filter = %d\n", config.rx_filter);
+
+       return 0;
+}
diff --git a/tools/testing/selftests/networking/timestamping/timestamping.c b/tools/testing/selftests/networking/timestamping/timestamping.c
new file mode 100644 (file)
index 0000000..5cdfd74
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * This program demonstrates how the various time stamping features in
+ * the Linux kernel work. It emulates the behavior of a PTP
+ * implementation in stand-alone master mode by sending PTPv1 Sync
+ * multicasts once every second. It looks for similar packets, but
+ * beyond that doesn't actually implement PTP.
+ *
+ * Outgoing packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support.
+ *
+ * Incoming packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
+ * SO_TIMESTAMP[NS].
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Author: Patrick Ohly <patrick.ohly@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include <asm/types.h>
+#include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
+
+#ifndef SO_TIMESTAMPING
+# define SO_TIMESTAMPING         37
+# define SCM_TIMESTAMPING        SO_TIMESTAMPING
+#endif
+
+#ifndef SO_TIMESTAMPNS
+# define SO_TIMESTAMPNS 35
+#endif
+
+#ifndef SIOCGSTAMPNS
+# define SIOCGSTAMPNS 0x8907
+#endif
+
+#ifndef SIOCSHWTSTAMP
+# define SIOCSHWTSTAMP 0x89b0
+#endif
+
+static void usage(const char *error)
+{
+       if (error)
+               printf("invalid option: %s\n", error);
+       printf("timestamping interface option*\n\n"
+              "Options:\n"
+              "  IP_MULTICAST_LOOP - looping outgoing multicasts\n"
+              "  SO_TIMESTAMP - normal software time stamping, ms resolution\n"
+              "  SO_TIMESTAMPNS - more accurate software time stamping\n"
+              "  SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
+              "  SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
+              "  SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
+              "  SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
+              "  SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
+              "  SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
+              "  SIOCGSTAMP - check last socket time stamp\n"
+              "  SIOCGSTAMPNS - more accurate socket time stamp\n");
+       exit(1);
+}
+
+static void bail(const char *error)
+{
+       printf("%s: %s\n", error, strerror(errno));
+       exit(1);
+}
+
+static const unsigned char sync[] = {
+       0x00, 0x01, 0x00, 0x01,
+       0x5f, 0x44, 0x46, 0x4c,
+       0x54, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x01, 0x01,
+
+       /* fake uuid */
+       0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05,
+
+       0x00, 0x01, 0x00, 0x37,
+       0x00, 0x00, 0x00, 0x08,
+       0x00, 0x00, 0x00, 0x00,
+       0x49, 0x05, 0xcd, 0x01,
+       0x29, 0xb1, 0x8d, 0xb0,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01,
+
+       /* fake uuid */
+       0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05,
+
+       0x00, 0x00, 0x00, 0x37,
+       0x00, 0x00, 0x00, 0x04,
+       0x44, 0x46, 0x4c, 0x54,
+       0x00, 0x00, 0xf0, 0x60,
+       0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01,
+       0x00, 0x00, 0xf0, 0x60,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x04,
+       0x44, 0x46, 0x4c, 0x54,
+       0x00, 0x01,
+
+       /* fake uuid */
+       0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05,
+
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00
+};
+
+static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
+{
+       struct timeval now;
+       int res;
+
+       res = sendto(sock, sync, sizeof(sync), 0,
+               addr, addr_len);
+       gettimeofday(&now, 0);
+       if (res < 0)
+               printf("%s: %s\n", "send", strerror(errno));
+       else
+               printf("%ld.%06ld: sent %d bytes\n",
+                      (long)now.tv_sec, (long)now.tv_usec,
+                      res);
+}
+
+static void printpacket(struct msghdr *msg, int res,
+                       char *data,
+                       int sock, int recvmsg_flags,
+                       int siocgstamp, int siocgstampns)
+{
+       struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
+       struct cmsghdr *cmsg;
+       struct timeval tv;
+       struct timespec ts;
+       struct timeval now;
+
+       gettimeofday(&now, 0);
+
+       printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
+              (long)now.tv_sec, (long)now.tv_usec,
+              (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+              res,
+              inet_ntoa(from_addr->sin_addr),
+              msg->msg_controllen);
+       for (cmsg = CMSG_FIRSTHDR(msg);
+            cmsg;
+            cmsg = CMSG_NXTHDR(msg, cmsg)) {
+               printf("   cmsg len %zu: ", cmsg->cmsg_len);
+               switch (cmsg->cmsg_level) {
+               case SOL_SOCKET:
+                       printf("SOL_SOCKET ");
+                       switch (cmsg->cmsg_type) {
+                       case SO_TIMESTAMP: {
+                               struct timeval *stamp =
+                                       (struct timeval *)CMSG_DATA(cmsg);
+                               printf("SO_TIMESTAMP %ld.%06ld",
+                                      (long)stamp->tv_sec,
+                                      (long)stamp->tv_usec);
+                               break;
+                       }
+                       case SO_TIMESTAMPNS: {
+                               struct timespec *stamp =
+                                       (struct timespec *)CMSG_DATA(cmsg);
+                               printf("SO_TIMESTAMPNS %ld.%09ld",
+                                      (long)stamp->tv_sec,
+                                      (long)stamp->tv_nsec);
+                               break;
+                       }
+                       case SO_TIMESTAMPING: {
+                               struct timespec *stamp =
+                                       (struct timespec *)CMSG_DATA(cmsg);
+                               printf("SO_TIMESTAMPING ");
+                               printf("SW %ld.%09ld ",
+                                      (long)stamp->tv_sec,
+                                      (long)stamp->tv_nsec);
+                               stamp++;
+                               /* skip deprecated HW transformed */
+                               stamp++;
+                               printf("HW raw %ld.%09ld",
+                                      (long)stamp->tv_sec,
+                                      (long)stamp->tv_nsec);
+                               break;
+                       }
+                       default:
+                               printf("type %d", cmsg->cmsg_type);
+                               break;
+                       }
+                       break;
+               case IPPROTO_IP:
+                       printf("IPPROTO_IP ");
+                       switch (cmsg->cmsg_type) {
+                       case IP_RECVERR: {
+                               struct sock_extended_err *err =
+                                       (struct sock_extended_err *)CMSG_DATA(cmsg);
+                               printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
+                                       strerror(err->ee_errno),
+                                       err->ee_origin,
+#ifdef SO_EE_ORIGIN_TIMESTAMPING
+                                       err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
+                                       "bounced packet" : "unexpected origin"
+#else
+                                       "probably SO_EE_ORIGIN_TIMESTAMPING"
+#endif
+                                       );
+                               if (res < sizeof(sync))
+                                       printf(" => truncated data?!");
+                               else if (!memcmp(sync, data + res - sizeof(sync),
+                                                       sizeof(sync)))
+                                       printf(" => GOT OUR DATA BACK (HURRAY!)");
+                               break;
+                       }
+                       case IP_PKTINFO: {
+                               struct in_pktinfo *pktinfo =
+                                       (struct in_pktinfo *)CMSG_DATA(cmsg);
+                               printf("IP_PKTINFO interface index %u",
+                                       pktinfo->ipi_ifindex);
+                               break;
+                       }
+                       default:
+                               printf("type %d", cmsg->cmsg_type);
+                               break;
+                       }
+                       break;
+               default:
+                       printf("level %d type %d",
+                               cmsg->cmsg_level,
+                               cmsg->cmsg_type);
+                       break;
+               }
+               printf("\n");
+       }
+
+       if (siocgstamp) {
+               if (ioctl(sock, SIOCGSTAMP, &tv))
+                       printf("   %s: %s\n", "SIOCGSTAMP", strerror(errno));
+               else
+                       printf("SIOCGSTAMP %ld.%06ld\n",
+                              (long)tv.tv_sec,
+                              (long)tv.tv_usec);
+       }
+       if (siocgstampns) {
+               if (ioctl(sock, SIOCGSTAMPNS, &ts))
+                       printf("   %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
+               else
+                       printf("SIOCGSTAMPNS %ld.%09ld\n",
+                              (long)ts.tv_sec,
+                              (long)ts.tv_nsec);
+       }
+}
+
+static void recvpacket(int sock, int recvmsg_flags,
+                      int siocgstamp, int siocgstampns)
+{
+       char data[256];
+       struct msghdr msg;
+       struct iovec entry;
+       struct sockaddr_in from_addr;
+       struct {
+               struct cmsghdr cm;
+               char control[512];
+       } control;
+       int res;
+
+       memset(&msg, 0, sizeof(msg));
+       msg.msg_iov = &entry;
+       msg.msg_iovlen = 1;
+       entry.iov_base = data;
+       entry.iov_len = sizeof(data);
+       msg.msg_name = (caddr_t)&from_addr;
+       msg.msg_namelen = sizeof(from_addr);
+       msg.msg_control = &control;
+       msg.msg_controllen = sizeof(control);
+
+       res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
+       if (res < 0) {
+               printf("%s %s: %s\n",
+                      "recvmsg",
+                      (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+                      strerror(errno));
+       } else {
+               printpacket(&msg, res, data,
+                           sock, recvmsg_flags,
+                           siocgstamp, siocgstampns);
+       }
+}
+
+int main(int argc, char **argv)
+{
+       int so_timestamping_flags = 0;
+       int so_timestamp = 0;
+       int so_timestampns = 0;
+       int siocgstamp = 0;
+       int siocgstampns = 0;
+       int ip_multicast_loop = 0;
+       char *interface;
+       int i;
+       int enabled = 1;
+       int sock;
+       struct ifreq device;
+       struct ifreq hwtstamp;
+       struct hwtstamp_config hwconfig, hwconfig_requested;
+       struct sockaddr_in addr;
+       struct ip_mreq imr;
+       struct in_addr iaddr;
+       int val;
+       socklen_t len;
+       struct timeval next;
+
+       if (argc < 2)
+               usage(0);
+       interface = argv[1];
+
+       for (i = 2; i < argc; i++) {
+               if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
+                       so_timestamp = 1;
+               else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
+                       so_timestampns = 1;
+               else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
+                       siocgstamp = 1;
+               else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
+                       siocgstampns = 1;
+               else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
+                       ip_multicast_loop = 1;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
+                       so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+               else
+                       usage(argv[i]);
+       }
+
+       sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (sock < 0)
+               bail("socket");
+
+       memset(&device, 0, sizeof(device));
+       strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
+       if (ioctl(sock, SIOCGIFADDR, &device) < 0)
+               bail("getting interface IP address");
+
+       memset(&hwtstamp, 0, sizeof(hwtstamp));
+       strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
+       hwtstamp.ifr_data = (void *)&hwconfig;
+       memset(&hwconfig, 0, sizeof(hwconfig));
+       hwconfig.tx_type =
+               (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
+               HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+       hwconfig.rx_filter =
+               (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
+               HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
+       hwconfig_requested = hwconfig;
+       if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
+               if ((errno == EINVAL || errno == ENOTSUP) &&
+                   hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
+                   hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
+                       printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
+               else
+                       bail("SIOCSHWTSTAMP");
+       }
+       printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
+              hwconfig_requested.tx_type, hwconfig.tx_type,
+              hwconfig_requested.rx_filter, hwconfig.rx_filter);
+
+       /* bind to PTP port */
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       addr.sin_port = htons(319 /* PTP event port */);
+       if (bind(sock,
+                (struct sockaddr *)&addr,
+                sizeof(struct sockaddr_in)) < 0)
+               bail("bind");
+
+       /* set multicast group for outgoing packets */
+       inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
+       addr.sin_addr = iaddr;
+       imr.imr_multiaddr.s_addr = iaddr.s_addr;
+       imr.imr_interface.s_addr =
+               ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
+       if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
+                      &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
+               bail("set multicast");
+
+       /* join multicast group, loop our own packet */
+       if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                      &imr, sizeof(struct ip_mreq)) < 0)
+               bail("join multicast group");
+
+       if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
+                      &ip_multicast_loop, sizeof(enabled)) < 0) {
+               bail("loop multicast");
+       }
+
+       /* set socket options for time stamping */
+       if (so_timestamp &&
+               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
+                          &enabled, sizeof(enabled)) < 0)
+               bail("setsockopt SO_TIMESTAMP");
+
+       if (so_timestampns &&
+               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
+                          &enabled, sizeof(enabled)) < 0)
+               bail("setsockopt SO_TIMESTAMPNS");
+
+       if (so_timestamping_flags &&
+               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
+                          &so_timestamping_flags,
+                          sizeof(so_timestamping_flags)) < 0)
+               bail("setsockopt SO_TIMESTAMPING");
+
+       /* request IP_PKTINFO for debugging purposes */
+       if (setsockopt(sock, SOL_IP, IP_PKTINFO,
+                      &enabled, sizeof(enabled)) < 0)
+               printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
+
+       /* verify socket options */
+       len = sizeof(val);
+       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
+               printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
+       else
+               printf("SO_TIMESTAMP %d\n", val);
+
+       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
+               printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
+                      strerror(errno));
+       else
+               printf("SO_TIMESTAMPNS %d\n", val);
+
+       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
+               printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
+                      strerror(errno));
+       } else {
+               printf("SO_TIMESTAMPING %d\n", val);
+               if (val != so_timestamping_flags)
+                       printf("   not the expected value %d\n",
+                              so_timestamping_flags);
+       }
+
+       /* send packets forever every five seconds */
+       gettimeofday(&next, 0);
+       next.tv_sec = (next.tv_sec + 1) / 5 * 5;
+       next.tv_usec = 0;
+       while (1) {
+               struct timeval now;
+               struct timeval delta;
+               long delta_us;
+               int res;
+               fd_set readfs, errorfs;
+
+               gettimeofday(&now, 0);
+               delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
+                       (long)(next.tv_usec - now.tv_usec);
+               if (delta_us > 0) {
+                       /* continue waiting for timeout or data */
+                       delta.tv_sec = delta_us / 1000000;
+                       delta.tv_usec = delta_us % 1000000;
+
+                       FD_ZERO(&readfs);
+                       FD_ZERO(&errorfs);
+                       FD_SET(sock, &readfs);
+                       FD_SET(sock, &errorfs);
+                       printf("%ld.%06ld: select %ldus\n",
+                              (long)now.tv_sec, (long)now.tv_usec,
+                              delta_us);
+                       res = select(sock + 1, &readfs, 0, &errorfs, &delta);
+                       gettimeofday(&now, 0);
+                       printf("%ld.%06ld: select returned: %d, %s\n",
+                              (long)now.tv_sec, (long)now.tv_usec,
+                              res,
+                              res < 0 ? strerror(errno) : "success");
+                       if (res > 0) {
+                               if (FD_ISSET(sock, &readfs))
+                                       printf("ready for reading\n");
+                               if (FD_ISSET(sock, &errorfs))
+                                       printf("has error\n");
+                               recvpacket(sock, 0,
+                                          siocgstamp,
+                                          siocgstampns);
+                               recvpacket(sock, MSG_ERRQUEUE,
+                                          siocgstamp,
+                                          siocgstampns);
+                       }
+               } else {
+                       /* write one packet */
+                       sendpacket(sock,
+                                  (struct sockaddr *)&addr,
+                                  sizeof(addr));
+                       next.tv_sec += 5;
+                       continue;
+               }
+       }
+
+       return 0;
+}
diff --git a/tools/testing/selftests/networking/timestamping/txtimestamp.c b/tools/testing/selftests/networking/timestamping/txtimestamp.c
new file mode 100644 (file)
index 0000000..5df0704
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2014 Google Inc.
+ * Author: willemb@google.com (Willem de Bruijn)
+ *
+ * Test software tx timestamping, including
+ *
+ * - SCHED, SND and ACK timestamps
+ * - RAW, UDP and TCP
+ * - IPv4 and IPv6
+ * - various packet sizes (to test GSO and TSO)
+ *
+ * Consult the command line arguments for help on running
+ * the various testcases.
+ *
+ * This test requires a dummy TCP server.
+ * A simple `nc6 [-u] -l -p $DESTPORT` will do
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <asm/types.h>
+#include <error.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/errqueue.h>
+#include <linux/if_ether.h>
+#include <linux/net_tstamp.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+#include <netpacket/packet.h>
+#include <poll.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+/* command line parameters */
+static int cfg_proto = SOCK_STREAM;
+static int cfg_ipproto = IPPROTO_TCP;
+static int cfg_num_pkts = 4;
+static int do_ipv4 = 1;
+static int do_ipv6 = 1;
+static int cfg_payload_len = 10;
+static bool cfg_show_payload;
+static bool cfg_do_pktinfo;
+static bool cfg_loop_nodata;
+static uint16_t dest_port = 9000;
+
+static struct sockaddr_in daddr;
+static struct sockaddr_in6 daddr6;
+static struct timespec ts_prev;
+
+static void __print_timestamp(const char *name, struct timespec *cur,
+                             uint32_t key, int payload_len)
+{
+       if (!(cur->tv_sec | cur->tv_nsec))
+               return;
+
+       fprintf(stderr, "  %s: %lu s %lu us (seq=%u, len=%u)",
+                       name, cur->tv_sec, cur->tv_nsec / 1000,
+                       key, payload_len);
+
+       if ((ts_prev.tv_sec | ts_prev.tv_nsec)) {
+               int64_t cur_ms, prev_ms;
+
+               cur_ms = (long) cur->tv_sec * 1000 * 1000;
+               cur_ms += cur->tv_nsec / 1000;
+
+               prev_ms = (long) ts_prev.tv_sec * 1000 * 1000;
+               prev_ms += ts_prev.tv_nsec / 1000;
+
+               fprintf(stderr, "  (%+" PRId64 " us)", cur_ms - prev_ms);
+       }
+
+       ts_prev = *cur;
+       fprintf(stderr, "\n");
+}
+
+static void print_timestamp_usr(void)
+{
+       struct timespec ts;
+       struct timeval tv;      /* avoid dependency on -lrt */
+
+       gettimeofday(&tv, NULL);
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = tv.tv_usec * 1000;
+
+       __print_timestamp("  USR", &ts, 0, 0);
+}
+
+static void print_timestamp(struct scm_timestamping *tss, int tstype,
+                           int tskey, int payload_len)
+{
+       const char *tsname;
+
+       switch (tstype) {
+       case SCM_TSTAMP_SCHED:
+               tsname = "  ENQ";
+               break;
+       case SCM_TSTAMP_SND:
+               tsname = "  SND";
+               break;
+       case SCM_TSTAMP_ACK:
+               tsname = "  ACK";
+               break;
+       default:
+               error(1, 0, "unknown timestamp type: %u",
+               tstype);
+       }
+       __print_timestamp(tsname, &tss->ts[0], tskey, payload_len);
+}
+
+/* TODO: convert to check_and_print payload once API is stable */
+static void print_payload(char *data, int len)
+{
+       int i;
+
+       if (!len)
+               return;
+
+       if (len > 70)
+               len = 70;
+
+       fprintf(stderr, "payload: ");
+       for (i = 0; i < len; i++)
+               fprintf(stderr, "%02hhx ", data[i]);
+       fprintf(stderr, "\n");
+}
+
+static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr)
+{
+       char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN];
+
+       fprintf(stderr, "         pktinfo: ifindex=%u src=%s dst=%s\n",
+               ifindex,
+               saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown",
+               daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown");
+}
+
+static void __poll(int fd)
+{
+       struct pollfd pollfd;
+       int ret;
+
+       memset(&pollfd, 0, sizeof(pollfd));
+       pollfd.fd = fd;
+       ret = poll(&pollfd, 1, 100);
+       if (ret != 1)
+               error(1, errno, "poll");
+}
+
+static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
+{
+       struct sock_extended_err *serr = NULL;
+       struct scm_timestamping *tss = NULL;
+       struct cmsghdr *cm;
+       int batch = 0;
+
+       for (cm = CMSG_FIRSTHDR(msg);
+            cm && cm->cmsg_len;
+            cm = CMSG_NXTHDR(msg, cm)) {
+               if (cm->cmsg_level == SOL_SOCKET &&
+                   cm->cmsg_type == SCM_TIMESTAMPING) {
+                       tss = (void *) CMSG_DATA(cm);
+               } else if ((cm->cmsg_level == SOL_IP &&
+                           cm->cmsg_type == IP_RECVERR) ||
+                          (cm->cmsg_level == SOL_IPV6 &&
+                           cm->cmsg_type == IPV6_RECVERR)) {
+                       serr = (void *) CMSG_DATA(cm);
+                       if (serr->ee_errno != ENOMSG ||
+                           serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) {
+                               fprintf(stderr, "unknown ip error %d %d\n",
+                                               serr->ee_errno,
+                                               serr->ee_origin);
+                               serr = NULL;
+                       }
+               } else if (cm->cmsg_level == SOL_IP &&
+                          cm->cmsg_type == IP_PKTINFO) {
+                       struct in_pktinfo *info = (void *) CMSG_DATA(cm);
+                       print_pktinfo(AF_INET, info->ipi_ifindex,
+                                     &info->ipi_spec_dst, &info->ipi_addr);
+               } else if (cm->cmsg_level == SOL_IPV6 &&
+                          cm->cmsg_type == IPV6_PKTINFO) {
+                       struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm);
+                       print_pktinfo(AF_INET6, info6->ipi6_ifindex,
+                                     NULL, &info6->ipi6_addr);
+               } else
+                       fprintf(stderr, "unknown cmsg %d,%d\n",
+                                       cm->cmsg_level, cm->cmsg_type);
+
+               if (serr && tss) {
+                       print_timestamp(tss, serr->ee_info, serr->ee_data,
+                                       payload_len);
+                       serr = NULL;
+                       tss = NULL;
+                       batch++;
+               }
+       }
+
+       if (batch > 1)
+               fprintf(stderr, "batched %d timestamps\n", batch);
+}
+
+static int recv_errmsg(int fd)
+{
+       static char ctrl[1024 /* overprovision*/];
+       static struct msghdr msg;
+       struct iovec entry;
+       static char *data;
+       int ret = 0;
+
+       data = malloc(cfg_payload_len);
+       if (!data)
+               error(1, 0, "malloc");
+
+       memset(&msg, 0, sizeof(msg));
+       memset(&entry, 0, sizeof(entry));
+       memset(ctrl, 0, sizeof(ctrl));
+
+       entry.iov_base = data;
+       entry.iov_len = cfg_payload_len;
+       msg.msg_iov = &entry;
+       msg.msg_iovlen = 1;
+       msg.msg_name = NULL;
+       msg.msg_namelen = 0;
+       msg.msg_control = ctrl;
+       msg.msg_controllen = sizeof(ctrl);
+
+       ret = recvmsg(fd, &msg, MSG_ERRQUEUE);
+       if (ret == -1 && errno != EAGAIN)
+               error(1, errno, "recvmsg");
+
+       if (ret >= 0) {
+               __recv_errmsg_cmsg(&msg, ret);
+               if (cfg_show_payload)
+                       print_payload(data, cfg_payload_len);
+       }
+
+       free(data);
+       return ret == -1;
+}
+
+static void do_test(int family, unsigned int opt)
+{
+       char *buf;
+       int fd, i, val = 1, total_len;
+
+       if (family == AF_INET6 && cfg_proto != SOCK_STREAM) {
+               /* due to lack of checksum generation code */
+               fprintf(stderr, "test: skipping datagram over IPv6\n");
+               return;
+       }
+
+       total_len = cfg_payload_len;
+       if (cfg_proto == SOCK_RAW) {
+               total_len += sizeof(struct udphdr);
+               if (cfg_ipproto == IPPROTO_RAW)
+                       total_len += sizeof(struct iphdr);
+       }
+
+       buf = malloc(total_len);
+       if (!buf)
+               error(1, 0, "malloc");
+
+       fd = socket(family, cfg_proto, cfg_ipproto);
+       if (fd < 0)
+               error(1, errno, "socket");
+
+       if (cfg_proto == SOCK_STREAM) {
+               if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+                              (char*) &val, sizeof(val)))
+                       error(1, 0, "setsockopt no nagle");
+
+               if (family == PF_INET) {
+                       if (connect(fd, (void *) &daddr, sizeof(daddr)))
+                               error(1, errno, "connect ipv4");
+               } else {
+                       if (connect(fd, (void *) &daddr6, sizeof(daddr6)))
+                               error(1, errno, "connect ipv6");
+               }
+       }
+
+       if (cfg_do_pktinfo) {
+               if (family == AF_INET6) {
+                       if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO,
+                                      &val, sizeof(val)))
+                               error(1, errno, "setsockopt pktinfo ipv6");
+               } else {
+                       if (setsockopt(fd, SOL_IP, IP_PKTINFO,
+                                      &val, sizeof(val)))
+                               error(1, errno, "setsockopt pktinfo ipv4");
+               }
+       }
+
+       opt |= SOF_TIMESTAMPING_SOFTWARE |
+              SOF_TIMESTAMPING_OPT_CMSG |
+              SOF_TIMESTAMPING_OPT_ID;
+       if (cfg_loop_nodata)
+               opt |= SOF_TIMESTAMPING_OPT_TSONLY;
+
+       if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
+                      (char *) &opt, sizeof(opt)))
+               error(1, 0, "setsockopt timestamping");
+
+       for (i = 0; i < cfg_num_pkts; i++) {
+               memset(&ts_prev, 0, sizeof(ts_prev));
+               memset(buf, 'a' + i, total_len);
+
+               if (cfg_proto == SOCK_RAW) {
+                       struct udphdr *udph;
+                       int off = 0;
+
+                       if (cfg_ipproto == IPPROTO_RAW) {
+                               struct iphdr *iph = (void *) buf;
+
+                               memset(iph, 0, sizeof(*iph));
+                               iph->ihl      = 5;
+                               iph->version  = 4;
+                               iph->ttl      = 2;
+                               iph->daddr    = daddr.sin_addr.s_addr;
+                               iph->protocol = IPPROTO_UDP;
+                               /* kernel writes saddr, csum, len */
+
+                               off = sizeof(*iph);
+                       }
+
+                       udph = (void *) buf + off;
+                       udph->source = ntohs(9000);     /* random spoof */
+                       udph->dest   = ntohs(dest_port);
+                       udph->len    = ntohs(sizeof(*udph) + cfg_payload_len);
+                       udph->check  = 0;       /* not allowed for IPv6 */
+               }
+
+               print_timestamp_usr();
+               if (cfg_proto != SOCK_STREAM) {
+                       if (family == PF_INET)
+                               val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr));
+                       else
+                               val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6));
+               } else {
+                       val = send(fd, buf, cfg_payload_len, 0);
+               }
+               if (val != total_len)
+                       error(1, errno, "send");
+
+               /* wait for all errors to be queued, else ACKs arrive OOO */
+               usleep(50 * 1000);
+
+               __poll(fd);
+
+               while (!recv_errmsg(fd)) {}
+       }
+
+       if (close(fd))
+               error(1, errno, "close");
+
+       free(buf);
+       usleep(400 * 1000);
+}
+
+static void __attribute__((noreturn)) usage(const char *filepath)
+{
+       fprintf(stderr, "\nUsage: %s [options] hostname\n"
+                       "\nwhere options are:\n"
+                       "  -4:   only IPv4\n"
+                       "  -6:   only IPv6\n"
+                       "  -h:   show this message\n"
+                       "  -I:   request PKTINFO\n"
+                       "  -l N: send N bytes at a time\n"
+                       "  -n:   set no-payload option\n"
+                       "  -r:   use raw\n"
+                       "  -R:   use raw (IP_HDRINCL)\n"
+                       "  -p N: connect to port N\n"
+                       "  -u:   use udp\n"
+                       "  -x:   show payload (up to 70 bytes)\n",
+                       filepath);
+       exit(1);
+}
+
+static void parse_opt(int argc, char **argv)
+{
+       int proto_count = 0;
+       char c;
+
+       while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) {
+               switch (c) {
+               case '4':
+                       do_ipv6 = 0;
+                       break;
+               case '6':
+                       do_ipv4 = 0;
+                       break;
+               case 'I':
+                       cfg_do_pktinfo = true;
+                       break;
+               case 'n':
+                       cfg_loop_nodata = true;
+                       break;
+               case 'r':
+                       proto_count++;
+                       cfg_proto = SOCK_RAW;
+                       cfg_ipproto = IPPROTO_UDP;
+                       break;
+               case 'R':
+                       proto_count++;
+                       cfg_proto = SOCK_RAW;
+                       cfg_ipproto = IPPROTO_RAW;
+                       break;
+               case 'u':
+                       proto_count++;
+                       cfg_proto = SOCK_DGRAM;
+                       cfg_ipproto = IPPROTO_UDP;
+                       break;
+               case 'l':
+                       cfg_payload_len = strtoul(optarg, NULL, 10);
+                       break;
+               case 'p':
+                       dest_port = strtoul(optarg, NULL, 10);
+                       break;
+               case 'x':
+                       cfg_show_payload = true;
+                       break;
+               case 'h':
+               default:
+                       usage(argv[0]);
+               }
+       }
+
+       if (!cfg_payload_len)
+               error(1, 0, "payload may not be nonzero");
+       if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472)
+               error(1, 0, "udp packet might exceed expected MTU");
+       if (!do_ipv4 && !do_ipv6)
+               error(1, 0, "pass -4 or -6, not both");
+       if (proto_count > 1)
+               error(1, 0, "pass -r, -R or -u, not multiple");
+
+       if (optind != argc - 1)
+               error(1, 0, "missing required hostname argument");
+}
+
+static void resolve_hostname(const char *hostname)
+{
+       struct addrinfo *addrs, *cur;
+       int have_ipv4 = 0, have_ipv6 = 0;
+
+       if (getaddrinfo(hostname, NULL, NULL, &addrs))
+               error(1, errno, "getaddrinfo");
+
+       cur = addrs;
+       while (cur && !have_ipv4 && !have_ipv6) {
+               if (!have_ipv4 && cur->ai_family == AF_INET) {
+                       memcpy(&daddr, cur->ai_addr, sizeof(daddr));
+                       daddr.sin_port = htons(dest_port);
+                       have_ipv4 = 1;
+               }
+               else if (!have_ipv6 && cur->ai_family == AF_INET6) {
+                       memcpy(&daddr6, cur->ai_addr, sizeof(daddr6));
+                       daddr6.sin6_port = htons(dest_port);
+                       have_ipv6 = 1;
+               }
+               cur = cur->ai_next;
+       }
+       if (addrs)
+               freeaddrinfo(addrs);
+
+       do_ipv4 &= have_ipv4;
+       do_ipv6 &= have_ipv6;
+}
+
+static void do_main(int family)
+{
+       fprintf(stderr, "family:       %s\n",
+                       family == PF_INET ? "INET" : "INET6");
+
+       fprintf(stderr, "test SND\n");
+       do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE);
+
+       fprintf(stderr, "test ENQ\n");
+       do_test(family, SOF_TIMESTAMPING_TX_SCHED);
+
+       fprintf(stderr, "test ENQ + SND\n");
+       do_test(family, SOF_TIMESTAMPING_TX_SCHED |
+                       SOF_TIMESTAMPING_TX_SOFTWARE);
+
+       if (cfg_proto == SOCK_STREAM) {
+               fprintf(stderr, "\ntest ACK\n");
+               do_test(family, SOF_TIMESTAMPING_TX_ACK);
+
+               fprintf(stderr, "\ntest SND + ACK\n");
+               do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE |
+                               SOF_TIMESTAMPING_TX_ACK);
+
+               fprintf(stderr, "\ntest ENQ + SND + ACK\n");
+               do_test(family, SOF_TIMESTAMPING_TX_SCHED |
+                               SOF_TIMESTAMPING_TX_SOFTWARE |
+                               SOF_TIMESTAMPING_TX_ACK);
+       }
+}
+
+const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" };
+
+int main(int argc, char **argv)
+{
+       if (argc == 1)
+               usage(argv[0]);
+
+       parse_opt(argc, argv);
+       resolve_hostname(argv[argc - 1]);
+
+       fprintf(stderr, "protocol:     %s\n", sock_names[cfg_proto]);
+       fprintf(stderr, "payload:      %u\n", cfg_payload_len);
+       fprintf(stderr, "server port:  %u\n", dest_port);
+       fprintf(stderr, "\n");
+
+       if (do_ipv4)
+               do_main(PF_INET);
+       if (do_ipv6)
+               do_main(PF_INET6);
+
+       return 0;
+}
diff --git a/tools/testing/selftests/prctl/.gitignore b/tools/testing/selftests/prctl/.gitignore
new file mode 100644 (file)
index 0000000..0b5c274
--- /dev/null
@@ -0,0 +1,3 @@
+disable-tsc-ctxt-sw-stress-test
+disable-tsc-on-off-stress-test
+disable-tsc-test
diff --git a/tools/testing/selftests/prctl/Makefile b/tools/testing/selftests/prctl/Makefile
new file mode 100644 (file)
index 0000000..35aa1c8
--- /dev/null
@@ -0,0 +1,15 @@
+ifndef CROSS_COMPILE
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \
+               disable-tsc-test
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
+endif
+endif
diff --git a/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c
new file mode 100644 (file)
index 0000000..f7499d1
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Tests if the control register is updated correctly
+ * at context switches
+ *
+ * Warning: this test will cause a very high load for a few seconds
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <wait.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+static void sigsegv_expect(int sig)
+{
+       /* */
+}
+
+static void segvtask(void)
+{
+       if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
+       {
+               perror("prctl");
+               exit(0);
+       }
+       signal(SIGSEGV, sigsegv_expect);
+       alarm(10);
+       rdtsc();
+       fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
+       exit(0);
+}
+
+
+static void sigsegv_fail(int sig)
+{
+       fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
+       exit(0);
+}
+
+static void rdtsctask(void)
+{
+       if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
+       {
+               perror("prctl");
+               exit(0);
+       }
+       signal(SIGSEGV, sigsegv_fail);
+       alarm(10);
+       for(;;) rdtsc();
+}
+
+
+int main(void)
+{
+       int n_tasks = 100, i;
+
+       fprintf(stderr, "[No further output means we're allright]\n");
+
+       for (i=0; i<n_tasks; i++)
+               if (fork() == 0)
+               {
+                       if (i & 1)
+                               segvtask();
+                       else
+                               rdtsctask();
+               }
+
+       for (i=0; i<n_tasks; i++)
+               wait(NULL);
+
+       exit(0);
+}
+
diff --git a/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c
new file mode 100644 (file)
index 0000000..a06f027
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Tests if the control register is updated correctly
+ * when set with prctl()
+ *
+ * Warning: this test will cause a very high load for a few seconds
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <wait.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+/* snippet from wikipedia :-) */
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+int should_segv = 0;
+
+static void sigsegv_cb(int sig)
+{
+       if (!should_segv)
+       {
+               fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
+               exit(0);
+       }
+       if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
+       {
+               perror("prctl");
+               exit(0);
+       }
+       should_segv = 0;
+
+       rdtsc();
+}
+
+static void task(void)
+{
+       signal(SIGSEGV, sigsegv_cb);
+       alarm(10);
+       for(;;)
+       {
+               rdtsc();
+               if (should_segv)
+               {
+                       fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
+                       exit(0);
+               }
+               if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
+               {
+                       perror("prctl");
+                       exit(0);
+               }
+               should_segv = 1;
+       }
+}
+
+
+int main(void)
+{
+       int n_tasks = 100, i;
+
+       fprintf(stderr, "[No further output means we're allright]\n");
+
+       for (i=0; i<n_tasks; i++)
+               if (fork() == 0)
+                       task();
+
+       for (i=0; i<n_tasks; i++)
+               wait(NULL);
+
+       exit(0);
+}
+
diff --git a/tools/testing/selftests/prctl/disable-tsc-test.c b/tools/testing/selftests/prctl/disable-tsc-test.c
new file mode 100644 (file)
index 0000000..8d494f7
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE         1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+const char *tsc_names[] =
+{
+       [0] = "[not set]",
+       [PR_TSC_ENABLE] = "PR_TSC_ENABLE",
+       [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
+};
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+static void sigsegv_cb(int sig)
+{
+       int tsc_val = 0;
+
+       printf("[ SIG_SEGV ]\n");
+       printf("prctl(PR_GET_TSC, &tsc_val); ");
+       fflush(stdout);
+
+       if ( prctl(PR_GET_TSC, &tsc_val) == -1)
+               perror("prctl");
+
+       printf("tsc_val == %s\n", tsc_names[tsc_val]);
+       printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
+       fflush(stdout);
+       if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
+               perror("prctl");
+
+       printf("rdtsc() == ");
+}
+
+int main(void)
+{
+       int tsc_val = 0;
+
+       signal(SIGSEGV, sigsegv_cb);
+
+       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+       printf("prctl(PR_GET_TSC, &tsc_val); ");
+       fflush(stdout);
+
+       if ( prctl(PR_GET_TSC, &tsc_val) == -1)
+               perror("prctl");
+
+       printf("tsc_val == %s\n", tsc_names[tsc_val]);
+       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+       printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
+       fflush(stdout);
+
+       if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
+               perror("prctl");
+
+       printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+       printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
+       fflush(stdout);
+
+       if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
+               perror("prctl");
+
+       printf("rdtsc() == ");
+       fflush(stdout);
+       printf("%llu\n", (unsigned long long)rdtsc());
+       fflush(stdout);
+
+       exit(EXIT_SUCCESS);
+}
+
diff --git a/tools/testing/selftests/ptp/.gitignore b/tools/testing/selftests/ptp/.gitignore
new file mode 100644 (file)
index 0000000..f562e49
--- /dev/null
@@ -0,0 +1 @@
+testptp
diff --git a/tools/testing/selftests/ptp/Makefile b/tools/testing/selftests/ptp/Makefile
new file mode 100644 (file)
index 0000000..83dd42b
--- /dev/null
@@ -0,0 +1,8 @@
+TEST_PROGS := testptp
+LDLIBS += -lrt
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
new file mode 100644 (file)
index 0000000..5d2eae1
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * PTP 1588 clock support - User space test program
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define _GNU_SOURCE
+#define __SANE_USERSPACE_TYPES__        /* For PPC64, to get LL64 types */
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/ptp_clock.h>
+
+#define DEVICE "/dev/ptp0"
+
+#ifndef ADJ_SETOFFSET
+#define ADJ_SETOFFSET 0x0100
+#endif
+
+#ifndef CLOCK_INVALID
+#define CLOCK_INVALID -1
+#endif
+
+/* clock_adjtime is not available in GLIBC < 2.14 */
+#if !__GLIBC_PREREQ(2, 14)
+#include <sys/syscall.h>
+static int clock_adjtime(clockid_t id, struct timex *tx)
+{
+       return syscall(__NR_clock_adjtime, id, tx);
+}
+#endif
+
+static clockid_t get_clockid(int fd)
+{
+#define CLOCKFD 3
+#define FD_TO_CLOCKID(fd)      ((~(clockid_t) (fd) << 3) | CLOCKFD)
+
+       return FD_TO_CLOCKID(fd);
+}
+
+static void handle_alarm(int s)
+{
+       printf("received signal %d\n", s);
+}
+
+static int install_handler(int signum, void (*handler)(int))
+{
+       struct sigaction action;
+       sigset_t mask;
+
+       /* Unblock the signal. */
+       sigemptyset(&mask);
+       sigaddset(&mask, signum);
+       sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+       /* Install the signal handler. */
+       action.sa_handler = handler;
+       action.sa_flags = 0;
+       sigemptyset(&action.sa_mask);
+       sigaction(signum, &action, NULL);
+
+       return 0;
+}
+
+static long ppb_to_scaled_ppm(int ppb)
+{
+       /*
+        * The 'freq' field in the 'struct timex' is in parts per
+        * million, but with a 16 bit binary fractional field.
+        * Instead of calculating either one of
+        *
+        *    scaled_ppm = (ppb / 1000) << 16  [1]
+        *    scaled_ppm = (ppb << 16) / 1000  [2]
+        *
+        * we simply use double precision math, in order to avoid the
+        * truncation in [1] and the possible overflow in [2].
+        */
+       return (long) (ppb * 65.536);
+}
+
+static int64_t pctns(struct ptp_clock_time *t)
+{
+       return t->sec * 1000000000LL + t->nsec;
+}
+
+static void usage(char *progname)
+{
+       fprintf(stderr,
+               "usage: %s [options]\n"
+               " -a val     request a one-shot alarm after 'val' seconds\n"
+               " -A val     request a periodic alarm every 'val' seconds\n"
+               " -c         query the ptp clock's capabilities\n"
+               " -d name    device to open\n"
+               " -e val     read 'val' external time stamp events\n"
+               " -f val     adjust the ptp clock frequency by 'val' ppb\n"
+               " -g         get the ptp clock time\n"
+               " -h         prints this message\n"
+               " -i val     index for event/trigger\n"
+               " -k val     measure the time offset between system and phc clock\n"
+               "            for 'val' times (Maximum 25)\n"
+               " -l         list the current pin configuration\n"
+               " -L pin,val configure pin index 'pin' with function 'val'\n"
+               "            the channel index is taken from the '-i' option\n"
+               "            'val' specifies the auxiliary function:\n"
+               "            0 - none\n"
+               "            1 - external time stamp\n"
+               "            2 - periodic output\n"
+               " -p val     enable output with a period of 'val' nanoseconds\n"
+               " -P val     enable or disable (val=1|0) the system clock PPS\n"
+               " -s         set the ptp clock time from the system time\n"
+               " -S         set the system time from the ptp clock time\n"
+               " -t val     shift the ptp clock time by 'val' seconds\n"
+               " -T val     set the ptp clock time to 'val' seconds\n",
+               progname);
+}
+
+int main(int argc, char *argv[])
+{
+       struct ptp_clock_caps caps;
+       struct ptp_extts_event event;
+       struct ptp_extts_request extts_request;
+       struct ptp_perout_request perout_request;
+       struct ptp_pin_desc desc;
+       struct timespec ts;
+       struct timex tx;
+
+       static timer_t timerid;
+       struct itimerspec timeout;
+       struct sigevent sigevent;
+
+       struct ptp_clock_time *pct;
+       struct ptp_sys_offset *sysoff;
+
+
+       char *progname;
+       unsigned int i;
+       int c, cnt, fd;
+
+       char *device = DEVICE;
+       clockid_t clkid;
+       int adjfreq = 0x7fffffff;
+       int adjtime = 0;
+       int capabilities = 0;
+       int extts = 0;
+       int gettime = 0;
+       int index = 0;
+       int list_pins = 0;
+       int oneshot = 0;
+       int pct_offset = 0;
+       int n_samples = 0;
+       int periodic = 0;
+       int perout = -1;
+       int pin_index = -1, pin_func;
+       int pps = -1;
+       int seconds = 0;
+       int settime = 0;
+
+       int64_t t1, t2, tp;
+       int64_t interval, offset;
+
+       progname = strrchr(argv[0], '/');
+       progname = progname ? 1+progname : argv[0];
+       while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:T:v"))) {
+               switch (c) {
+               case 'a':
+                       oneshot = atoi(optarg);
+                       break;
+               case 'A':
+                       periodic = atoi(optarg);
+                       break;
+               case 'c':
+                       capabilities = 1;
+                       break;
+               case 'd':
+                       device = optarg;
+                       break;
+               case 'e':
+                       extts = atoi(optarg);
+                       break;
+               case 'f':
+                       adjfreq = atoi(optarg);
+                       break;
+               case 'g':
+                       gettime = 1;
+                       break;
+               case 'i':
+                       index = atoi(optarg);
+                       break;
+               case 'k':
+                       pct_offset = 1;
+                       n_samples = atoi(optarg);
+                       break;
+               case 'l':
+                       list_pins = 1;
+                       break;
+               case 'L':
+                       cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func);
+                       if (cnt != 2) {
+                               usage(progname);
+                               return -1;
+                       }
+                       break;
+               case 'p':
+                       perout = atoi(optarg);
+                       break;
+               case 'P':
+                       pps = atoi(optarg);
+                       break;
+               case 's':
+                       settime = 1;
+                       break;
+               case 'S':
+                       settime = 2;
+                       break;
+               case 't':
+                       adjtime = atoi(optarg);
+                       break;
+               case 'T':
+                       settime = 3;
+                       seconds = atoi(optarg);
+                       break;
+               case 'h':
+                       usage(progname);
+                       return 0;
+               case '?':
+               default:
+                       usage(progname);
+                       return -1;
+               }
+       }
+
+       fd = open(device, O_RDWR);
+       if (fd < 0) {
+               fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+               return -1;
+       }
+
+       clkid = get_clockid(fd);
+       if (CLOCK_INVALID == clkid) {
+               fprintf(stderr, "failed to read clock id\n");
+               return -1;
+       }
+
+       if (capabilities) {
+               if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+                       perror("PTP_CLOCK_GETCAPS");
+               } else {
+                       printf("capabilities:\n"
+                              "  %d maximum frequency adjustment (ppb)\n"
+                              "  %d programmable alarms\n"
+                              "  %d external time stamp channels\n"
+                              "  %d programmable periodic signals\n"
+                              "  %d pulse per second\n"
+                              "  %d programmable pins\n"
+                              "  %d cross timestamping\n",
+                              caps.max_adj,
+                              caps.n_alarm,
+                              caps.n_ext_ts,
+                              caps.n_per_out,
+                              caps.pps,
+                              caps.n_pins,
+                              caps.cross_timestamping);
+               }
+       }
+
+       if (0x7fffffff != adjfreq) {
+               memset(&tx, 0, sizeof(tx));
+               tx.modes = ADJ_FREQUENCY;
+               tx.freq = ppb_to_scaled_ppm(adjfreq);
+               if (clock_adjtime(clkid, &tx)) {
+                       perror("clock_adjtime");
+               } else {
+                       puts("frequency adjustment okay");
+               }
+       }
+
+       if (adjtime) {
+               memset(&tx, 0, sizeof(tx));
+               tx.modes = ADJ_SETOFFSET;
+               tx.time.tv_sec = adjtime;
+               tx.time.tv_usec = 0;
+               if (clock_adjtime(clkid, &tx) < 0) {
+                       perror("clock_adjtime");
+               } else {
+                       puts("time shift okay");
+               }
+       }
+
+       if (gettime) {
+               if (clock_gettime(clkid, &ts)) {
+                       perror("clock_gettime");
+               } else {
+                       printf("clock time: %ld.%09ld or %s",
+                              ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec));
+               }
+       }
+
+       if (settime == 1) {
+               clock_gettime(CLOCK_REALTIME, &ts);
+               if (clock_settime(clkid, &ts)) {
+                       perror("clock_settime");
+               } else {
+                       puts("set time okay");
+               }
+       }
+
+       if (settime == 2) {
+               clock_gettime(clkid, &ts);
+               if (clock_settime(CLOCK_REALTIME, &ts)) {
+                       perror("clock_settime");
+               } else {
+                       puts("set time okay");
+               }
+       }
+
+       if (settime == 3) {
+               ts.tv_sec = seconds;
+               ts.tv_nsec = 0;
+               if (clock_settime(clkid, &ts)) {
+                       perror("clock_settime");
+               } else {
+                       puts("set time okay");
+               }
+       }
+
+       if (extts) {
+               memset(&extts_request, 0, sizeof(extts_request));
+               extts_request.index = index;
+               extts_request.flags = PTP_ENABLE_FEATURE;
+               if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+                       perror("PTP_EXTTS_REQUEST");
+                       extts = 0;
+               } else {
+                       puts("external time stamp request okay");
+               }
+               for (; extts; extts--) {
+                       cnt = read(fd, &event, sizeof(event));
+                       if (cnt != sizeof(event)) {
+                               perror("read");
+                               break;
+                       }
+                       printf("event index %u at %lld.%09u\n", event.index,
+                              event.t.sec, event.t.nsec);
+                       fflush(stdout);
+               }
+               /* Disable the feature again. */
+               extts_request.flags = 0;
+               if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+                       perror("PTP_EXTTS_REQUEST");
+               }
+       }
+
+       if (list_pins) {
+               int n_pins = 0;
+               if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+                       perror("PTP_CLOCK_GETCAPS");
+               } else {
+                       n_pins = caps.n_pins;
+               }
+               for (i = 0; i < n_pins; i++) {
+                       desc.index = i;
+                       if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) {
+                               perror("PTP_PIN_GETFUNC");
+                               break;
+                       }
+                       printf("name %s index %u func %u chan %u\n",
+                              desc.name, desc.index, desc.func, desc.chan);
+               }
+       }
+
+       if (oneshot) {
+               install_handler(SIGALRM, handle_alarm);
+               /* Create a timer. */
+               sigevent.sigev_notify = SIGEV_SIGNAL;
+               sigevent.sigev_signo = SIGALRM;
+               if (timer_create(clkid, &sigevent, &timerid)) {
+                       perror("timer_create");
+                       return -1;
+               }
+               /* Start the timer. */
+               memset(&timeout, 0, sizeof(timeout));
+               timeout.it_value.tv_sec = oneshot;
+               if (timer_settime(timerid, 0, &timeout, NULL)) {
+                       perror("timer_settime");
+                       return -1;
+               }
+               pause();
+               timer_delete(timerid);
+       }
+
+       if (periodic) {
+               install_handler(SIGALRM, handle_alarm);
+               /* Create a timer. */
+               sigevent.sigev_notify = SIGEV_SIGNAL;
+               sigevent.sigev_signo = SIGALRM;
+               if (timer_create(clkid, &sigevent, &timerid)) {
+                       perror("timer_create");
+                       return -1;
+               }
+               /* Start the timer. */
+               memset(&timeout, 0, sizeof(timeout));
+               timeout.it_interval.tv_sec = periodic;
+               timeout.it_value.tv_sec = periodic;
+               if (timer_settime(timerid, 0, &timeout, NULL)) {
+                       perror("timer_settime");
+                       return -1;
+               }
+               while (1) {
+                       pause();
+               }
+               timer_delete(timerid);
+       }
+
+       if (perout >= 0) {
+               if (clock_gettime(clkid, &ts)) {
+                       perror("clock_gettime");
+                       return -1;
+               }
+               memset(&perout_request, 0, sizeof(perout_request));
+               perout_request.index = index;
+               perout_request.start.sec = ts.tv_sec + 2;
+               perout_request.start.nsec = 0;
+               perout_request.period.sec = 0;
+               perout_request.period.nsec = perout;
+               if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) {
+                       perror("PTP_PEROUT_REQUEST");
+               } else {
+                       puts("periodic output request okay");
+               }
+       }
+
+       if (pin_index >= 0) {
+               memset(&desc, 0, sizeof(desc));
+               desc.index = pin_index;
+               desc.func = pin_func;
+               desc.chan = index;
+               if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) {
+                       perror("PTP_PIN_SETFUNC");
+               } else {
+                       puts("set pin function okay");
+               }
+       }
+
+       if (pps != -1) {
+               int enable = pps ? 1 : 0;
+               if (ioctl(fd, PTP_ENABLE_PPS, enable)) {
+                       perror("PTP_ENABLE_PPS");
+               } else {
+                       puts("pps for system time request okay");
+               }
+       }
+
+       if (pct_offset) {
+               if (n_samples <= 0 || n_samples > 25) {
+                       puts("n_samples should be between 1 and 25");
+                       usage(progname);
+                       return -1;
+               }
+
+               sysoff = calloc(1, sizeof(*sysoff));
+               if (!sysoff) {
+                       perror("calloc");
+                       return -1;
+               }
+               sysoff->n_samples = n_samples;
+
+               if (ioctl(fd, PTP_SYS_OFFSET, sysoff))
+                       perror("PTP_SYS_OFFSET");
+               else
+                       puts("system and phc clock time offset request okay");
+
+               pct = &sysoff->ts[0];
+               for (i = 0; i < sysoff->n_samples; i++) {
+                       t1 = pctns(pct+2*i);
+                       tp = pctns(pct+2*i+1);
+                       t2 = pctns(pct+2*i+2);
+                       interval = t2 - t1;
+                       offset = (t2 + t1) / 2 - tp;
+
+                       printf("system time: %lld.%u\n",
+                               (pct+2*i)->sec, (pct+2*i)->nsec);
+                       printf("phc    time: %lld.%u\n",
+                               (pct+2*i+1)->sec, (pct+2*i+1)->nsec);
+                       printf("system time: %lld.%u\n",
+                               (pct+2*i+2)->sec, (pct+2*i+2)->nsec);
+                       printf("system/phc clock time offset is %" PRId64 " ns\n"
+                              "system     clock time delay  is %" PRId64 " ns\n",
+                               offset, interval);
+               }
+
+               free(sysoff);
+       }
+
+       close(fd);
+       return 0;
+}
diff --git a/tools/testing/selftests/ptp/testptp.mk b/tools/testing/selftests/ptp/testptp.mk
new file mode 100644 (file)
index 0000000..4ef2d97
--- /dev/null
@@ -0,0 +1,33 @@
+# PTP 1588 clock support - User space test program
+#
+# Copyright (C) 2010 OMICRON electronics GmbH
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CC        = $(CROSS_COMPILE)gcc
+INC       = -I$(KBUILD_OUTPUT)/usr/include
+CFLAGS    = -Wall $(INC)
+LDLIBS    = -lrt
+PROGS     = testptp
+
+all: $(PROGS)
+
+testptp: testptp.o
+
+clean:
+       rm -f testptp.o
+
+distclean: clean
+       rm -f $(PROGS)
index 5a246a0..15cf56d 100644 (file)
@@ -122,7 +122,7 @@ static int check_itimer(int which)
        else if (which == ITIMER_REAL)
                idle_loop();
 
-       gettimeofday(&end, NULL);
+       err = gettimeofday(&end, NULL);
        if (err < 0) {
                perror("Can't call gettimeofday()\n");
                return -1;
@@ -175,7 +175,7 @@ static int check_timer_create(int which)
 
        user_loop();
 
-       gettimeofday(&end, NULL);
+       err = gettimeofday(&end, NULL);
        if (err < 0) {
                perror("Can't call gettimeofday()\n");
                return -1;
diff --git a/tools/testing/selftests/vDSO/.gitignore b/tools/testing/selftests/vDSO/.gitignore
new file mode 100644 (file)
index 0000000..133bf9e
--- /dev/null
@@ -0,0 +1,2 @@
+vdso_test
+vdso_standalone_test_x86
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
new file mode 100644 (file)
index 0000000..706b68b
--- /dev/null
@@ -0,0 +1,20 @@
+ifndef CROSS_COMPILE
+CFLAGS := -std=gnu99
+CFLAGS_vdso_standalone_test_x86 := -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector
+ifeq ($(CONFIG_X86_32),y)
+LDLIBS += -lgcc_s
+endif
+
+TEST_PROGS := vdso_test vdso_standalone_test_x86
+
+all: $(TEST_PROGS)
+vdso_test: parse_vdso.c vdso_test.c
+vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
+       $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
+               vdso_standalone_test_x86.c parse_vdso.c \
+               -o vdso_standalone_test_x86
+
+include ../lib.mk
+clean:
+       rm -fr $(TEST_PROGS)
+endif
diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
new file mode 100644 (file)
index 0000000..1dbb4b8
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * parse_vdso.c: Linux reference vDSO parser
+ * Written by Andrew Lutomirski, 2011-2014.
+ *
+ * This code is meant to be linked in to various programs that run on Linux.
+ * As such, it is available with as few restrictions as possible.  This file
+ * is licensed under the Creative Commons Zero License, version 1.0,
+ * available at http://creativecommons.org/publicdomain/zero/1.0/legalcode
+ *
+ * The vDSO is a regular ELF DSO that the kernel maps into user space when
+ * it starts a program.  It works equally well in statically and dynamically
+ * linked binaries.
+ *
+ * This code is tested on x86.  In principle it should work on any
+ * architecture that has a vDSO.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <elf.h>
+
+/*
+ * To use this vDSO parser, first call one of the vdso_init_* functions.
+ * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
+ * to vdso_init_from_sysinfo_ehdr.  Otherwise pass auxv to vdso_init_from_auxv.
+ * Then call vdso_sym for each symbol you want.  For example, to look up
+ * gettimeofday on x86_64, use:
+ *
+ *     <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
+ * or
+ *     <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+ *
+ * vdso_sym will return 0 if the symbol doesn't exist or if the init function
+ * failed or was not called.  vdso_sym is a little slow, so its return value
+ * should be cached.
+ *
+ * vdso_sym is threadsafe; the init functions are not.
+ *
+ * These are the prototypes:
+ */
+extern void vdso_init_from_auxv(void *auxv);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void *vdso_sym(const char *version, const char *name);
+
+
+/* And here's the code. */
+#ifndef ELF_BITS
+# if ULONG_MAX > 0xffffffffUL
+#  define ELF_BITS 64
+# else
+#  define ELF_BITS 32
+# endif
+#endif
+
+#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
+#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
+#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
+
+static struct vdso_info
+{
+       bool valid;
+
+       /* Load information */
+       uintptr_t load_addr;
+       uintptr_t load_offset;  /* load_addr - recorded vaddr */
+
+       /* Symbol table */
+       ELF(Sym) *symtab;
+       const char *symstrings;
+       ELF(Word) *bucket, *chain;
+       ELF(Word) nbucket, nchain;
+
+       /* Version table */
+       ELF(Versym) *versym;
+       ELF(Verdef) *verdef;
+} vdso_info;
+
+/* Straight from the ELF specification. */
+static unsigned long elf_hash(const unsigned char *name)
+{
+       unsigned long h = 0, g;
+       while (*name)
+       {
+               h = (h << 4) + *name++;
+               if (g = h & 0xf0000000)
+                       h ^= g >> 24;
+               h &= ~g;
+       }
+       return h;
+}
+
+void vdso_init_from_sysinfo_ehdr(uintptr_t base)
+{
+       size_t i;
+       bool found_vaddr = false;
+
+       vdso_info.valid = false;
+
+       vdso_info.load_addr = base;
+
+       ELF(Ehdr) *hdr = (ELF(Ehdr)*)base;
+       if (hdr->e_ident[EI_CLASS] !=
+           (ELF_BITS == 32 ? ELFCLASS32 : ELFCLASS64)) {
+               return;  /* Wrong ELF class -- check ELF_BITS */
+       }
+
+       ELF(Phdr) *pt = (ELF(Phdr)*)(vdso_info.load_addr + hdr->e_phoff);
+       ELF(Dyn) *dyn = 0;
+
+       /*
+        * We need two things from the segment table: the load offset
+        * and the dynamic table.
+        */
+       for (i = 0; i < hdr->e_phnum; i++)
+       {
+               if (pt[i].p_type == PT_LOAD && !found_vaddr) {
+                       found_vaddr = true;
+                       vdso_info.load_offset = base
+                               + (uintptr_t)pt[i].p_offset
+                               - (uintptr_t)pt[i].p_vaddr;
+               } else if (pt[i].p_type == PT_DYNAMIC) {
+                       dyn = (ELF(Dyn)*)(base + pt[i].p_offset);
+               }
+       }
+
+       if (!found_vaddr || !dyn)
+               return;  /* Failed */
+
+       /*
+        * Fish out the useful bits of the dynamic table.
+        */
+       ELF(Word) *hash = 0;
+       vdso_info.symstrings = 0;
+       vdso_info.symtab = 0;
+       vdso_info.versym = 0;
+       vdso_info.verdef = 0;
+       for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
+               switch (dyn[i].d_tag) {
+               case DT_STRTAB:
+                       vdso_info.symstrings = (const char *)
+                               ((uintptr_t)dyn[i].d_un.d_ptr
+                                + vdso_info.load_offset);
+                       break;
+               case DT_SYMTAB:
+                       vdso_info.symtab = (ELF(Sym) *)
+                               ((uintptr_t)dyn[i].d_un.d_ptr
+                                + vdso_info.load_offset);
+                       break;
+               case DT_HASH:
+                       hash = (ELF(Word) *)
+                               ((uintptr_t)dyn[i].d_un.d_ptr
+                                + vdso_info.load_offset);
+                       break;
+               case DT_VERSYM:
+                       vdso_info.versym = (ELF(Versym) *)
+                               ((uintptr_t)dyn[i].d_un.d_ptr
+                                + vdso_info.load_offset);
+                       break;
+               case DT_VERDEF:
+                       vdso_info.verdef = (ELF(Verdef) *)
+                               ((uintptr_t)dyn[i].d_un.d_ptr
+                                + vdso_info.load_offset);
+                       break;
+               }
+       }
+       if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
+               return;  /* Failed */
+
+       if (!vdso_info.verdef)
+               vdso_info.versym = 0;
+
+       /* Parse the hash table header. */
+       vdso_info.nbucket = hash[0];
+       vdso_info.nchain = hash[1];
+       vdso_info.bucket = &hash[2];
+       vdso_info.chain = &hash[vdso_info.nbucket + 2];
+
+       /* That's all we need. */
+       vdso_info.valid = true;
+}
+
+static bool vdso_match_version(ELF(Versym) ver,
+                              const char *name, ELF(Word) hash)
+{
+       /*
+        * This is a helper function to check if the version indexed by
+        * ver matches name (which hashes to hash).
+        *
+        * The version definition table is a mess, and I don't know how
+        * to do this in better than linear time without allocating memory
+        * to build an index.  I also don't know why the table has
+        * variable size entries in the first place.
+        *
+        * For added fun, I can't find a comprehensible specification of how
+        * to parse all the weird flags in the table.
+        *
+        * So I just parse the whole table every time.
+        */
+
+       /* First step: find the version definition */
+       ver &= 0x7fff;  /* Apparently bit 15 means "hidden" */
+       ELF(Verdef) *def = vdso_info.verdef;
+       while(true) {
+               if ((def->vd_flags & VER_FLG_BASE) == 0
+                   && (def->vd_ndx & 0x7fff) == ver)
+                       break;
+
+               if (def->vd_next == 0)
+                       return false;  /* No definition. */
+
+               def = (ELF(Verdef) *)((char *)def + def->vd_next);
+       }
+
+       /* Now figure out whether it matches. */
+       ELF(Verdaux) *aux = (ELF(Verdaux)*)((char *)def + def->vd_aux);
+       return def->vd_hash == hash
+               && !strcmp(name, vdso_info.symstrings + aux->vda_name);
+}
+
+void *vdso_sym(const char *version, const char *name)
+{
+       unsigned long ver_hash;
+       if (!vdso_info.valid)
+               return 0;
+
+       ver_hash = elf_hash(version);
+       ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
+
+       for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
+               ELF(Sym) *sym = &vdso_info.symtab[chain];
+
+               /* Check for a defined global or weak function w/ right name. */
+               if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+                       continue;
+               if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+                   ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+                       continue;
+               if (sym->st_shndx == SHN_UNDEF)
+                       continue;
+               if (strcmp(name, vdso_info.symstrings + sym->st_name))
+                       continue;
+
+               /* Check symbol version. */
+               if (vdso_info.versym
+                   && !vdso_match_version(vdso_info.versym[chain],
+                                          version, ver_hash))
+                       continue;
+
+               return (void *)(vdso_info.load_offset + sym->st_value);
+       }
+
+       return 0;
+}
+
+void vdso_init_from_auxv(void *auxv)
+{
+       ELF(auxv_t) *elf_auxv = auxv;
+       for (int i = 0; elf_auxv[i].a_type != AT_NULL; i++)
+       {
+               if (elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
+                       vdso_init_from_sysinfo_ehdr(elf_auxv[i].a_un.a_val);
+                       return;
+               }
+       }
+
+       vdso_info.valid = false;
+}
diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
new file mode 100644 (file)
index 0000000..93b0ebf
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * vdso_test.c: Sample code to test parse_vdso.c on x86
+ * Copyright (c) 2011-2014 Andy Lutomirski
+ * Subject to the GNU General Public License, version 2
+ *
+ * You can amuse yourself by compiling with:
+ * gcc -std=gnu99 -nostdlib
+ *     -Os -fno-asynchronous-unwind-tables -flto -lgcc_s
+ *      vdso_standalone_test_x86.c parse_vdso.c
+ * to generate a small binary.  On x86_64, you can omit -lgcc_s
+ * if you want the binary to be completely standalone.
+ */
+
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdint.h>
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+/* We need a libc functions... */
+int strcmp(const char *a, const char *b)
+{
+       /* This implementation is buggy: it never returns -1. */
+       while (*a || *b) {
+               if (*a != *b)
+                       return 1;
+               if (*a == 0 || *b == 0)
+                       return 1;
+               a++;
+               b++;
+       }
+
+       return 0;
+}
+
+/* ...and two syscalls.  This is x86-specific. */
+static inline long x86_syscall3(long nr, long a0, long a1, long a2)
+{
+       long ret;
+#ifdef __x86_64__
+       asm volatile ("syscall" : "=a" (ret) : "a" (nr),
+                     "D" (a0), "S" (a1), "d" (a2) :
+                     "cc", "memory", "rcx",
+                     "r8", "r9", "r10", "r11" );
+#else
+       asm volatile ("int $0x80" : "=a" (ret) : "a" (nr),
+                     "b" (a0), "c" (a1), "d" (a2) :
+                     "cc", "memory" );
+#endif
+       return ret;
+}
+
+static inline long linux_write(int fd, const void *data, size_t len)
+{
+       return x86_syscall3(__NR_write, fd, (long)data, (long)len);
+}
+
+static inline void linux_exit(int code)
+{
+       x86_syscall3(__NR_exit, code, 0, 0);
+}
+
+void to_base10(char *lastdig, time_t n)
+{
+       while (n) {
+               *lastdig = (n % 10) + '0';
+               n /= 10;
+               lastdig--;
+       }
+}
+
+__attribute__((externally_visible)) void c_main(void **stack)
+{
+       /* Parse the stack */
+       long argc = (long)*stack;
+       stack += argc + 2;
+
+       /* Now we're pointing at the environment.  Skip it. */
+       while(*stack)
+               stack++;
+       stack++;
+
+       /* Now we're pointing at auxv.  Initialize the vDSO parser. */
+       vdso_init_from_auxv((void *)stack);
+
+       /* Find gettimeofday. */
+       typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
+       gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+
+       if (!gtod)
+               linux_exit(1);
+
+       struct timeval tv;
+       long ret = gtod(&tv, 0);
+
+       if (ret == 0) {
+               char buf[] = "The time is                     .000000\n";
+               to_base10(buf + 31, tv.tv_sec);
+               to_base10(buf + 38, tv.tv_usec);
+               linux_write(1, buf, sizeof(buf) - 1);
+       } else {
+               linux_exit(ret);
+       }
+
+       linux_exit(0);
+}
+
+/*
+ * This is the real entry point.  It passes the initial stack into
+ * the C entry point.
+ */
+asm (
+       ".text\n"
+       ".global _start\n"
+       ".type _start,@function\n"
+       "_start:\n\t"
+#ifdef __x86_64__
+       "mov %rsp,%rdi\n\t"
+       "jmp c_main"
+#else
+       "push %esp\n\t"
+       "call c_main\n\t"
+       "int $3"
+#endif
+       );
diff --git a/tools/testing/selftests/vDSO/vdso_test.c b/tools/testing/selftests/vDSO/vdso_test.c
new file mode 100644 (file)
index 0000000..8daeb7d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * vdso_test.c: Sample code to test parse_vdso.c
+ * Copyright (c) 2014 Andy Lutomirski
+ * Subject to the GNU General Public License, version 2
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_test.c parse_vdso.c
+ *
+ * Tested on x86, 32-bit and 64-bit.  It may work on other architectures, too.
+ */
+
+#include <stdint.h>
+#include <elf.h>
+#include <stdio.h>
+#include <sys/auxv.h>
+#include <sys/time.h>
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+int main(int argc, char **argv)
+{
+       unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
+       if (!sysinfo_ehdr) {
+               printf("AT_SYSINFO_EHDR is not present!\n");
+               return 0;
+       }
+
+       vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
+
+       /* Find gettimeofday. */
+       typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
+       gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+
+       if (!gtod) {
+               printf("Could not find __vdso_gettimeofday\n");
+               return 1;
+       }
+
+       struct timeval tv;
+       long ret = gtod(&tv, 0);
+
+       if (ret == 0) {
+               printf("The time is %lld.%06lld\n",
+                      (long long)tv.tv_sec, (long long)tv.tv_usec);
+       } else {
+               printf("__vdso_gettimeofday failed\n");
+       }
+
+       return 0;
+}
diff --git a/tools/testing/selftests/watchdog/.gitignore b/tools/testing/selftests/watchdog/.gitignore
new file mode 100644 (file)
index 0000000..5aac515
--- /dev/null
@@ -0,0 +1 @@
+watchdog-test
diff --git a/tools/testing/selftests/watchdog/Makefile b/tools/testing/selftests/watchdog/Makefile
new file mode 100644 (file)
index 0000000..f863c66
--- /dev/null
@@ -0,0 +1,8 @@
+TEST_PROGS := watchdog-test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+       rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c
new file mode 100644 (file)
index 0000000..6983d05
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Watchdog Driver Test Program
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+int fd;
+const char v = 'V';
+
+/*
+ * This function simply sends an IOCTL to the driver, which in turn ticks
+ * the PC Watchdog card to reset its internal timer so it doesn't trigger
+ * a computer reset.
+ */
+static void keep_alive(void)
+{
+    int dummy;
+
+    printf(".");
+    ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+}
+
+/*
+ * The main program.  Run the program with "-d" to disable the card,
+ * or "-e" to enable the card.
+ */
+
+static void term(int sig)
+{
+    int ret = write(fd, &v, 1);
+
+    close(fd);
+    if (ret < 0)
+       printf("\nStopping watchdog ticks failed (%d)...\n", errno);
+    else
+       printf("\nStopping watchdog ticks...\n");
+    exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+    int flags;
+    unsigned int ping_rate = 1;
+    int ret;
+
+    setbuf(stdout, NULL);
+
+    fd = open("/dev/watchdog", O_WRONLY);
+
+    if (fd == -1) {
+       printf("Watchdog device not enabled.\n");
+       exit(-1);
+    }
+
+    if (argc > 1) {
+       if (!strncasecmp(argv[1], "-d", 2)) {
+           flags = WDIOS_DISABLECARD;
+           ioctl(fd, WDIOC_SETOPTIONS, &flags);
+           printf("Watchdog card disabled.\n");
+           goto end;
+       } else if (!strncasecmp(argv[1], "-e", 2)) {
+           flags = WDIOS_ENABLECARD;
+           ioctl(fd, WDIOC_SETOPTIONS, &flags);
+           printf("Watchdog card enabled.\n");
+           goto end;
+       } else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
+           flags = atoi(argv[2]);
+           ioctl(fd, WDIOC_SETTIMEOUT, &flags);
+           printf("Watchdog timeout set to %u seconds.\n", flags);
+           goto end;
+       } else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
+           ping_rate = strtoul(argv[2], NULL, 0);
+           printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
+       } else {
+           printf("-d to disable, -e to enable, -t <n> to set " \
+               "the timeout,\n-p <n> to set the ping rate, and \n");
+           printf("run by itself to tick the card.\n");
+           goto end;
+       }
+    }
+
+    printf("Watchdog Ticking Away!\n");
+
+    signal(SIGINT, term);
+
+    while(1) {
+       keep_alive();
+       sleep(ping_rate);
+    }
+end:
+    ret = write(fd, &v, 1);
+    if (ret < 0)
+       printf("Stopping watchdog ticks failed (%d)...\n", errno);
+    close(fd);
+    return 0;
+}
index eb17917..7972cc5 100644 (file)
@@ -13,7 +13,7 @@ Statistics for individual zram devices are exported through sysfs nodes at
 
 Kconfig required:
 CONFIG_ZRAM=y
-CONFIG_ZRAM_LZ4_COMPRESS=y
+CONFIG_CRYPTO_LZ4=y
 CONFIG_ZPOOL=y
 CONFIG_ZSMALLOC=y