Initial revision
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@1 53a565d1-3bb7-0310-b661-cf11e63c67ab
This commit is contained in:
commit
0f5ef10baa
|
@ -0,0 +1,2 @@
|
||||||
|
Andreas Bombe <andreas.bombe@munich.netsurf.de>
|
||||||
|
or: <bombe@informatik.tu-muenchen.de>
|
|
@ -0,0 +1,182 @@
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
These are generic installation instructions.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, a file
|
||||||
|
`config.cache' that saves the results of its tests to speed up
|
||||||
|
reconfiguring, and a file `config.log' containing compiler output
|
||||||
|
(useful mainly for debugging `configure').
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If at some point `config.cache'
|
||||||
|
contains results you don't want to keep, you may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.in' is used to create `configure' by a program
|
||||||
|
called `autoconf'. You only need `configure.in' if you want to change
|
||||||
|
it or regenerate `configure' using a newer version of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system. If you're
|
||||||
|
using `csh' on an old version of System V, you might need to type
|
||||||
|
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
5. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. You can give `configure'
|
||||||
|
initial values for variables by setting them in the environment. Using
|
||||||
|
a Bourne-compatible shell, you can do that on the command line like
|
||||||
|
this:
|
||||||
|
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||||
|
|
||||||
|
Or on systems that have the `env' program, you can do it like this:
|
||||||
|
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you must use a version of `make' that
|
||||||
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
If you have to use a `make' that does not supports the `VPATH'
|
||||||
|
variable, you have to compile the package for one architecture at a time
|
||||||
|
in the source code directory. After you have installed the package for
|
||||||
|
one architecture, use `make distclean' before reconfiguring for another
|
||||||
|
architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
PATH as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' can not figure out
|
||||||
|
automatically, but needs to determine by the type of host the package
|
||||||
|
will run on. Usually `configure' can figure that out, but if it prints
|
||||||
|
a message saying it can not guess the host type, give it the
|
||||||
|
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name with three fields:
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the host type.
|
||||||
|
|
||||||
|
If you are building compiler tools for cross-compiling, you can also
|
||||||
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
|
produce code for and the `--build=TYPE' option to select the type of
|
||||||
|
system on which you are compiling the package.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Operation Controls
|
||||||
|
==================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Use and save the results of the tests in FILE instead of
|
||||||
|
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||||
|
debugging `configure'.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options.
|
|
@ -0,0 +1,5 @@
|
||||||
|
# process this file with automake to create a Makefile.in
|
||||||
|
|
||||||
|
SUBDIRS = src
|
||||||
|
|
||||||
|
EXTRA_DIST = debian/*
|
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
libraw1394
|
||||||
|
==========
|
||||||
|
|
||||||
|
1. About libraw1394
|
||||||
|
|
||||||
|
libraw1394 is the only supported interface to the kernel side raw1394 of
|
||||||
|
the Linux IEEE-1394 subsystem, which provides direct access to the connected
|
||||||
|
1394 buses to user space. Through libraw1394/raw1394, applications can directly
|
||||||
|
send to and receive from other nodes without requiring a kernel driver for the
|
||||||
|
protocol in question.
|
||||||
|
|
||||||
|
The reason for making a library the interface to the kernel is to avoid
|
||||||
|
a program dependancy on the kernel version, which would hinder development and
|
||||||
|
optimization of raw1394. If development changed the protocol and made it
|
||||||
|
incompatible with previous versions only the libraw1394 has to be upgraded to
|
||||||
|
match the kernel version (instead of all applications).
|
||||||
|
|
||||||
|
|
||||||
|
2. Copyleft
|
||||||
|
|
||||||
|
libraw1394 itself is licensed under the Lesser General Public License
|
||||||
|
(short LGPL, see file COPYING.LIB in the source distribution). Other files in
|
||||||
|
the source archives not belonging to but being part of the build procedure of
|
||||||
|
libraw1394 are under their own licenses, as stated at the top of the individual
|
||||||
|
files.
|
||||||
|
|
||||||
|
|
||||||
|
3. API documentation
|
||||||
|
|
||||||
|
There is currently no external document describing the library functions,
|
||||||
|
but you can find documentation for all functions in the header file raw1394.h.
|
||||||
|
|
||||||
|
|
||||||
|
4. Multithreading
|
||||||
|
|
||||||
|
This library should be multithreadable with the restriction that one
|
||||||
|
raw1394handle_t may be used only within a single thread. Multiple threads
|
||||||
|
operating on the same handle would royally mess up the kernel-user protocol.
|
||||||
|
Simply use separate handles for each thread in which you need to use libraw1394.
|
||||||
|
|
||||||
|
|
||||||
|
5. Maintainer
|
||||||
|
|
||||||
|
Maintainer of libraw1394 is currently Andreas Bombe. Send suggestions,
|
||||||
|
bug reports and fixes to andreas.bombe@munich.netsurf.de. See the file AUTHORS
|
||||||
|
for a complete list of contributors to libraw1394.
|
||||||
|
|
||||||
|
|
||||||
|
1999-11-23 Andreas Bombe
|
|
@ -0,0 +1,9 @@
|
||||||
|
# process this file with autoconf to get a configure script
|
||||||
|
|
||||||
|
AC_INIT(Makefile.am)
|
||||||
|
AM_INIT_AUTOMAKE(libraw1394, 0.3)
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
|
AC_OUTPUT([ Makefile src/Makefile ])
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
There's nothing here so far, as you probably noticed. I intend to
|
||||||
|
package libraw1394 for Debian as soon as it gets stable and I become a Debian
|
||||||
|
maintainer for this package. Or as soon as I grok Debian's package management
|
||||||
|
system, for that matter...
|
||||||
|
|
||||||
|
Andreas Bombe
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# the libraw1394 itself
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libraw1394.la
|
||||||
|
|
||||||
|
libraw1394_la_LDFLAGS = -version-info 0:0:0
|
||||||
|
|
||||||
|
libraw1394_la_SOURCES = \
|
||||||
|
main.c \
|
||||||
|
eventloop.c \
|
||||||
|
readwrite.c \
|
||||||
|
kernel-raw1394.h \
|
||||||
|
raw1394_private.h
|
||||||
|
|
||||||
|
# headers to be installed
|
||||||
|
pkginclude_HEADERS = raw1394.h csr.h
|
||||||
|
|
||||||
|
# testlibraw
|
||||||
|
noinst_PROGRAMS = testlibraw
|
||||||
|
testlibraw_LDADD = libraw1394.la
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
#define CSR_REGISTER_BASE 0xfffff0000000ULL
|
||||||
|
|
||||||
|
/* register offsets relative to CSR_REGISTER_BASE */
|
||||||
|
#define CSR_STATE_CLEAR 0x0
|
||||||
|
#define CSR_STATE_SET 0x4
|
||||||
|
#define CSR_NODE_IDS 0x8
|
||||||
|
#define CSR_RESET_START 0xc
|
||||||
|
#define CSR_SPLIT_TIMEOUT_HI 0x18
|
||||||
|
#define CSR_SPLIT_TIMEOUT_LO 0x1c
|
||||||
|
#define CSR_CYCLE_TIME 0x200
|
||||||
|
#define CSR_BUS_TIME 0x204
|
||||||
|
#define CSR_BUSY_TIMEOUT 0x210
|
||||||
|
#define CSR_BUS_MANAGER_ID 0x21c
|
||||||
|
#define CSR_BANDWIDTH_AVAILABLE 0x220
|
||||||
|
#define CSR_CHANNELS_AVAILABLE_HI 0x224
|
||||||
|
#define CSR_CHANNELS_AVAILABLE_LO 0x228
|
||||||
|
#define CSR_CONFIG_ROM 0x400
|
||||||
|
#define CSR_CONFIG_ROM_END 0x800
|
||||||
|
#define CSR_TOPOLOGY_MAP 0x1000
|
||||||
|
#define CSR_TOPOLOGY_MAP_END 0x1400
|
||||||
|
#define CSR_SPEED_MAP 0x2000
|
||||||
|
#define CSR_SPEED_MAP_END 0x3000
|
|
@ -0,0 +1,81 @@
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "raw1394.h"
|
||||||
|
#include "kernel-raw1394.h"
|
||||||
|
#include "raw1394_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
int raw1394_loop_iterate(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
if (read(handle->fd, req, sizeof(*req)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (req->type) {
|
||||||
|
case RAW1394_REQ_BUS_RESET:
|
||||||
|
handle->generation = req->generation;
|
||||||
|
handle->num_of_nodes = req->misc & 0xffff;
|
||||||
|
handle->local_id = req->misc >> 16;
|
||||||
|
|
||||||
|
if (handle->bus_reset_handler) {
|
||||||
|
retval = handle->bus_reset_handler(handle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RAW1394_REQ_ISO_RECEIVE:
|
||||||
|
if (handle->iso_handler) {
|
||||||
|
retval = handle->iso_handler(handle,
|
||||||
|
(handle->buffer[0] >> 8)
|
||||||
|
& 0x3f, req->length,
|
||||||
|
handle->buffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (handle->tag_handler) {
|
||||||
|
retval = handle->tag_handler(handle, req->tag,
|
||||||
|
req->error);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bus_reset_handler_t raw1394_set_bus_reset_handler(struct raw1394_handle *handle,
|
||||||
|
bus_reset_handler_t new)
|
||||||
|
{
|
||||||
|
bus_reset_handler_t old;
|
||||||
|
|
||||||
|
old = handle->bus_reset_handler;
|
||||||
|
handle->bus_reset_handler = new;
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_handler_t raw1394_set_tag_handler(struct raw1394_handle *handle,
|
||||||
|
tag_handler_t new)
|
||||||
|
{
|
||||||
|
tag_handler_t old;
|
||||||
|
|
||||||
|
old = handle->tag_handler;
|
||||||
|
handle->tag_handler = new;
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
iso_handler_t raw1394_set_iso_handler(struct raw1394_handle *handle,
|
||||||
|
iso_handler_t new)
|
||||||
|
{
|
||||||
|
iso_handler_t old;
|
||||||
|
|
||||||
|
old = handle->iso_handler;
|
||||||
|
handle->iso_handler = new;
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
|
||||||
|
#ifndef IEEE1394_RAW1394_H
|
||||||
|
#define IEEE1394_RAW1394_H
|
||||||
|
|
||||||
|
#define RAW1394_DEVICE_MAJOR 171
|
||||||
|
#define RAW1394_DEVICE_NAME "raw1394"
|
||||||
|
|
||||||
|
#define RAW1394_KERNELAPI_VERSION 1
|
||||||
|
|
||||||
|
/* state: opened */
|
||||||
|
#define RAW1394_REQ_INITIALIZE 1
|
||||||
|
|
||||||
|
/* state: initialized */
|
||||||
|
#define RAW1394_REQ_LIST_CARDS 2
|
||||||
|
#define RAW1394_REQ_SET_CARD 3
|
||||||
|
|
||||||
|
/* state: connected */
|
||||||
|
#define RAW1394_REQ_ASYNC_READ 100
|
||||||
|
#define RAW1394_REQ_ASYNC_WRITE 101
|
||||||
|
#define RAW1394_REQ_LOCK 102
|
||||||
|
#define RAW1394_REQ_LOCK64 103
|
||||||
|
|
||||||
|
#define RAW1394_REQ_ISO_LISTEN 200
|
||||||
|
|
||||||
|
/* kernel to user */
|
||||||
|
#define RAW1394_REQ_BUS_RESET 10000
|
||||||
|
#define RAW1394_REQ_ISO_RECEIVE 10001
|
||||||
|
|
||||||
|
/* error codes */
|
||||||
|
#define RAW1394_ERROR_NONE 0
|
||||||
|
#define RAW1394_ERROR_COMPAT (-1001)
|
||||||
|
#define RAW1394_ERROR_STATE_ORDER (-1002)
|
||||||
|
#define RAW1394_ERROR_GENERATION (-1003)
|
||||||
|
#define RAW1394_ERROR_INVALID_ARG (-1004)
|
||||||
|
#define RAW1394_ERROR_MEMFAULT (-1005)
|
||||||
|
#define RAW1394_ERROR_ALREADY (-1006)
|
||||||
|
|
||||||
|
#define RAW1394_ERROR_EXCESSIVE (-1020)
|
||||||
|
#define RAW1394_ERROR_UNTIDY_LEN (-1021)
|
||||||
|
|
||||||
|
#define RAW1394_ERROR_SEND_ERROR (-1100)
|
||||||
|
#define RAW1394_ERROR_ABORTED (-1101)
|
||||||
|
#define RAW1394_ERROR_TIMEOUT (-1102)
|
||||||
|
|
||||||
|
|
||||||
|
struct raw1394_request {
|
||||||
|
int type;
|
||||||
|
int error;
|
||||||
|
int misc;
|
||||||
|
|
||||||
|
unsigned int generation;
|
||||||
|
octlet_t address;
|
||||||
|
|
||||||
|
unsigned long tag;
|
||||||
|
|
||||||
|
size_t length;
|
||||||
|
quadlet_t *sendb;
|
||||||
|
quadlet_t *recvb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct raw1394_khost_list {
|
||||||
|
int nodes;
|
||||||
|
char name[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
struct file_info {
|
||||||
|
struct list_head list;
|
||||||
|
|
||||||
|
enum { opened, initialized, connected } state;
|
||||||
|
|
||||||
|
struct hpsb_host *host;
|
||||||
|
|
||||||
|
struct list_head req_pending;
|
||||||
|
struct list_head req_complete;
|
||||||
|
struct semaphore complete_sem;
|
||||||
|
spinlock_t reqlists_lock;
|
||||||
|
wait_queue_head_t poll_wait_complete;
|
||||||
|
|
||||||
|
u64 listen_channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pending_request {
|
||||||
|
struct list_head list;
|
||||||
|
struct file_info *file_info;
|
||||||
|
struct hpsb_packet *packet;
|
||||||
|
struct tq_struct tq;
|
||||||
|
quadlet_t *data;
|
||||||
|
int free_data;
|
||||||
|
struct raw1394_request req;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct host_info {
|
||||||
|
struct list_head list;
|
||||||
|
struct hpsb_host *host;
|
||||||
|
struct list_head file_info_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
#endif /* IEEE1394_RAW1394_H */
|
|
@ -0,0 +1,179 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "raw1394.h"
|
||||||
|
#include "kernel-raw1394.h"
|
||||||
|
#include "raw1394_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int bus_reset_default(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tag_handler_default(struct raw1394_handle *handle, unsigned long tag,
|
||||||
|
int error)
|
||||||
|
{
|
||||||
|
struct raw1394_reqhandle *rh;
|
||||||
|
|
||||||
|
if (tag) {
|
||||||
|
rh = (struct raw1394_reqhandle *)tag;
|
||||||
|
return rh->callback(handle, rh->data, error);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iso_handler_default(struct raw1394_handle *handle, int channel,
|
||||||
|
size_t length, quadlet_t *data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int init_rawdevice(struct raw1394_handle *h)
|
||||||
|
{
|
||||||
|
struct raw1394_request *req = &h->req;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
req->type = RAW1394_REQ_INITIALIZE;
|
||||||
|
req->misc = RAW1394_KERNELAPI_VERSION;
|
||||||
|
|
||||||
|
if (write(h->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
if (read(h->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
if (req->error) {
|
||||||
|
errno = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return req->generation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct raw1394_handle *raw1394_get_handle(void)
|
||||||
|
{
|
||||||
|
struct raw1394_handle *handle;
|
||||||
|
|
||||||
|
handle = malloc(sizeof(struct raw1394_handle));
|
||||||
|
if (!handle) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->fd = open("/dev/raw1394", O_RDWR);
|
||||||
|
if (handle->fd < 0) {
|
||||||
|
free(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->generation = init_rawdevice(handle);
|
||||||
|
if (handle->generation < 0) {
|
||||||
|
close(handle->fd);
|
||||||
|
free(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->bus_reset_handler = bus_reset_default;
|
||||||
|
handle->tag_handler = tag_handler_default;
|
||||||
|
handle->iso_handler = iso_handler_default;
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void raw1394_destroy_handle(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
if (handle) {
|
||||||
|
close(handle->fd);
|
||||||
|
free(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_get_fd(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
return handle->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int raw1394_get_generation(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
return handle->generation;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_get_nodecount(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
return handle->num_of_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeid_t raw1394_get_local_id(struct raw1394_handle *handle)
|
||||||
|
{
|
||||||
|
return handle->local_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int raw1394_get_port_info(struct raw1394_handle *handle,
|
||||||
|
struct raw1394_portinfo *pinf, int maxports)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
struct raw1394_khost_list *khl;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
req->type = RAW1394_REQ_LIST_CARDS;
|
||||||
|
req->generation = handle->generation;
|
||||||
|
req->recvb = handle->buffer;
|
||||||
|
req->length = HBUF_SIZE;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (write(handle->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
if (read(handle->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
|
||||||
|
if (!req->error) break;
|
||||||
|
|
||||||
|
if (req->error == RAW1394_ERROR_GENERATION) {
|
||||||
|
handle->generation = req->generation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (num = req->misc, khl = (struct raw1394_khost_list *)handle->buffer;
|
||||||
|
num && maxports; num--, maxports--, pinf++, khl++) {
|
||||||
|
pinf->nodes = khl->nodes;
|
||||||
|
strcpy(pinf->name, khl->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return req->misc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_set_port(struct raw1394_handle *handle, int port)
|
||||||
|
{
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
|
||||||
|
req->type = RAW1394_REQ_SET_CARD;
|
||||||
|
req->generation = handle->generation;
|
||||||
|
req->misc = port;
|
||||||
|
|
||||||
|
if (write(handle->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
if (read(handle->fd, req, sizeof(*req)) < 0) return -1;
|
||||||
|
|
||||||
|
switch (req->error) {
|
||||||
|
case RAW1394_ERROR_GENERATION:
|
||||||
|
handle->generation = req->generation;
|
||||||
|
errno = ESTALE;
|
||||||
|
return -1;
|
||||||
|
case RAW1394_ERROR_INVALID_ARG:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
case RAW1394_ERROR_NONE:
|
||||||
|
handle->num_of_nodes = req->misc & 0xffff;
|
||||||
|
handle->local_id = req->misc >> 16;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
errno = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
|
||||||
|
#ifndef _LIBRAW1394_RAW1394_H
|
||||||
|
#define _LIBRAW1394_RAW1394_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
typedef u_int32_t quadlet_t;
|
||||||
|
typedef u_int64_t octlet_t;
|
||||||
|
typedef u_int64_t nodeaddr_t;
|
||||||
|
typedef u_int16_t nodeid_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct raw1394_handle *raw1394handle_t;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Required as initialization. One handle can control one port, it is possible
|
||||||
|
* to use multiple handles. raw1394_get_handle returns NULL for failure,
|
||||||
|
* raw1394_destroy_handle accepts NULL. If raw1394_get_handle returns NULL and
|
||||||
|
* errno is 0, this version of libraw1394 is incompatible with the kernel.
|
||||||
|
*/
|
||||||
|
raw1394handle_t raw1394_get_handle(void);
|
||||||
|
void raw1394_destroy_handle(raw1394handle_t handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the fd of this handle to select()/poll() on it. Don't try to mess around
|
||||||
|
* with it any other way. Valid only after the handle got attached to a port.
|
||||||
|
*/
|
||||||
|
int raw1394_get_fd(raw1394handle_t handle);
|
||||||
|
|
||||||
|
unsigned int raw1394_get_generation(raw1394handle_t handle);
|
||||||
|
nodeid_t raw1394_get_local_id(raw1394handle_t handle);
|
||||||
|
|
||||||
|
/* Get number of nodes on bus. */
|
||||||
|
int raw1394_get_nodecount(raw1394handle_t handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns number of available ports (port == one IEEE 1394 card or onboard
|
||||||
|
* chip). A maximum number of maxport raw1394_portinfos will be filled out at
|
||||||
|
* *pinf, zero is valid if you're only interested in the number of ports (which
|
||||||
|
* is returned).
|
||||||
|
*/
|
||||||
|
struct raw1394_portinfo {
|
||||||
|
int nodes;
|
||||||
|
char name[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
int raw1394_get_port_info(raw1394handle_t handle, struct raw1394_portinfo *pinf,
|
||||||
|
int maxports);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach handle to port (counted from zero). Returns zero for success or -1
|
||||||
|
* for failure. If in the case of failure errno is set to ESTALE the generation
|
||||||
|
* number has changed and you should reget the port info.
|
||||||
|
*/
|
||||||
|
int raw1394_set_port(raw1394handle_t handle, int port);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get one new message through handle and process it. See below for handler
|
||||||
|
* registering functions. This function will return -1 for an error or the
|
||||||
|
* return value of the handler which got executed. Default handlers always
|
||||||
|
* return zero.
|
||||||
|
*/
|
||||||
|
int raw1394_loop_iterate(raw1394handle_t handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the handler that will be called when a bus reset message is encountered.
|
||||||
|
* The default action is to do nothing. Returns old handler.
|
||||||
|
*/
|
||||||
|
typedef int (*bus_reset_handler_t)(raw1394handle_t);
|
||||||
|
bus_reset_handler_t raw1394_set_bus_reset_handler(raw1394handle_t handle,
|
||||||
|
bus_reset_handler_t new);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the handler that will be called when an async read/write/lock returns.
|
||||||
|
* The default action is to call the callback in the raw1394_reqhandle pointed
|
||||||
|
* to by tag. Returns old handler.
|
||||||
|
*/
|
||||||
|
typedef int (*tag_handler_t)(raw1394handle_t, unsigned long tag, int errcode);
|
||||||
|
tag_handler_t raw1394_set_tag_handler(raw1394handle_t handle,
|
||||||
|
tag_handler_t new);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the handler that will be called when an iso packet arrives (data points
|
||||||
|
* to the iso packet header). The default action is to do nothing. Returns old
|
||||||
|
* handler.
|
||||||
|
*
|
||||||
|
* Iso receive is not implemented yet.
|
||||||
|
*/
|
||||||
|
typedef int (*iso_handler_t)(raw1394handle_t, int channel, size_t length,
|
||||||
|
quadlet_t *data);
|
||||||
|
iso_handler_t raw1394_set_iso_handler(raw1394handle_t handle,
|
||||||
|
iso_handler_t new);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the general request handle. It is used by the default tag handler
|
||||||
|
* when a request completes, it calls the callback and passes it the data
|
||||||
|
* pointer and the error code of the request.
|
||||||
|
*/
|
||||||
|
typedef int (*req_callback_t)(raw1394handle_t, void *data, int errcode);
|
||||||
|
struct raw1394_reqhandle {
|
||||||
|
req_callback_t callback;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Passes custom tag. Use pointer to raw1394_reqhandle if you use the standard
|
||||||
|
* tag handler.
|
||||||
|
*/
|
||||||
|
int raw1394_start_read(struct raw1394_handle *handle, nodeid_t node,
|
||||||
|
nodeaddr_t addr, size_t length, quadlet_t *buffer,
|
||||||
|
unsigned long tag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This does the complete transaction and will return when it's finished. It
|
||||||
|
* will call raw1394_loop_iterate() as often as necessary, return values of
|
||||||
|
* handlers called will be lost.
|
||||||
|
*/
|
||||||
|
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
||||||
|
size_t length, quadlet_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LIBRAW1394_RAW1394_H */
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
#ifndef _RAW1394_PRIVATE_H
|
||||||
|
#define _RAW1394_PRIVATE_H
|
||||||
|
|
||||||
|
struct raw1394_handle {
|
||||||
|
int fd;
|
||||||
|
unsigned int generation;
|
||||||
|
|
||||||
|
nodeid_t local_id;
|
||||||
|
int num_of_nodes;
|
||||||
|
|
||||||
|
bus_reset_handler_t bus_reset_handler;
|
||||||
|
tag_handler_t tag_handler;
|
||||||
|
iso_handler_t iso_handler;
|
||||||
|
|
||||||
|
struct raw1394_request req;
|
||||||
|
quadlet_t buffer[2048];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HBUF_SIZE 8192
|
||||||
|
#define CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request))
|
||||||
|
|
||||||
|
#endif /* _RAW1394_PRIVATE_H */
|
|
@ -0,0 +1,96 @@
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "raw1394.h"
|
||||||
|
#include "kernel-raw1394.h"
|
||||||
|
#include "raw1394_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct sync_cb_data {
|
||||||
|
int done;
|
||||||
|
int errcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sync_cb(struct raw1394_handle *unused,
|
||||||
|
struct sync_cb_data *data, int error)
|
||||||
|
{
|
||||||
|
data->errcode = error;
|
||||||
|
data->done = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int raw1394_start_read(struct raw1394_handle *handle, nodeid_t node,
|
||||||
|
nodeaddr_t addr, size_t length, quadlet_t *buffer,
|
||||||
|
unsigned long tag)
|
||||||
|
{
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
|
||||||
|
req->type = RAW1394_REQ_ASYNC_READ;
|
||||||
|
req->generation = handle->generation;
|
||||||
|
req->tag = tag;
|
||||||
|
|
||||||
|
req->address = ((u_int64_t)node << 48) | addr;
|
||||||
|
req->length = length;
|
||||||
|
req->recvb = buffer;
|
||||||
|
|
||||||
|
return (int)write(handle->fd, req, sizeof(*req));
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
|
||||||
|
nodeaddr_t addr, size_t length, quadlet_t *data,
|
||||||
|
unsigned long tag)
|
||||||
|
{
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
|
||||||
|
req->type = RAW1394_REQ_ASYNC_WRITE;
|
||||||
|
req->generation = handle->generation;
|
||||||
|
req->tag = tag;
|
||||||
|
|
||||||
|
req->address = ((u_int64_t)node << 48) | addr;
|
||||||
|
req->length = length;
|
||||||
|
req->sendb = data;
|
||||||
|
|
||||||
|
return (int)write(handle->fd, req, sizeof(*req));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define SYNCFUNC_VARS \
|
||||||
|
struct sync_cb_data sd = { 0, 0 }; \
|
||||||
|
struct raw1394_reqhandle rh = { (req_callback_t)sync_cb, &sd }; \
|
||||||
|
int err
|
||||||
|
|
||||||
|
#define SYNCFUNC_BODY \
|
||||||
|
if (err < 0) return err; \
|
||||||
|
while (!sd.done) raw1394_loop_iterate(handle); \
|
||||||
|
return sd.errcode
|
||||||
|
|
||||||
|
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
||||||
|
size_t length, quadlet_t *buffer)
|
||||||
|
{
|
||||||
|
SYNCFUNC_VARS;
|
||||||
|
|
||||||
|
err = raw1394_start_read(handle, node, addr, length, buffer,
|
||||||
|
(unsigned long)&rh);
|
||||||
|
|
||||||
|
SYNCFUNC_BODY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_write(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
||||||
|
size_t length, quadlet_t *data)
|
||||||
|
{
|
||||||
|
SYNCFUNC_VARS;
|
||||||
|
|
||||||
|
err = raw1394_start_write(handle, node, addr, length, data,
|
||||||
|
(unsigned long)&rh);
|
||||||
|
|
||||||
|
SYNCFUNC_BODY;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SYNCFUNC_VARS
|
||||||
|
#undef SYNCFUNC_BODY
|
|
@ -0,0 +1,119 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "raw1394.h"
|
||||||
|
#include "csr.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TESTADDR (CSR_REGISTER_BASE + CSR_CYCLE_TIME)
|
||||||
|
|
||||||
|
const char not_compatible[] = "\
|
||||||
|
This libraw1394 does not work with your version of Linux. You need a different
|
||||||
|
version that matches your kernel (see kernel help text for the raw1394 option to
|
||||||
|
find out which is the correct version).\n";
|
||||||
|
|
||||||
|
const char not_loaded[] = "\
|
||||||
|
This probably means that you don't have raw1394 support in the kernel or that
|
||||||
|
you haven't loaded the raw1394 module.\n";
|
||||||
|
|
||||||
|
|
||||||
|
quadlet_t buffer;
|
||||||
|
|
||||||
|
int my_tag_handler(struct raw1394_handle *handle, unsigned long tag, int error)
|
||||||
|
{
|
||||||
|
if (error < 0) {
|
||||||
|
printf("completed with error %d\n", error);
|
||||||
|
} else {
|
||||||
|
printf("completed with 0x%08x, value 0x%08x\n", error, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
raw1394handle_t handle;
|
||||||
|
int i, numcards;
|
||||||
|
struct raw1394_portinfo pinf[16];
|
||||||
|
|
||||||
|
tag_handler_t std_handler;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
|
||||||
|
handle = raw1394_get_handle();
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
if (!errno) {
|
||||||
|
printf(not_compatible);
|
||||||
|
} else {
|
||||||
|
perror("couldn't get handle");
|
||||||
|
printf(not_loaded);
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("successfully got handle\n");
|
||||||
|
printf("current generation number: %d\n", raw1394_get_generation(handle));
|
||||||
|
|
||||||
|
numcards = raw1394_get_port_info(handle, pinf, 16);
|
||||||
|
if (numcards < 0) {
|
||||||
|
perror("couldn't get card info");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("%d card(s) found\n", numcards);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!numcards) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numcards; i++) {
|
||||||
|
printf(" nodes on bus: %2d, card name: %s\n", pinf[i].nodes,
|
||||||
|
pinf[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw1394_set_port(handle, 0) < 0) {
|
||||||
|
perror("couldn't set port");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("using first card found: %d nodes on bus, local ID is %d\n",
|
||||||
|
raw1394_get_nodecount(handle),
|
||||||
|
raw1394_get_local_id(handle) & 0x3f);
|
||||||
|
|
||||||
|
printf("\ndoing transactions with custom tag handler\n");
|
||||||
|
std_handler = raw1394_set_tag_handler(handle, my_tag_handler);
|
||||||
|
for (i = 0; i < pinf[0].nodes; i++) {
|
||||||
|
printf("trying to send read request to node %d... ", i);
|
||||||
|
fflush(stdout);
|
||||||
|
buffer = 0;
|
||||||
|
|
||||||
|
if (raw1394_start_read(handle, 0xffc0 | i, TESTADDR, 4,
|
||||||
|
&buffer, 0) < 0) {
|
||||||
|
perror("failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
raw1394_loop_iterate(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nusing standard tag handler and synchronous calls\n");
|
||||||
|
raw1394_set_tag_handler(handle, std_handler);
|
||||||
|
for (i = 0; i < pinf[0].nodes; i++) {
|
||||||
|
printf("trying to read from node %d... ", i);
|
||||||
|
fflush(stdout);
|
||||||
|
buffer = 0;
|
||||||
|
|
||||||
|
retval = raw1394_read(handle, 0xffc0 | i, TESTADDR, 4, &buffer);
|
||||||
|
if (retval < 0) {
|
||||||
|
printf("failed with error %d\n", retval);
|
||||||
|
} else {
|
||||||
|
printf("completed with 0x%08x, value 0x%08x\n", retval,
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
Reference in New Issue