Handle generation number is not automatically advanced with bus reset.
Function raw1394_update_generation() added for manual update. Bus reset handler get current generation number as argument. Default bus reset handler calls raw1394_update_generation(). git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@60 53a565d1-3bb7-0310-b661-cf11e63c67ab
This commit is contained in:
parent
fdc1945dab
commit
e02dee488a
13
Makefile.am
13
Makefile.am
|
@ -7,6 +7,19 @@ aclocal_DATA = libraw1394.m4
|
||||||
|
|
||||||
EXTRA_DIST = libraw1394.m4
|
EXTRA_DIST = libraw1394.m4
|
||||||
|
|
||||||
|
doc: psdoc pdfdoc htmldoc
|
||||||
|
|
||||||
|
psdoc:
|
||||||
|
$(MAKE) -C doc psdoc
|
||||||
|
|
||||||
|
pdfdoc:
|
||||||
|
$(MAKE) -C doc pdfdoc
|
||||||
|
|
||||||
|
htmldoc:
|
||||||
|
$(MAKE) -C doc htmldoc
|
||||||
|
|
||||||
|
.PHONY: doc psdoc pdfdoc htmldoc
|
||||||
|
|
||||||
# make required device file
|
# make required device file
|
||||||
dev:
|
dev:
|
||||||
mknod -m 600 /dev/raw1394 c 171 0
|
mknod -m 600 /dev/raw1394 c 171 0
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -4,9 +4,13 @@ Version 0.9:
|
||||||
mainly raw1394_read(), raw1394_write(), raw1394_lock;
|
mainly raw1394_read(), raw1394_write(), raw1394_lock;
|
||||||
Source incompatibility! Parts need to be adapted in application code, but
|
Source incompatibility! Parts need to be adapted in application code, but
|
||||||
it's well worth it.
|
it's well worth it.
|
||||||
|
- the generation number is not unconditionally updated on bus reset in the event
|
||||||
|
loop anymore, the new function raw1394_update_generation() has to be used
|
||||||
|
(unless the default bus reset handler is used) so that transactions won't fail
|
||||||
- iso handlers used to get the iso header quadlet in host endian, now they get
|
- iso handlers used to get the iso header quadlet in host endian, now they get
|
||||||
it in big endian like the rest of the packet for consistency
|
it in big endian like the rest of the packet for consistency
|
||||||
- testlibraw gets installed now, man page also included
|
- testlibraw gets installed now, man page also included
|
||||||
|
- (not yet complete) documentation in Docbook format included
|
||||||
- libraw1394.m4 autoconf macro added
|
- libraw1394.m4 autoconf macro added
|
||||||
|
|
||||||
Version 0.8:
|
Version 0.8:
|
||||||
|
|
49
README
49
README
|
@ -28,34 +28,10 @@ files.
|
||||||
|
|
||||||
3. API documentation
|
3. API documentation
|
||||||
|
|
||||||
There is currently no external document describing the library
|
Finally there is something, in the doc subdirectory. The file is
|
||||||
functions, but you can find documentation for all functions in the header file
|
libraw1394.sgml (it's Docbook format), and there are preformatted PostScript and
|
||||||
raw1394.h. Some real documentation will come Real Soon Now.
|
HTML available. This documentation is not complete yet! I hopefully will have
|
||||||
|
a libraw1394 0.9.1 out soon with finished documentation.
|
||||||
To clear up some confusion (it wasn't documented before, what was I
|
|
||||||
thinking), here is a description of the return values of the
|
|
||||||
raw1394_(read|write|lock) functions and also the errcode parameter of
|
|
||||||
tag_handler_t or reeqhandler_t:
|
|
||||||
|
|
||||||
If it is negative it signals an error in handling the request locally
|
|
||||||
(1394 target node not reached) and errno contains a Unix error code just like
|
|
||||||
with other library functions. If it is positive it still does not signal
|
|
||||||
success of the request itself, just that it was properly communicated to the
|
|
||||||
1394 target node. To know whether it succeeded the lower 32 bits have to be
|
|
||||||
further decoded.
|
|
||||||
|
|
||||||
The upper 16 bits contain the acknowledge code from the other node, the
|
|
||||||
lower 16 bits the response code. Both of these codes are the standard codes
|
|
||||||
from the 1394 standard with the exception of 0x10 for the ack which is set on an
|
|
||||||
access to the local node (there is no 1394 bus involved and therefore no ack
|
|
||||||
exists). Most of the acks completely determine the success of the request
|
|
||||||
(ack_complete or one of the error codes). The response code has to be
|
|
||||||
interpreted if the ack is ack_pending or the dummy ack 0x10. Only in this case
|
|
||||||
is the response code valid.
|
|
||||||
|
|
||||||
This way of reporting errors will be replaced by a more sensible
|
|
||||||
approach with (one of the, but hopefully) the next version of libraw.
|
|
||||||
Documented here only for those who can't wait.
|
|
||||||
|
|
||||||
|
|
||||||
4. Multithreading
|
4. Multithreading
|
||||||
|
@ -66,7 +42,20 @@ 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.
|
Simply use separate handles for each thread in which you need to use libraw1394.
|
||||||
|
|
||||||
|
|
||||||
5. Maintainer
|
5. Autoconf macro
|
||||||
|
|
||||||
|
Along with the library an autoconf macro gets installed (in
|
||||||
|
$prefix/share/aclocal). It is called the following way:
|
||||||
|
|
||||||
|
AC_LIB_RAW1394(MINIMUMVERSION[,ACTION_IF_FOUND[,ACTION_IF_NOT_FOUND]])
|
||||||
|
|
||||||
|
Versions prior to 0.9 can not be checked and appear as "not found".
|
||||||
|
This macro sets the variables LIBRAW1394_CPPFLAGS, LIBRAW1394_CFLAGS and
|
||||||
|
LIBRAW1394_LIBS. You have to include those into your build variables so that
|
||||||
|
the build process correctly links with libraw1394.
|
||||||
|
|
||||||
|
|
||||||
|
6. Maintainer
|
||||||
|
|
||||||
Maintainer of libraw1394 is currently Andreas Bombe. Send suggestions,
|
Maintainer of libraw1394 is currently Andreas Bombe. Send suggestions,
|
||||||
bug reports and fixes to andreas.bombe@munich.netsurf.de. See the file AUTHORS
|
bug reports and fixes to andreas.bombe@munich.netsurf.de. See the file AUTHORS
|
||||||
|
@ -77,4 +66,4 @@ http://sourceforge.net/project/?group_id=2514 for more information. You can
|
||||||
also submit bugs through this page.
|
also submit bugs through this page.
|
||||||
|
|
||||||
|
|
||||||
2000-11-25 Andreas Bombe
|
2001-05-14 Andreas Bombe
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# process this file with autoconf to get a configure script
|
# process this file with autoconf to get a configure script
|
||||||
|
|
||||||
AC_INIT(Makefile.am)
|
AC_INIT(Makefile.am)
|
||||||
AM_INIT_AUTOMAKE(libraw1394, 0.8.99)
|
AM_INIT_AUTOMAKE(libraw1394, 0.9.0)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
@ -14,7 +14,7 @@ AC_C_BIGENDIAN
|
||||||
|
|
||||||
# set the libtool so version numbers
|
# set the libtool so version numbers
|
||||||
lt_major=5
|
lt_major=5
|
||||||
lt_revision=1
|
lt_revision=0
|
||||||
lt_age=0
|
lt_age=0
|
||||||
|
|
||||||
AC_SUBST(lt_major)
|
AC_SUBST(lt_major)
|
||||||
|
|
|
@ -1,3 +1,30 @@
|
||||||
|
EXTRA_DIST = testlibraw.1.in libraw1394.sgml libraw1394 libraw1394.ps
|
||||||
|
|
||||||
# man files for testlibraw
|
# man files for testlibraw
|
||||||
man_MANS = testlibraw.1
|
man_MANS = testlibraw.1
|
||||||
EXTRA_DIST = testlibraw.1.in
|
|
||||||
|
# libraw1394 docbook documentation
|
||||||
|
|
||||||
|
CLEANFILES = libraw1394.aux libraw1394.dvi libraw1394.log libraw1394.out \
|
||||||
|
libraw1394.tex libraw1394.pdf
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = libraw1394.ps
|
||||||
|
|
||||||
|
maintainer-clean-local:
|
||||||
|
rm -rf libraw1394
|
||||||
|
|
||||||
|
doc: psdoc pdfdoc htmldoc
|
||||||
|
psdoc: libraw1394.ps
|
||||||
|
pdfdoc: libraw1394.pdf
|
||||||
|
htmldoc: libraw1394/book1.html
|
||||||
|
|
||||||
|
.PHONY: doc psdoc pdfdoc htmldoc
|
||||||
|
|
||||||
|
libraw1394.ps: libraw1394.sgml
|
||||||
|
db2ps $<
|
||||||
|
|
||||||
|
libraw1394.pdf: libraw1394.sgml
|
||||||
|
db2pdf $<
|
||||||
|
|
||||||
|
libraw1394/book1.html: libraw1394.sgml
|
||||||
|
db2html $<
|
||||||
|
|
|
@ -0,0 +1,766 @@
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
|
||||||
|
|
||||||
|
<book>
|
||||||
|
<bookinfo>
|
||||||
|
|
||||||
|
<title>libraw1394</title>
|
||||||
|
<subtitle>version 0.9</subtitle>
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
<year>2001</year>
|
||||||
|
<holder>Andreas Bombe</holder>
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<toc></toc>
|
||||||
|
|
||||||
|
<chapter id="introduction">
|
||||||
|
<title>Introduction</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The Linux kernel's IEEE 1394 subsystem provides access to the raw 1394 bus
|
||||||
|
through the raw1394 module. This includes the standard 1394 transactions
|
||||||
|
(read, write, lock) on the active side, isochronous stream receiving and
|
||||||
|
sending and dumps of data written to the FCP_COMMAND and FCP_RESPONSE
|
||||||
|
registers. raw1394 uses a character device to communicate to user
|
||||||
|
programs using a special protocol.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
libraw1394 was created with the intent to hide that protocol from
|
||||||
|
applications so that
|
||||||
|
<orderedlist numeration="arabic">
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
the protocol has to be implemented correctly only once.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
all work can be done using easy to understand functions instead of
|
||||||
|
handling a complicated command structure.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
only libraw1394 has to be changed when raw1394's interface changes.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To fully achieve the goals (especially 3) libraw1394 is distributed under
|
||||||
|
the LGPL (Lesser General Public License - see file COPYING.LIB for more
|
||||||
|
information.) to allow linking with any program, be it open source or
|
||||||
|
binary only. The requirements are that the libraw1394 part can be
|
||||||
|
replaced (relinked) with another version of the library and that changes
|
||||||
|
to libraw1394 itself fall under LGPL again. Refer to the LGPL text for
|
||||||
|
details.
|
||||||
|
</para>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="intro1394">
|
||||||
|
<title>Short Introduction into IEEE 1394</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
IEEE 1394 in fact defines two types of hardware implementations for this
|
||||||
|
bus system, cable and backplane. The only one described here and
|
||||||
|
supported by the Linux subsystem is the cable implementation. Most people
|
||||||
|
not familiar with the standard probably don't even know that there is
|
||||||
|
something else than the 1394 cable specification.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If you are familiar with CSR architectures (as defined in --FIXME--), then
|
||||||
|
you already know most of 1394, which is a CSR implementation.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Bus Structure</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The basic data structures defined in the standard and used in this
|
||||||
|
document are the quadlet (32 bit quantity) and the octlet (64 bit
|
||||||
|
quantity) and blocks (any quantity of bytes). The bus byte ordering is
|
||||||
|
big endian. A transmission can be sent at one of multiple possible
|
||||||
|
speeds, from the slowest 100 Mbit/s over 200 and 400 Mbit/s up to 3.2
|
||||||
|
Gbit/s in the future (these speeds are also referred to as S100, S200,
|
||||||
|
...).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A 1394 bus consists of up to 64 nodes (with multiple buses possibly
|
||||||
|
being connected, but that is outside of the scope of this document and
|
||||||
|
not completely standardized yet), each having a local address space with
|
||||||
|
48 bit wide addressing. Each node is addressed with a 16 bit address,
|
||||||
|
which is further divided into a 10 bit bus ID and a 6 bit local node ID.
|
||||||
|
The highest value for both is a special value. Bus ID equal to 1023
|
||||||
|
means "local bus" (the bus the node is connected to), node ID equal to
|
||||||
|
63 means "all nodes" (broadcast).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The whole bus can thus be seen as a linear 64 bit address space by
|
||||||
|
concatenating the node address (most significant bits) and and node
|
||||||
|
address (least significant bits). libraw1394 treats them separately in
|
||||||
|
function arguments to save the application some fiddling with the bits.
|
||||||
|
The node IDs are completely dynamic and determined during the bus reset.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Unlike other buses there aren't many transactions or commands defined,
|
||||||
|
higher level commands are defined in terms of addresses accessed instead
|
||||||
|
of separate transaction types (comparable to memory mapped registers in
|
||||||
|
hardware). The 1394 transactions are:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>read (quadlets and blocks)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>write (quadlets and blocks)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>lock (some atomic modifications)</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
There is also the isochronous transaction (the above three are called
|
||||||
|
asynchronous transactions), which is a broadcast stream with guaranteed
|
||||||
|
bandwidth. It doesn't contain any address but is distinguished by a 6
|
||||||
|
bit channel number.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The bus view is only logical, physically it consists of many
|
||||||
|
point-to-point connections between nodes with every node forwarding data
|
||||||
|
it receives to every other port which is capable of the speed the
|
||||||
|
transaction is sent at (thus a S200 node in the path between two S400
|
||||||
|
nodes would limit their communication speed to S200). It forms a tree
|
||||||
|
structure with all but one node having a parent and a number of
|
||||||
|
children. One node is the root node and has no parents.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Bus Reset</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A bus reset occurs whenever the state of any node changes (including
|
||||||
|
addition and removal of nodes). At the beginning a root node is chosen,
|
||||||
|
then the tree identification determines for every node which port is
|
||||||
|
connected to a parent, child or nothing. Then the SelfID phase begins.
|
||||||
|
The root node sends a SelfID grant on its first port connected to a
|
||||||
|
child. If that is not a leaf node, it will itself forward the grant to
|
||||||
|
its first child. When a leaf node gets a grant, it will pick the lowest
|
||||||
|
node ID not yet in use (starting with 0) and send out a SelfID packet
|
||||||
|
with its node ID and more information, then acknowledge the SelfID grant
|
||||||
|
to its parent, which will send a grant to its next child until it
|
||||||
|
configured all its children, then pick a node ID itself, send SelfID
|
||||||
|
packet and ack to parent.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
After bus reset the used node IDs are in a sequential range with no
|
||||||
|
holes starting from 0 with the root node having the highest ID. This
|
||||||
|
also means that node IDs can change for many or all nodes with the
|
||||||
|
insertion of a new node or moving the role of root to another node. In
|
||||||
|
libraw1394 all transactions are tagged automatically with a generation
|
||||||
|
number which is increased in every bus reset and transactions with an
|
||||||
|
obsolete generation will fail in order to avoid targetting the wrong
|
||||||
|
node. Nodes have to be identified in a different way than their
|
||||||
|
volatile node IDs, namely by reading their globally unique ID (GUID)
|
||||||
|
contained in the configuration ROM.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Transactions</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The packets transmitted on the bus are acknowledged by the receiving end
|
||||||
|
unless they are broadcast packets (broadcast writes and isochronous
|
||||||
|
packets). The acknowledge code contains an error code, which either
|
||||||
|
signifies error, success or packet pending. In the first two cases the
|
||||||
|
transaction completes, in the last a response packet will follow at a
|
||||||
|
later time from the targetted node to the source node (this is called a
|
||||||
|
split transaction). Only writes can succeed and complete in the ack
|
||||||
|
code, reads and locks require a response. Error and packet pending can
|
||||||
|
happen for every transaction.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The response packets contain a response code (rcode) which signifies
|
||||||
|
success or type of error. libraw1394 contains a function to convert
|
||||||
|
ack/rcode pairs into errno codes which convey roughly the same meaning.
|
||||||
|
This is done automatically for the synchronous read/write/lock wrapper
|
||||||
|
functions, i.e. they return a negative value for failure and a standard
|
||||||
|
error code can be found in the global variable <symbol>errno</symbol>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For read and write there are two different types, quadlet and block.
|
||||||
|
The quadlet types have all their payload (exactly one quadlet) in the
|
||||||
|
packet header, the block types have a variable length data block
|
||||||
|
appended to the header. Programs using libraw1394 don't have to care
|
||||||
|
about that, quadlet transactions are automatically used when the data
|
||||||
|
length is 4 bytes and block transactions otherwise.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The lock transaction has several extended transaction codes defined
|
||||||
|
which choose the atomic operation to perform, the most used being the
|
||||||
|
compare-and-swap (code 0x2). The transaction passes the data value and
|
||||||
|
(depending on the operation) the arg value to the target node and
|
||||||
|
returns the old value at the target address, but only when the
|
||||||
|
transaction does not have an error. All three values are of the same
|
||||||
|
size, either one quadlet or one octlet.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In the compare-and-swap case, the data value is written to the target
|
||||||
|
address if the old value is identical to the arg value. The old value
|
||||||
|
is returned in any case and can be used to find out whether the swap
|
||||||
|
succeeded by repeating the compare locally. Isochronous resource
|
||||||
|
allocation is done using compare-and-swap, as described below. Since
|
||||||
|
the old value is always returned, it more efficient to do the first
|
||||||
|
attempt with the reset value of the target register as arg instead of
|
||||||
|
reading it first. Repeat with the returned old value as new arg value
|
||||||
|
if it didn't succeed.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Bus Management</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
There are three basic bus service nodes defined in IEEE 1394 (higher
|
||||||
|
level protocols may define more): cycle master, isochronous resource
|
||||||
|
manager and bus manager. These positions are contended for in and
|
||||||
|
shortly after the bus reset and may all be taken by a single node. A
|
||||||
|
node does not have to support being any of those but if it is bus
|
||||||
|
manager capable it also has to be iso manager capable, if it is iso
|
||||||
|
manager capable it also has to be cycle master capable.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The cycle master sends 8000 cycle start packets per second, which
|
||||||
|
initiate an iso cycle. Without that, no isochronous transmission is
|
||||||
|
possible. Only the root node is allowed to be cycle master, if it is
|
||||||
|
not capable then no iso transmissions can occur (and the iso or bus
|
||||||
|
manager have to select another node to become root and initiate a bus
|
||||||
|
reset).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The isochronous resource manager is the central point where channel and
|
||||||
|
bandwidth allocations are stored. A bit in the SelfID shows whether a
|
||||||
|
node is iso manager capable or not, the iso manager capable node with
|
||||||
|
the highest ID wins the position after a bus reset. Apart from
|
||||||
|
containing allocation registers, this one doesn't do much. Only if
|
||||||
|
there is no bus manager, it may determine a cycle master capable node to
|
||||||
|
become root and initiate a bus reset.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The bus manager has more responsibilities: power management (calculate
|
||||||
|
power provision and consumption on the bus and turn on disabled nodes if
|
||||||
|
enough power is available), bus optimization (calculate an effective gap
|
||||||
|
count, optimize the topology by selecting a better positioned node for
|
||||||
|
root) and some registers relevant to topology (topology map containing
|
||||||
|
the SelfIDs of the last reset and a speed map, which is obsoleted in
|
||||||
|
IEEE 1394a). The bus manager capable nodes contend for the role by
|
||||||
|
doing a lock transaction on the bus manager ID register in the iso
|
||||||
|
manager, the first to successfully complete the transaction wins the
|
||||||
|
role.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Isochronous Transmissions</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Nodes can allocate a channel and bandwidth for isochronous transmissions
|
||||||
|
at the iso manager to broadcast timing critical data (e.g. multimedia
|
||||||
|
streams) on the bus. However these transmissions are unreliable, there
|
||||||
|
is no guarantee that every packet reaches the intended recipients (the
|
||||||
|
software and hardware involved also take iso packets a bit more
|
||||||
|
lightly). After a cycle start packet, the isochronous cycle begins and
|
||||||
|
every node can transmit iso packets, however only one packet per channel
|
||||||
|
is allowed. As soon as a gap of a certain length appears (i.e. no node
|
||||||
|
sends anymore), the iso cycle ends and the rest of the time until the
|
||||||
|
next cycle start is reserved for asynchronous packets.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The channel register on the iso manager consists of 64 bits, each of
|
||||||
|
which signifies one channel. A channel can be allocated by any node by
|
||||||
|
doing a compare-swap lock request with the new bitmask. Likewise the
|
||||||
|
bandwidth can be allocated by doing a lock request with the new value.
|
||||||
|
The bandwidth register contains the remaining time available for every
|
||||||
|
iso cycle. Since you allocate time, the maximum data you are allowed to
|
||||||
|
put into an iso packet depends on the speed you will send at.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
On every bus reset, the resource registers are resetted to their initial
|
||||||
|
values (all channels free, all bandwidth minus some amount set aside for
|
||||||
|
asynchronous communication available), this has to happen since the
|
||||||
|
isochronous manager may have moved to another node. Isochronous
|
||||||
|
transmissions may continue with the old allocations for a certain
|
||||||
|
(FIXME) amount of time. During that time, the nodes have to reallocate
|
||||||
|
their resources and no new allocations are allowed to occur. Only after
|
||||||
|
this period new allocations may be done, this avoids nodes losing their
|
||||||
|
allocations over a bus reset.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
libraw1394 does not provide special functions for allocating iso
|
||||||
|
resources nor does it clean up after programs when they exit. Protocols
|
||||||
|
exist that require the first node to use some resources to allocate it
|
||||||
|
and then leave it for the last node using it to deallocate it. This may
|
||||||
|
be different nodes, so automatic behaviour would be very undesirable in
|
||||||
|
these cases.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="general">
|
||||||
|
<title>Data Structures and Program Flow</title>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Overview</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The 1394 subsystem in Linux is divided into the classical three layers,
|
||||||
|
like most other interface subsystems in Linux. The subsystem consists
|
||||||
|
of the core, which provides basic services like handling of the 1394
|
||||||
|
protocol (converting the abstract transactions into packets and back),
|
||||||
|
collecting information about bus and nodes and providing some services
|
||||||
|
to the bus that are required to be available for standards conformant
|
||||||
|
node (e.g. CSR registers). Below that are the hardware drivers, which
|
||||||
|
handle converting packets and bus events to and from hardware accesses.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Above the core are the highlevel drivers, which use the services
|
||||||
|
provided by the core to implement protocols for certain devices and act
|
||||||
|
as drivers to these. raw1394 is one such driver, however it is not
|
||||||
|
specialized to handle one kind of device but is designed to accept
|
||||||
|
commands from user space to do any transaction wanted (as far as
|
||||||
|
possible from current core design). Using raw1394, normal applications
|
||||||
|
can access 1394 nodes on the bus and it is not neccessary to write
|
||||||
|
kernel code just for that.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
raw1394 communicates to user space like most device drivers do, through
|
||||||
|
device files in /dev. It uses a defined protocol on that device, but
|
||||||
|
applications don't have to and should not care about that. All of this
|
||||||
|
is taken care of by libraw1394, which provides a set of functions that
|
||||||
|
convert to and from raw1394 protocol packets and are a lot easier to
|
||||||
|
handle than that underlying protocol.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Handles</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The handle presented to the application for using libraw1394 is the
|
||||||
|
raw1394handle_t, an opaque data structure (which means you don't need to
|
||||||
|
know its internals). The handle (and with it a connection to the kernel
|
||||||
|
side of raw1394) is obtained using
|
||||||
|
<function>raw1394_new_handle()</function>. Insufficient permissions to
|
||||||
|
access the kernel driver will result in failure of this function, among
|
||||||
|
other possibilities of failure.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
While initializing the handle, a certain order of function calls have to
|
||||||
|
be obeyed or undefined results will occur. This order reflects the
|
||||||
|
various states of initialization to be done:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para><function>raw1394_new_handle()</function></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><function>raw1394_get_port_info()</function></para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para><function>raw1394_set_port()</function></para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Ports</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A computer may have multiple 1394 buses connected by having multiple
|
||||||
|
1394 chips. Each of these is called a port, and the handle has to be
|
||||||
|
connected to one port before it can be used for anything. Even if no
|
||||||
|
nodes are connected to the chip in question, it forms a complete bus
|
||||||
|
(with just one node, itself).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A list of available ports together with some information about it
|
||||||
|
(name of the hardware, number of connected nodes) is available via
|
||||||
|
<function>raw1394_get_port_info()</function>, which is to be called
|
||||||
|
right getting a fresh handle. The user should be presented with a
|
||||||
|
choice of available ports if there is more than one. It may be good
|
||||||
|
practice to do that even if there is only one port, since that may
|
||||||
|
result from a normally configured port just not being available,
|
||||||
|
making it confusing to be dropped right into the application attached
|
||||||
|
to a port without a choice and notion of anything going wrong.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The choice of port is then reported using
|
||||||
|
<function>raw1394_set_port()</function>. If this function fails and
|
||||||
|
<symbol>errno</symbol> is set to <symbol>ESTALE</symbol>, then
|
||||||
|
something has changed about the ports (port was added or removed)
|
||||||
|
between getting the port info and trying to set a port. It is
|
||||||
|
required that the current port list is fetched (presenting the user
|
||||||
|
with the choice again) and setting the port is retried with the new
|
||||||
|
data.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
After a successful <function>raw1394_set_port()</function>, the get and
|
||||||
|
set port functions must not be used anymore on this handle. Undefined
|
||||||
|
results occur if you do so. To make up for this, all the other
|
||||||
|
functions are allowed now.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>The Event Loop</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
All commands in libraw1394 are asynchronous, with some synchronous
|
||||||
|
wrapper functions for some types of transactions. This means that there
|
||||||
|
are two streams of data, one going into raw1394 and one coming out.
|
||||||
|
With this design you can send out multiple transactions without having
|
||||||
|
to wait for the response before you can continue (sending out other
|
||||||
|
transactions, for example). The responses and other events (like bus
|
||||||
|
resets and received isochronous packets) are queued, and you can get
|
||||||
|
them with <function>raw1394_loop_iterate()</function>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This forms an event loop you may already know from similar systems like
|
||||||
|
GUI toolkits. <function>raw1394_loop_iterate()</function> gets one
|
||||||
|
message from the event queue in raw1394, processes it with the
|
||||||
|
configured callback functions and returns the value returned by the
|
||||||
|
callback (so you can signal to the main loop from your callback; the
|
||||||
|
standard callbacks all return 0). It normally blocks when there are no
|
||||||
|
events and always processes only one event. If you are only receiving
|
||||||
|
broadcast events like isochronous packets you thus have to set up a loop
|
||||||
|
continuously calling the iterate function to get your callbacks called.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Often it is necessary to have multiple event loops and combine them,
|
||||||
|
e.g. if your application uses a GUI toolkit which also has its own event
|
||||||
|
loop. In that case you can use <function>raw1394_get_fd()</function> to
|
||||||
|
get the file descriptor used for this handle by libraw1394. The fd can
|
||||||
|
be used to for <function>select()</function> or
|
||||||
|
<function>poll()</function> calls (testing for read availability)
|
||||||
|
together with the other loop's fd, some event loops also allow to add
|
||||||
|
other fds to their own set (GTK's event loop does). If these trigger on
|
||||||
|
the libraw1394 fd, you can call
|
||||||
|
<function>raw1394_loop_iterate()</function> once and it is guaranteed
|
||||||
|
that it will not block since at the very least one event waits. After
|
||||||
|
the first call you continue the main event loop. If more events wait,
|
||||||
|
the <function>select()</function>/<function>poll()</function> will
|
||||||
|
immediately return again.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You can also use the fd to set the <symbol>O_NONBLOCK</symbol> flag with
|
||||||
|
<function>fcntl()</function>. After that, the iterate function will not
|
||||||
|
block anymore but fail with <symbol>errno</symbol> set to
|
||||||
|
<symbol>EAGAIN</symbol> if no events wait. These are the only legal
|
||||||
|
uses for the fd returned by <function>raw1394_get_fd()</function>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
There are some functions which provide a synchronous wrapper for
|
||||||
|
transactions, note that these will call
|
||||||
|
<function>raw1394_loop_iterate()</function> continuously until their
|
||||||
|
transaction is completed, thus having implicit callback invocations
|
||||||
|
during their execution. The standard transaction functions have names
|
||||||
|
of the form <function>raw1394_start_xxx</function>, the synchronous
|
||||||
|
wrappers are called <function>raw1394_xxx</function>.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<title>Handlers</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
There are a number of handlers which can be set using the appropriate
|
||||||
|
function as described in the function reference and which libraw1394
|
||||||
|
will call during a <function>raw1394_loop_iterate()</function>. These
|
||||||
|
are:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>tag handler (called for completed commands)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>bus reset handler (called when a bus reset happens)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>iso handler (called when an iso packet is received)</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>fcp handler (called when a FCP command or response is
|
||||||
|
received)</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
The bus reset handler is always called, the tag handler for every
|
||||||
|
command that completes, the iso handler and fcp handler are only called
|
||||||
|
when the application chooses to receive these packets. Handlers return
|
||||||
|
an integer value which is passed on by
|
||||||
|
<function>raw1394_loop_iterate()</function> (only one handler is called
|
||||||
|
per invocation), <constant>0</constant> is returned without a handler in
|
||||||
|
place.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The tag handler case is a bit special since the default handler is
|
||||||
|
actually doing something. Every command that you start can be given an
|
||||||
|
unsigned long tag which is passed untouched to the tag handler when the
|
||||||
|
event loop sees a completed command. The default handler expects this
|
||||||
|
value to be a pointer to a <structname>raw1394_reqhandle</structname>
|
||||||
|
structure, which contains a data pointer and its own callback function
|
||||||
|
pointer. The callback gets the untouched data pointer and error code as
|
||||||
|
arguments. If you want to use tags that are not
|
||||||
|
<structname>raw1394_reqhandle</structname> pointers you have to set up
|
||||||
|
your own tag handler.
|
||||||
|
</para>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="functions">
|
||||||
|
<title>Function Reference</title>
|
||||||
|
|
||||||
|
<refentry>
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>raw1394_new_handle</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>raw1394_net_handle</refname>
|
||||||
|
<refpurpose>create new handle</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>raw1394handle_t <function>raw1394_new_handle</function></funcdef>
|
||||||
|
<void>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates and returns a new handle. It is not allowed to use the same
|
||||||
|
handle in multiple threads or forked processes. It is allowed to
|
||||||
|
create and use multiple handles, however. Use one handle per thread
|
||||||
|
which needs it in the multithreaded case.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Returns the created handle or <constant>NULL</constant> when
|
||||||
|
initialization fails. In the latter case <varname>errno</varname>
|
||||||
|
either contains some OS specific error code or <constant>0</constant>
|
||||||
|
if the error is that libraw1394 and raw1394 don't support each other's
|
||||||
|
protocol versions.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
|
||||||
|
<refentry>
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>raw1394_destroy_handle</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>raw1394_destroy_handle</refname>
|
||||||
|
<refpurpose>deallocate handle</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>void <function>raw1394_destroy_handle</function></funcdef>
|
||||||
|
<paramdef>raw1394handle_t <parameter>handle</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Arguments</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>handle</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>handle to be deallocated</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Closes connection with raw1394 on this handle and deallocates
|
||||||
|
everything associated with it. It is safe to pass
|
||||||
|
<constant>NULL</constant> as handle, nothing is done in this case.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
|
||||||
|
<refentry>
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>raw1394_get_fd</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>raw1394_get_fd</refname>
|
||||||
|
<refpurpose>get the communication file descriptor</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>raw1394_get_fd</function></funcdef>
|
||||||
|
<paramdef>raw1394handle_t <parameter>handle</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Arguments</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>handle</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>handle of which the fd is to be returned from</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Returns the fd used for communication with the raw1394 kernel module.
|
||||||
|
This can be used for
|
||||||
|
<function>select()</function>/<function>poll()</function> calls if you
|
||||||
|
wait on other fds or can be integrated into another event loop
|
||||||
|
(e.g. from a GUI application framework). It can also be used to
|
||||||
|
set/remove the <constant>O_NONBLOCK</constant> flag using
|
||||||
|
<function>fcntl()</function> to modify the block behaviour in
|
||||||
|
<function>raw1394_loop_iterate()</function>. It must not be used for
|
||||||
|
anything else.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The fd of the communication stream. Invalid fds may be returned
|
||||||
|
before a port was set using <function>raw1394_set_port()</function>.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
|
||||||
|
<refentry>
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>raw1394_(get|set)_userdata</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>raw1394_get_userdata</refname>
|
||||||
|
<refname>raw1394_set_userdata</refname>
|
||||||
|
<refpurpose>associate user data with a handle</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>void *<function>raw1394_get_userdata</function></funcdef>
|
||||||
|
<paramdef>raw1394handle_t <parameter>handle</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>void <function>raw1394_set_userdata</function></funcdef>
|
||||||
|
<paramdef>raw1394handle_t <parameter>handle</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Arguments</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><parameter>handle</parameter></term>
|
||||||
|
<listitem>
|
||||||
|
<para>handle associated with the user data</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Allows to associate one void pointer with a handle. libraw1394 does
|
||||||
|
not care about the data, it just stores it in the handle allowing it
|
||||||
|
to be retrieved at any time. This can be useful when multiple handles
|
||||||
|
are used, so that callbacks can identify the handle.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<function>raw1394_get_userdata()</function> returns the void pointer
|
||||||
|
associated with the handle.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
</refentry>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
</book>
|
|
@ -28,8 +28,6 @@ int raw1394_loop_iterate(struct raw1394_handle *handle)
|
||||||
|
|
||||||
switch (req->type) {
|
switch (req->type) {
|
||||||
case RAW1394_REQ_BUS_RESET:
|
case RAW1394_REQ_BUS_RESET:
|
||||||
handle->generation = req->generation;
|
|
||||||
|
|
||||||
if (handle->protocol_version == 3) {
|
if (handle->protocol_version == 3) {
|
||||||
handle->num_of_nodes = req->misc & 0xffff;
|
handle->num_of_nodes = req->misc & 0xffff;
|
||||||
handle->local_id = req->misc >> 16;
|
handle->local_id = req->misc >> 16;
|
||||||
|
@ -40,7 +38,8 @@ int raw1394_loop_iterate(struct raw1394_handle *handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->bus_reset_handler) {
|
if (handle->bus_reset_handler) {
|
||||||
retval = handle->bus_reset_handler(handle);
|
retval = handle->bus_reset_handler(handle,
|
||||||
|
req->generation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
#include "raw1394_private.h"
|
#include "raw1394_private.h"
|
||||||
|
|
||||||
|
|
||||||
static int bus_reset_default(struct raw1394_handle *handle)
|
static int bus_reset_default(struct raw1394_handle *handle, unsigned int gen)
|
||||||
{
|
{
|
||||||
|
raw1394_update_generation(handle, gen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +125,11 @@ unsigned int raw1394_get_generation(struct raw1394_handle *handle)
|
||||||
return handle->generation;
|
return handle->generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void raw1394_update_generation(struct raw1394_handle *handle, unsigned int gen)
|
||||||
|
{
|
||||||
|
handle->generation = gen;
|
||||||
|
}
|
||||||
|
|
||||||
int raw1394_get_nodecount(struct raw1394_handle *handle)
|
int raw1394_get_nodecount(struct raw1394_handle *handle)
|
||||||
{
|
{
|
||||||
return handle->num_of_nodes;
|
return handle->num_of_nodes;
|
||||||
|
|
|
@ -45,7 +45,6 @@ int raw1394_get_fd(raw1394handle_t handle);
|
||||||
void *raw1394_get_userdata(raw1394handle_t handle);
|
void *raw1394_get_userdata(raw1394handle_t handle);
|
||||||
void raw1394_set_userdata(raw1394handle_t handle, void *data);
|
void raw1394_set_userdata(raw1394handle_t handle, void *data);
|
||||||
|
|
||||||
unsigned int raw1394_get_generation(raw1394handle_t handle);
|
|
||||||
nodeid_t raw1394_get_local_id(raw1394handle_t handle);
|
nodeid_t raw1394_get_local_id(raw1394handle_t handle);
|
||||||
nodeid_t raw1394_get_irm_id(raw1394handle_t handle);
|
nodeid_t raw1394_get_irm_id(raw1394handle_t handle);
|
||||||
|
|
||||||
|
@ -92,12 +91,25 @@ int raw1394_loop_iterate(raw1394handle_t handle);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the handler that will be called when a bus reset message is encountered.
|
* Set the handler that will be called when a bus reset message is encountered.
|
||||||
* The default action is to do nothing. Returns old handler.
|
* The default action is to just call raw1394_update_generation(). Returns old
|
||||||
|
* handler.
|
||||||
*/
|
*/
|
||||||
typedef int (*bus_reset_handler_t)(raw1394handle_t);
|
typedef int (*bus_reset_handler_t)(raw1394handle_t, unsigned int generation);
|
||||||
bus_reset_handler_t raw1394_set_bus_reset_handler(raw1394handle_t handle,
|
bus_reset_handler_t raw1394_set_bus_reset_handler(raw1394handle_t handle,
|
||||||
bus_reset_handler_t new_h);
|
bus_reset_handler_t new_h);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since node IDs may change during a bus reset, generation numbers incremented
|
||||||
|
* every bus reset are used to verify if a transaction request is intended for
|
||||||
|
* this configuration. If numbers don't match, they will fail immediately.
|
||||||
|
*
|
||||||
|
* raw1394_get_generation() returns the generation number in use by the handle,
|
||||||
|
* not the current generation number. The current generation number is passed
|
||||||
|
* to the bus reset handler.
|
||||||
|
*/
|
||||||
|
unsigned int raw1394_get_generation(raw1394handle_t handle);
|
||||||
|
void raw1394_update_generation(raw1394handle_t handle, unsigned int generation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the handler that will be called when an async read/write/lock returns.
|
* 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
|
* The default action is to call the callback in the raw1394_reqhandle pointed
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
/* Variables to find version by linking (avoid need for test program) */
|
/* Variables to find version by linking (avoid need for test program) */
|
||||||
|
|
||||||
char __libraw1394_version_0_8_99;
|
char __libraw1394_version_0_9;
|
||||||
|
char __libraw1394_version_0_9_0;
|
||||||
|
|
||||||
/* This function is to be used by the autoconf macro to find the lib version */
|
/* This function is to be used by the autoconf macro to find the lib version */
|
||||||
const char *raw1394_get_libversion()
|
const char *raw1394_get_libversion()
|
||||||
|
|
Reference in New Issue