/* -*- mode: c; c-basic-offset: 2 -*- */
/*
* nosy-dump - Interface to snoop mode driver for TI PCILynx 1394 controllers
* Copyright (C) 2002-2006 Kristian Høgsberg
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <endian.h>
#include <popt.h>
#include <poll.h>
#include <byteswap.h>
#include <termios.h>
#include <signal.h>
#include "list.h"
#include "nosy-user.h"
#include "nosy-dump.h"
enum {
PACKET_FIELD_DETAIL = 0x01,
PACKET_FIELD_DATA_LENGTH = 0x02,
/* Marks the fields we print in transaction view. */
PACKET_FIELD_TRANSACTION = 0x04
};
static void
print_packet(uint32_t *data, size_t length);
static void
decode_link_packet(struct link_packet *packet, size_t length,
int include_flags, int exclude_flags);
static int run = 1;
sig_t sys_sigint_handler;
static char *option_nosy_device = "/dev/nosy";
static char *option_view = "packet";
static char *option_output = NULL;
static char *option_input = NULL;
static int option_hex;
static int option_iso;
static int option_cycle_start;
static int option_version;
static int option_verbose;
enum {
VIEW_TRANSACTION,
VIEW_PACKET,
VIEW_STATS
};
static const struct poptOption options[] = {
{
longName: "device",
shortName: 'd',
argInfo: POPT_ARG_STRING,
arg: &option_nosy_device,
descrip: "Path to nosy device.",
argDescrip: "DEVICE"
},
{
longName: "view",
argInfo: POPT_ARG_STRING,
arg: &option_view,
descrip: "Specify view of bus traffic: packet, transaction or stats.",
argDescrip: "VIEW"
},
{
longName: "hex",
shortName: 'x',
argInfo: POPT_ARG_NONE,
arg: &option_hex,
descrip: "Print each packet in hex.",
},
{
longName: "iso",
argInfo: POPT_ARG_NONE,
arg: &option_iso,
descrip: "Print iso packets.",
},
{
longName: "cycle-start",
argInfo: POPT_ARG_NONE,
arg: &option_cycle_start,
descrip: "Print cycle start packets.",
},
{
longName: "verbose",
shortName: 'v',
argInfo: POPT_ARG_NONE,
arg: &option_verbose,
descrip: "Verbose packet view.",
},
{
longName: "output",
shortName: 'o',
argInfo: POPT_ARG_STRING,
arg: &option_output,
descrip: "Log to output file.",
argDescrip: "FILENAME"
},
{
longName: "input",
shortName: 'i',
argInfo: POPT_ARG_STRING,
arg: &option_input,
descrip: "Decode log from file.",
argDescrip: "FILENAME"
},
{
longName: "version",
argInfo: POPT_ARG_NONE,
arg: &option_version,
descrip: "Specify print version info.",
},
POPT_AUTOHELP
POPT_TABLEEND
};
void
sigint_handler(int signal_num)
{
if (run == 1) {
run = 0;
/* Allow all Ctrl-C's except the first to interrupt the program in
* the usual way.
*/
signal(SIGINT, SIG_DFL);
}
}
struct subaction *
subaction_create(uint32_t *data, size_t length)
{
struct subaction *sa;
/* we put the ack in the subaction struct for easy access. */
sa = malloc(sizeof *sa - sizeof sa->packet + length);
sa->ack = data[length / 4 - 1];
sa->length = length;
memcpy (&sa->packet, data, length);
return sa;
}
void
subaction_destroy(struct subaction *sa)
{
free(sa);
}
struct list pending_transaction_list =
{ &pending_transaction_list,