Added isochronous I/O support
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@4 53a565d1-3bb7-0310-b661-cf11e63c67ab
This commit is contained in:
parent
eb99eec7ab
commit
04f65912c3
10
NEWS
10
NEWS
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
Version 0.4:
|
||||||
|
|
||||||
|
- isochronous receive support
|
||||||
|
|
||||||
|
Version 0.3:
|
||||||
|
|
||||||
|
- first release of new libraw1394 for new raw1394 driver
|
||||||
|
- supports 1394 async reads/writes
|
||||||
|
- maintainer: Andreas Bombe <andreas.bombe@munich.netsurf.de>
|
|
@ -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.3)
|
AM_INIT_AUTOMAKE(libraw1394, 0.4)
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
|
|
||||||
lib_LTLIBRARIES = libraw1394.la
|
lib_LTLIBRARIES = libraw1394.la
|
||||||
|
|
||||||
libraw1394_la_LDFLAGS = -version-info 0:0:0
|
libraw1394_la_LDFLAGS = -version-info 1:0:1
|
||||||
|
|
||||||
libraw1394_la_SOURCES = \
|
libraw1394_la_SOURCES = \
|
||||||
main.c \
|
main.c \
|
||||||
eventloop.c \
|
eventloop.c \
|
||||||
readwrite.c \
|
readwrite.c \
|
||||||
|
iso.c \
|
||||||
kernel-raw1394.h \
|
kernel-raw1394.h \
|
||||||
raw1394_private.h
|
raw1394_private.h
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "raw1394.h"
|
||||||
|
#include "kernel-raw1394.h"
|
||||||
|
#include "raw1394_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int do_iso_listen(struct raw1394_handle *handle, int channel)
|
||||||
|
{
|
||||||
|
struct sync_cb_data sd = { 0, 0 };
|
||||||
|
struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, &sd };
|
||||||
|
int err;
|
||||||
|
struct raw1394_request *req = &handle->req;
|
||||||
|
|
||||||
|
CLEAR_REQ(req);
|
||||||
|
req->type = RAW1394_REQ_ISO_LISTEN;
|
||||||
|
req->generation = handle->generation;
|
||||||
|
req->misc = channel;
|
||||||
|
req->tag = (unsigned long)&rh;
|
||||||
|
req->recvb = handle->buffer;
|
||||||
|
req->length = HBUF_SIZE;
|
||||||
|
|
||||||
|
err = write(handle->fd, req, sizeof(*req));
|
||||||
|
while (!sd.done) {
|
||||||
|
if (err < 0) return err;
|
||||||
|
err = raw1394_loop_iterate(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sd.errcode) {
|
||||||
|
case RAW1394_ERROR_ALREADY:
|
||||||
|
errno = EALREADY;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case RAW1394_ERROR_INVALID_ARG:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errno = 0;
|
||||||
|
return sd.errcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_start_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||||
|
{
|
||||||
|
if (channel > 63) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_iso_listen(handle, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw1394_stop_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||||
|
{
|
||||||
|
if (channel > 63) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_iso_listen(handle, ~channel);
|
||||||
|
}
|
|
@ -65,6 +65,11 @@ struct raw1394_khost_list {
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
struct iso_block_store {
|
||||||
|
atomic_t refcount;
|
||||||
|
quadlet_t data[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct file_info {
|
struct file_info {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
|
@ -79,6 +84,8 @@ struct file_info {
|
||||||
wait_queue_head_t poll_wait_complete;
|
wait_queue_head_t poll_wait_complete;
|
||||||
|
|
||||||
u64 listen_channels;
|
u64 listen_channels;
|
||||||
|
quadlet_t *iso_buffer;
|
||||||
|
size_t iso_buffer_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pending_request {
|
struct pending_request {
|
||||||
|
@ -86,6 +93,7 @@ struct pending_request {
|
||||||
struct file_info *file_info;
|
struct file_info *file_info;
|
||||||
struct hpsb_packet *packet;
|
struct hpsb_packet *packet;
|
||||||
struct tq_struct tq;
|
struct tq_struct tq;
|
||||||
|
struct iso_block_store *ibs;
|
||||||
quadlet_t *data;
|
quadlet_t *data;
|
||||||
int free_data;
|
int free_data;
|
||||||
struct raw1394_request req;
|
struct raw1394_request req;
|
||||||
|
|
10
src/main.c
10
src/main.c
|
@ -33,6 +33,16 @@ static int iso_handler_default(struct raw1394_handle *handle, int channel,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _raw1394_sync_cb(struct raw1394_handle *unused, struct sync_cb_data *data,
|
||||||
|
int error)
|
||||||
|
{
|
||||||
|
data->errcode = error;
|
||||||
|
data->done = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned int init_rawdevice(struct raw1394_handle *h)
|
static unsigned int init_rawdevice(struct raw1394_handle *h)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,6 +64,10 @@ int raw1394_set_port(raw1394handle_t handle, int port);
|
||||||
* registering functions. This function will return -1 for an error or the
|
* registering functions. This function will return -1 for an error or the
|
||||||
* return value of the handler which got executed. Default handlers always
|
* return value of the handler which got executed. Default handlers always
|
||||||
* return zero.
|
* return zero.
|
||||||
|
*
|
||||||
|
* Note that some other library functions may call this function multiple times
|
||||||
|
* to wait for their completion, some handler return values may get lost if you
|
||||||
|
* use these.
|
||||||
*/
|
*/
|
||||||
int raw1394_loop_iterate(raw1394handle_t handle);
|
int raw1394_loop_iterate(raw1394handle_t handle);
|
||||||
|
|
||||||
|
@ -88,8 +92,6 @@ tag_handler_t raw1394_set_tag_handler(raw1394handle_t handle,
|
||||||
* Set the handler that will be called when an iso packet arrives (data points
|
* 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
|
* to the iso packet header). The default action is to do nothing. Returns old
|
||||||
* handler.
|
* handler.
|
||||||
*
|
|
||||||
* Iso receive is not implemented yet.
|
|
||||||
*/
|
*/
|
||||||
typedef int (*iso_handler_t)(raw1394handle_t, int channel, size_t length,
|
typedef int (*iso_handler_t)(raw1394handle_t, int channel, size_t length,
|
||||||
quadlet_t *data);
|
quadlet_t *data);
|
||||||
|
@ -112,23 +114,27 @@ struct raw1394_reqhandle {
|
||||||
* Passes custom tag. Use pointer to raw1394_reqhandle if you use the standard
|
* Passes custom tag. Use pointer to raw1394_reqhandle if you use the standard
|
||||||
* tag handler.
|
* tag handler.
|
||||||
*/
|
*/
|
||||||
int raw1394_start_read(struct raw1394_handle *handle, nodeid_t node,
|
int raw1394_start_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
nodeaddr_t addr, size_t length, quadlet_t *buffer,
|
size_t length, quadlet_t *buffer, unsigned long tag);
|
||||||
unsigned long tag);
|
int raw1394_start_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
|
size_t length, quadlet_t *data, unsigned long tag);
|
||||||
nodeaddr_t addr, size_t length, quadlet_t *data,
|
|
||||||
unsigned long tag);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This does the complete transaction and will return when it's finished. It
|
* 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
|
* will call raw1394_loop_iterate() as often as necessary, return values of
|
||||||
* handlers called will be therefore lost.
|
* handlers called will be therefore lost.
|
||||||
*/
|
*/
|
||||||
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
int raw1394_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
size_t length, quadlet_t *buffer);
|
size_t length, quadlet_t *buffer);
|
||||||
int raw1394_write(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
int raw1394_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
|
||||||
size_t length, quadlet_t *data);
|
size_t length, quadlet_t *data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start and stop receiving a certain isochronous channel. You have to set an
|
||||||
|
* iso handler (see above). You can receive multiple channels simultaneously.
|
||||||
|
*/
|
||||||
|
int raw1394_start_iso_rcv(raw1394handle_t handle, unsigned int channel);
|
||||||
|
int raw1394_stop_iso_rcv(raw1394handle_t handle, unsigned int channel);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,13 @@ struct raw1394_handle {
|
||||||
quadlet_t buffer[2048];
|
quadlet_t buffer[2048];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sync_cb_data {
|
||||||
|
int done;
|
||||||
|
int errcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
int _raw1394_sync_cb(struct raw1394_handle*, struct sync_cb_data*, int);
|
||||||
|
|
||||||
#define HBUF_SIZE 8192
|
#define HBUF_SIZE 8192
|
||||||
#define CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request))
|
#define CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request))
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,6 @@
|
||||||
#include "raw1394_private.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,
|
int raw1394_start_read(struct raw1394_handle *handle, nodeid_t node,
|
||||||
nodeaddr_t addr, size_t length, quadlet_t *buffer,
|
nodeaddr_t addr, size_t length, quadlet_t *buffer,
|
||||||
unsigned long tag)
|
unsigned long tag)
|
||||||
|
@ -62,12 +48,15 @@ int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
|
||||||
|
|
||||||
#define SYNCFUNC_VARS \
|
#define SYNCFUNC_VARS \
|
||||||
struct sync_cb_data sd = { 0, 0 }; \
|
struct sync_cb_data sd = { 0, 0 }; \
|
||||||
struct raw1394_reqhandle rh = { (req_callback_t)sync_cb, &sd }; \
|
struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, \
|
||||||
|
&sd }; \
|
||||||
int err
|
int err
|
||||||
|
|
||||||
#define SYNCFUNC_BODY \
|
#define SYNCFUNC_BODY \
|
||||||
|
while (!sd.done) { \
|
||||||
if (err < 0) return err; \
|
if (err < 0) return err; \
|
||||||
while (!sd.done) raw1394_loop_iterate(handle); \
|
err = raw1394_loop_iterate(handle); \
|
||||||
|
} \
|
||||||
return sd.errcode
|
return sd.errcode
|
||||||
|
|
||||||
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
|
||||||
|
|
Reference in New Issue