summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar abombe 1999-12-29 22:24:32 +0000
committerGravatar abombe 1999-12-29 22:24:32 +0000
commit04f65912c3c04161daee655136d8d74d3763da16 (patch)
tree0e753f84101b58ff77c431bfcc7851f475b7db7c /src
parent- Added FCP register addresses (diff)
Added isochronous I/O support
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@4 53a565d1-3bb7-0310-b661-cf11e63c67ab
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/iso.c64
-rw-r--r--src/kernel-raw1394.h8
-rw-r--r--src/main.c10
-rw-r--r--src/raw1394.h26
-rw-r--r--src/raw1394_private.h7
-rw-r--r--src/readwrite.c29
7 files changed, 116 insertions, 31 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4905126..ab32929 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,12 +3,13 @@
lib_LTLIBRARIES = libraw1394.la
-libraw1394_la_LDFLAGS = -version-info 0:0:0
+libraw1394_la_LDFLAGS = -version-info 1:0:1
libraw1394_la_SOURCES = \
main.c \
eventloop.c \
readwrite.c \
+ iso.c \
kernel-raw1394.h \
raw1394_private.h
diff --git a/src/iso.c b/src/iso.c
new file mode 100644
index 0000000..21abeae
--- /dev/null
+++ b/src/iso.c
@@ -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);
+}
diff --git a/src/kernel-raw1394.h b/src/kernel-raw1394.h
index fe8ea72..b1b0e4b 100644
--- a/src/kernel-raw1394.h
+++ b/src/kernel-raw1394.h
@@ -65,6 +65,11 @@ struct raw1394_khost_list {
#ifdef __KERNEL__
+struct iso_block_store {
+ atomic_t refcount;
+ quadlet_t data[0];
+};
+
struct file_info {
struct list_head list;
@@ -79,6 +84,8 @@ struct file_info {
wait_queue_head_t poll_wait_complete;
u64 listen_channels;
+ quadlet_t *iso_buffer;
+ size_t iso_buffer_length;
};
struct pending_request {
@@ -86,6 +93,7 @@ struct pending_request {
struct file_info *file_info;
struct hpsb_packet *packet;
struct tq_struct tq;
+ struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
struct raw1394_request req;
diff --git a/src/main.c b/src/main.c
index 7cc8fe1..d268f0b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,6 +33,16 @@ static int iso_handler_default(struct raw1394_handle *handle, int channel,
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)
{
diff --git a/src/raw1394.h b/src/raw1394.h
index d1fe443..849369e 100644
--- a/src/raw1394.h
+++ b/src/raw1394.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
* return value of the handler which got executed. Default handlers always
* 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);
@@ -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
* 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);
@@ -112,23 +114,27 @@ struct raw1394_reqhandle {
* 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);
-int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
- nodeaddr_t addr, size_t length, quadlet_t *data,
- unsigned long tag);
+int raw1394_start_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
+ size_t length, quadlet_t *buffer, unsigned long tag);
+int raw1394_start_write(raw1394handle_t handle, nodeid_t node, 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
* will call raw1394_loop_iterate() as often as necessary, return values of
* 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);
-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);
+/*
+ * 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
}
diff --git a/src/raw1394_private.h b/src/raw1394_private.h
index 06c2746..c570d4b 100644
--- a/src/raw1394_private.h
+++ b/src/raw1394_private.h
@@ -17,6 +17,13 @@ struct raw1394_handle {
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 CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request))
diff --git a/src/readwrite.c b/src/readwrite.c
index 37e9f71..192b0a1 100644
--- a/src/readwrite.c
+++ b/src/readwrite.c
@@ -6,20 +6,6 @@
#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)
@@ -60,14 +46,17 @@ int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
-#define SYNCFUNC_VARS \
- struct sync_cb_data sd = { 0, 0 }; \
- struct raw1394_reqhandle rh = { (req_callback_t)sync_cb, &sd }; \
+#define SYNCFUNC_VARS \
+ struct sync_cb_data sd = { 0, 0 }; \
+ struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, \
+ &sd }; \
int err
-#define SYNCFUNC_BODY \
- if (err < 0) return err; \
- while (!sd.done) raw1394_loop_iterate(handle); \
+#define SYNCFUNC_BODY \
+ while (!sd.done) { \
+ if (err < 0) return err; \
+ err = raw1394_loop_iterate(handle); \
+ } \
return sd.errcode
int raw1394_read(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,