summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar ddennedy 2002-10-23 21:18:49 +0000
committerGravatar ddennedy 2002-10-23 21:18:49 +0000
commit915a20a96f6fb81249f140a114b94f2b1502149d (patch)
tree78511c7186615b5d3473bd72f9b513ba5d9e00e1 /src
parentconfigure.ac: (diff)
merged weihs branch
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@84 53a565d1-3bb7-0310-b661-cf11e63c67ab
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/eventloop.c33
-rw-r--r--src/kernel-raw1394.h80
-rw-r--r--src/main.c98
-rw-r--r--src/raw1394.h199
-rw-r--r--src/raw1394_private.h13
-rw-r--r--src/readwrite.c145
7 files changed, 555 insertions, 16 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 328a4d6..b6a0140 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,9 +12,10 @@ libraw1394_la_SOURCES = \
readwrite.c \
iso.c \
fcp.c \
+ arm.c \
version.c \
kernel-raw1394.h \
raw1394_private.h
# headers to be installed
-pkginclude_HEADERS = raw1394.h csr.h ieee1394.h
+pkginclude_HEADERS = raw1394.h csr.h ieee1394.h kernel-raw1394.h
diff --git a/src/eventloop.c b/src/eventloop.c
index 1f19613..4eb83b6 100644
--- a/src/eventloop.c
+++ b/src/eventloop.c
@@ -2,10 +2,20 @@
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
*
* Copyright (C) 1999,2000,2001,2002 Andreas Bombe
+ * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
+ * 2002 Christian Toegel <christian.toegel@gmx.at>
*
* This library is licensed under the GNU Lesser General Public License (LGPL),
* version 2.1 or later. See the file COPYING.LIB in the distribution for
* details.
+ *
+ *
+ * Contributions:
+ *
+ * Manfred Weihs <weihs@ict.tuwien.ac.at>
+ * address range mapping
+ * Christian Toegel <christian.toegel@gmx.at>
+ * address range mapping
*/
#include <config.h>
@@ -76,6 +86,17 @@ int raw1394_loop_iterate(struct raw1394_handle *handle)
}
break;
+ case RAW1394_REQ_ARM:
+ if (handle->arm_tag_handler) {
+ retval = handle->arm_tag_handler(handle, req->tag,
+ (req->misc & (0xFF)),
+ ((req->misc >> 16) & (0xFFFF)),
+ int2ptr(req->recvb));
+ }
+ break;
+ case RAW1394_REQ_ECHO:
+ retval=req->misc;
+ break;
default:
if (handle->tag_handler) {
retval = handle->tag_handler(handle, req->tag,
@@ -130,6 +151,18 @@ tag_handler_t raw1394_set_tag_handler(struct raw1394_handle *handle,
return old;
}
+arm_tag_handler_t raw1394_set_arm_tag_handler(struct raw1394_handle *handle,
+ arm_tag_handler_t new)
+{
+ arm_tag_handler_t old;
+
+ old = handle->arm_tag_handler;
+ handle->arm_tag_handler = new;
+
+ return old;
+}
+
+
/**
* raw1394_set_iso_handler - set isochronous packet handler
* @new_h: pointer to new handler
diff --git a/src/kernel-raw1394.h b/src/kernel-raw1394.h
index 98c6298..1fe55d0 100644
--- a/src/kernel-raw1394.h
+++ b/src/kernel-raw1394.h
@@ -14,20 +14,32 @@
#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_SEND 104
+#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_SEND 104
+#define RAW1394_REQ_ASYNC_SEND 105
-#define RAW1394_REQ_ISO_LISTEN 200
-#define RAW1394_REQ_FCP_LISTEN 201
-#define RAW1394_REQ_RESET_BUS 202
+#define RAW1394_REQ_ISO_LISTEN 200
+#define RAW1394_REQ_FCP_LISTEN 201
+#define RAW1394_REQ_RESET_BUS 202
+#define RAW1394_REQ_GET_ROM 203
+#define RAW1394_REQ_UPDATE_ROM 204
+#define RAW1394_REQ_ECHO 205
+
+#define RAW1394_REQ_ARM_REGISTER 300
+#define RAW1394_REQ_ARM_UNREGISTER 301
+
+#define RAW1394_REQ_RESET_NOTIFY 400
+
+#define RAW1394_REQ_PHYPACKET 500
/* kernel to user */
#define RAW1394_REQ_BUS_RESET 10000
#define RAW1394_REQ_ISO_RECEIVE 10001
#define RAW1394_REQ_FCP_REQUEST 10002
+#define RAW1394_REQ_ARM 10003
/* error codes */
#define RAW1394_ERROR_NONE 0
@@ -45,6 +57,17 @@
#define RAW1394_ERROR_ABORTED (-1101)
#define RAW1394_ERROR_TIMEOUT (-1102)
+/* arm_codes */
+#define ARM_READ 1
+#define ARM_WRITE 2
+#define ARM_LOCK 4
+
+#define RAW1394_LONG_RESET 0
+#define RAW1394_SHORT_RESET 1
+
+/* busresetnotify ... */
+#define RAW1394_NOTIFY_OFF 0
+#define RAW1394_NOTIFY_ON 1
#include <asm/types.h>
@@ -69,6 +92,32 @@ struct raw1394_khost_list {
__u8 name[32];
};
+/* moved to raw1394.h to make it available to applications
+typedef struct arm_request {
+ nodeid_t destination_nodeid;
+ nodeid_t source_nodeid;
+ nodeaddr_t destination_offset;
+ u8 tlabel;
+ u8 tcode;
+ u_int8_t extended_transaction_code;
+ u_int32_t generation;
+ arm_length_t buffer_length;
+ byte_t *buffer;
+} *arm_request_t;
+
+typedef struct arm_response {
+ int response_code;
+ arm_length_t buffer_length;
+ byte_t *buffer;
+} *arm_response_t;
+
+typedef struct arm_request_response {
+ struct arm_request *request;
+ struct arm_response *response;
+} *arm_request_response_t;
+
+*/
+
#ifdef __KERNEL__
struct iso_block_store {
@@ -91,11 +140,26 @@ struct file_info {
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
+ struct list_head addr_list;
+
u8 *fcp_buffer;
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
+
+ u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
+};
+
+struct arm_addr {
+ struct list_head addr_list; /* file_info list */
+ u64 start, end;
+ u64 arm_tag;
+ u8 notification_options;
+ u8 access_rights;
+ u64 recvb;
+ u16 rec_length;
+ u8 *addr_space_buffer; /* accessed by read/write/lock */
};
struct pending_request {
diff --git a/src/main.c b/src/main.c
index e8864de..7bb847a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,10 +2,23 @@
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
*
* Copyright (C) 1999,2000,2001,2002 Andreas Bombe
+ * 2001, 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
+ * 2002 Christian Toegel <christian.toegel@gmx.at>
*
* This library is licensed under the GNU Lesser General Public License (LGPL),
* version 2.1 or later. See the file COPYING.LIB in the distribution for
* details.
+ *
+ *
+ * Contributions:
+ *
+ * Manfred Weihs <weihs@ict.tuwien.ac.at>
+ * configuration ROM manipulation
+ * address range mapping
+ * Christian Toegel <christian.toegel@gmx.at>
+ * address range mapping
+ * reset notification control (switch on/off)
+ * reset with selection of type (short/long)
*/
#include <config.h>
@@ -39,6 +52,25 @@ static int tag_handler_default(struct raw1394_handle *handle, unsigned long tag,
}
}
+static int arm_tag_handler_default(struct raw1394_handle *handle, unsigned long tag,
+ byte_t request_type, unsigned int requested_length,
+ void *data)
+{
+ struct raw1394_arm_reqhandle *rh;
+ struct arm_request_response *arm_req_resp;
+
+ if (tag) {
+ rh = (struct raw1394_arm_reqhandle *)tag;
+ arm_req_resp = (struct arm_request_response *) data;
+ return rh->arm_callback(handle, arm_req_resp,
+ requested_length, rh->pcontext,
+ request_type);
+ } else {
+ /* error ... */
+ return -1;
+ }
+}
+
int _raw1394_sync_cb(struct raw1394_handle *unused, struct sync_cb_data *data,
int error)
{
@@ -115,6 +147,7 @@ struct raw1394_handle *raw1394_new_handle(void)
handle->err = 0;
handle->bus_reset_handler = bus_reset_default;
handle->tag_handler = tag_handler_default;
+ handle->arm_tag_handler = arm_tag_handler_default;
memset(handle->iso_handler, 0, sizeof(handle->iso_handler));
return handle;
}
@@ -356,6 +389,21 @@ int raw1394_set_port(struct raw1394_handle *handle, int port)
}
}
+int raw1394_reset_bus_new(struct raw1394_handle *handle, int type)
+{
+ struct raw1394_request *req = &handle->req;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_RESET_BUS;
+ req->generation = handle->generation;
+ req->misc = type;
+
+ if (write(handle->fd, req, sizeof(*req)) < 0) return -1;
+
+ return 0; /* success */
+}
+
/**
* raw1394_reset_bus - initiate bus reset
@@ -368,14 +416,60 @@ int raw1394_set_port(struct raw1394_handle *handle, int port)
**/
int raw1394_reset_bus(struct raw1394_handle *handle)
{
+ return raw1394_reset_bus_new (handle, RAW1394_LONG_RESET);
+}
+
+int raw1394_busreset_notify (struct raw1394_handle *handle,
+ int off_on_switch)
+{
struct raw1394_request *req = &handle->req;
CLEAR_REQ(req);
- req->type = RAW1394_REQ_RESET_BUS;
+ req->type = RAW1394_REQ_RESET_NOTIFY;
req->generation = handle->generation;
+ req->misc = off_on_switch;
if (write(handle->fd, req, sizeof(*req)) < 0) return -1;
- return 0;
+ return 0; /* success */
+}
+
+int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
+ *new_rom, size_t size, unsigned char rom_version)
+{
+ struct raw1394_request *req = &handle->req;
+ int status;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_UPDATE_ROM;
+ req->sendb = (unsigned long) new_rom;
+ req->length = size;
+ req->misc = rom_version;
+ req->recvb = (unsigned long) &status;
+
+ if (write(handle->fd, req, sizeof(*req)) < 0) return -8;
+
+ return status;
+}
+
+int raw1394_get_config_rom(raw1394handle_t handle, quadlet_t *buffer,
+ size_t buffersize, size_t *rom_size, unsigned char *rom_version)
+{
+ struct raw1394_request *req = &handle->req;
+ int status;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_GET_ROM;
+ req->recvb = (unsigned long) buffer;
+ req->length = buffersize;
+ req->tag = (unsigned long) rom_size;
+ req->address = (unsigned long) rom_version;
+ req->sendb = (unsigned long) &status;
+
+ if (write(handle->fd, req, sizeof(*req)) < 0) return -8;
+
+ return status;
}
diff --git a/src/raw1394.h b/src/raw1394.h
index 8d14264..c1f7b16 100644
--- a/src/raw1394.h
+++ b/src/raw1394.h
@@ -1,14 +1,52 @@
#ifndef _LIBRAW1394_RAW1394_H
#define _LIBRAW1394_RAW1394_H
+#define ARM_READ 1
+#define ARM_WRITE 2
+#define ARM_LOCK 4
+
+#define RAW1394_LONG_RESET 0
+#define RAW1394_SHORT_RESET 1
+
+/* busresetnotify ... */
+#define RAW1394_NOTIFY_OFF 0
+#define RAW1394_NOTIFY_ON 1
+
#include <sys/types.h>
+typedef u_int8_t byte_t;
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 u_int8_t phyid_t;
+typedef u_int8_t arm_options_t;
+typedef u_int16_t arm_length_t;
typedef struct raw1394_handle *raw1394handle_t;
+typedef struct arm_request {
+ nodeid_t destination_nodeid;
+ nodeid_t source_nodeid;
+ nodeaddr_t destination_offset;
+ u_int8_t tlabel;
+ u_int8_t tcode;
+ u_int8_t extended_transaction_code;
+ u_int32_t generation;
+ arm_length_t buffer_length;
+ byte_t *buffer;
+} *arm_request_t;
+
+typedef struct arm_response {
+ int response_code;
+ arm_length_t buffer_length;
+ byte_t *buffer;
+} *arm_response_t;
+
+typedef struct arm_request_response {
+ struct arm_request *request;
+ struct arm_response *response;
+} *arm_request_response_t;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -32,6 +70,15 @@ raw1394handle_t raw1394_new_handle(void);
void raw1394_destroy_handle(raw1394handle_t handle);
/*
+ * Switch off/on busreset-notification for handle
+ * return-value:
+ * ==0 success
+ * !=0 failure
+ * off_on_switch .... RAW1394_NOTIFY_OFF or RAW1394_NOTIFY_ON
+ */
+int raw1394_busreset_notify (raw1394handle_t handle, int off_on_switch);
+
+/*
* 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.
*/
@@ -77,6 +124,15 @@ int raw1394_set_port(raw1394handle_t handle, int port);
int raw1394_reset_bus(raw1394handle_t handle);
/*
+ * Reset the connected bus (with certain type).
+ * return-value:
+ * -1 failure
+ * 0 success
+ * type .... RAW1394_SHORT_RESET or RAW1394_LONG_RESET
+ */
+int raw1394_reset_bus_new(raw1394handle_t handle, int type);
+
+/*
* 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
@@ -120,6 +176,17 @@ tag_handler_t raw1394_set_tag_handler(raw1394handle_t handle,
tag_handler_t new_h);
/*
+ * Set the handler that will be called when an async read/write/lock arm_request
+ * arrived. The default action is to call the arm_callback in the
+ * raw1394_arm_reqhandle pointed to by arm_tag. Returns old handler.
+ */
+typedef int (*arm_tag_handler_t)(raw1394handle_t handle, unsigned long arm_tag,
+ byte_t request_type, unsigned int requested_length,
+ void *data);
+arm_tag_handler_t raw1394_set_arm_tag_handler(raw1394handle_t handle,
+ arm_tag_handler_t new_h);
+
+/*
* 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.
*
@@ -159,6 +226,91 @@ struct raw1394_reqhandle {
};
/*
+ * This is the genereal arm-request handle. (arm...address range mapping)
+ * It is used by the default arm-tag handler when a request has been
+ * received, it calls the arm_callback.
+ */
+typedef int (*arm_req_callback_t) (raw1394handle_t,
+ struct arm_request_response *arm_req_resp,
+ unsigned int requested_length,
+ void *pcontext, byte_t request_type);
+
+struct raw1394_arm_reqhandle {
+ arm_req_callback_t arm_callback;
+ void *pcontext;
+};
+
+/*
+ * AdressRangeMapping REGISTERING:
+ * start, length .... identifies addressrange
+ * *initial_value ... pointer to buffer containing (if necessary) initial value
+ * NULL means undefined
+ * arm_tag .......... identifier for arm_tag_handler
+ * (usually pointer to raw1394_arm_reqhandle)
+ * access_rights .... access-rights for registered addressrange handled
+ * by kernel-part. Value is one or more binary or of the
+ * following flags: ARM_READ, ARM_WRITE, ARM_LOCK
+ * notification_options ... identifies for which type of request you want
+ * to be notified. Value is one or more binary or of the
+ * following flags: ARM_READ, ARM_WRITE, ARM_LOCK
+ * client_transactions ... identifies for which type of request you want
+ * to handle the request by the client application.
+ * for those requests no response will be generated, but
+ * has to be generated by the application.
+ * Value is one or more binary or of the
+ * following flags: ARM_READ, ARM_WRITE, ARM_LOCK
+ * For each bit set here, notification_options and
+ * access_rights will be ignored.
+ * returnvalue: 0 ... success
+ * <0 ... failure
+ */
+int raw1394_arm_register(struct raw1394_handle *handle, nodeaddr_t start,
+ size_t length, byte_t *initial_value,
+ octlet_t arm_tag, arm_options_t access_rights,
+ arm_options_t notification_options,
+ arm_options_t client_transactions);
+/*
+ * AdressRangeMapping UNREGISTERING:
+ * start ............ identifies addressrange for unregistering
+ * (value of start have to be the same value
+ * used for registering this adressrange)
+ * returnvalue: 0 ... success
+ * <0 ... failure
+ */
+int raw1394_arm_unregister(raw1394handle_t handle, nodeaddr_t start);
+
+/*
+ * send an echo request to the driver. the driver then send back the
+ * same request. raw1394_loop_iterate will return data as return value,
+ * when it processes the echo.
+ *
+ * data: arbitrary data; raw1394_loop_iterate will return it
+ * returnvalue: 0 .... success
+ * <0 ... failure
+ */
+int raw1394_echo_request(struct raw1394_handle *handle, quadlet_t data);
+
+/*
+ * wake up raw1394_loop_iterate (or a blocking read from the device
+ * file). actually this calls raw1394_echo_request with 0 as data.
+ *
+ * returnvalue: 0 .... success
+ * <0 ... failure
+ */
+int raw1394_wake_up(raw1394handle_t handle);
+
+
+/*
+ * send physical request such as linkon, physicalconfigurationpacket ... etc.
+ *
+ * returnvalue: 0 .... success
+ * <0 ... failure
+ */
+int raw1394_phy_packet_write (raw1394handle_t handle, quadlet_t data);
+int raw1394_start_phy_packet_write(raw1394handle_t handle,
+ quadlet_t data, unsigned long tag);
+
+/*
* Passes custom tag. Use pointer to raw1394_reqhandle if you use the standard
* tag handler.
*/
@@ -169,11 +321,30 @@ int raw1394_start_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
int raw1394_start_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
unsigned int extcode, quadlet_t data, quadlet_t arg,
quadlet_t *result, unsigned long tag);
+int raw1394_start_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
+ unsigned int extcode, octlet_t data, octlet_t arg,
+ octlet_t *result, unsigned long tag);
int raw1394_start_iso_write(raw1394handle_t handle, unsigned int channel,
unsigned int tag, unsigned int sy,
unsigned int speed, size_t length, quadlet_t *data,
unsigned long rawtag);
+
+/* This starts sending an arbitrary async packet. It gets an array of quadlets consisting of
+ header and data (without CRC in between). Header information is always in machine byte order,
+ data (data block as well as quadlet data in a read response for data quadlet) shall be in
+ big endian byte order. expect_response indicates, if we expect a response (i.e. if we will
+ get the tag back after the packet was sent or after a response arrived). length is the length
+ of the complete packet (header_length + length of the data block).
+ The main purpose of this function is to send responses for incoming transactions, that
+ are handled by the application.
+ Do not use that function, unless you really know, what you do! Sending corrupt packet may
+ lead to weird results.
+*/
+int raw1394_start_async_send(raw1394handle_t handle,
+ size_t length, size_t header_length, unsigned int expect_response,
+ quadlet_t *data, unsigned long rawtag);
+
/*
* 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
@@ -186,9 +357,15 @@ int raw1394_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
int raw1394_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
unsigned int extcode, quadlet_t data, quadlet_t arg,
quadlet_t *result);
+int raw1394_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
+ unsigned int extcode, octlet_t data, octlet_t arg,
+ octlet_t *result);
int raw1394_iso_write(raw1394handle_t handle, unsigned int channel,
unsigned int tag, unsigned int sy, unsigned int speed,
size_t length, quadlet_t *data);
+int raw1394_async_send(raw1394handle_t handle,
+ size_t length, size_t header_length, unsigned int expect_response,
+ quadlet_t *data);
/*
* Start and stop receiving a certain isochronous channel. You have to set an
@@ -211,6 +388,28 @@ int raw1394_stop_fcp_listen(raw1394handle_t handle);
*/
const char *raw1394_get_libversion(void);
+
+/* updates the configuration rom of a host. rom_version must be the current
+ * version, otherwise it will fail with return value -1.
+ * Return value -2 indicates that the new rom version is too big.
+ * Return value 0 indicates success
+*/
+
+int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
+ *new_rom, size_t size, unsigned char rom_version);
+
+
+/* reads the current version of the configuration rom of a host.
+ * buffersize is the size of the buffer, rom_size
+ * returns the size of the current rom image.. rom_version is the
+ * version number of the fetched rom.
+ * return value -1 indicates, that the buffer was too small,
+ * 0 indicates success.
+ */
+
+int raw1394_get_config_rom(raw1394handle_t handle, quadlet_t *buffer,
+ size_t buffersize, size_t *rom_size, unsigned char *rom_version);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/raw1394_private.h b/src/raw1394_private.h
index 7b414c8..733feae 100644
--- a/src/raw1394_private.h
+++ b/src/raw1394_private.h
@@ -2,6 +2,9 @@
#ifndef _RAW1394_PRIVATE_H
#define _RAW1394_PRIVATE_H
+#define HBUF_SIZE 8192
+#define ARM_REC_LENGTH 4096
+
struct raw1394_handle {
int fd;
int protocol_version;
@@ -15,12 +18,13 @@ struct raw1394_handle {
void *userdata;
bus_reset_handler_t bus_reset_handler;
- tag_handler_t tag_handler;
- fcp_handler_t fcp_handler;
- iso_handler_t iso_handler[64];
+ tag_handler_t tag_handler;
+ arm_tag_handler_t arm_tag_handler;
+ fcp_handler_t fcp_handler;
+ iso_handler_t iso_handler[64];
struct raw1394_request req;
- quadlet_t buffer[2048];
+ quadlet_t buffer[HBUF_SIZE/4]; /* 2048 */
};
struct sync_cb_data {
@@ -30,7 +34,6 @@ struct sync_cb_data {
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))
#if SIZEOF_VOID_P == 4
diff --git a/src/readwrite.c b/src/readwrite.c
index bb918d4..4573137 100644
--- a/src/readwrite.c
+++ b/src/readwrite.c
@@ -2,15 +2,29 @@
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
*
* Copyright (C) 1999,2000,2001,2002 Andreas Bombe
+ * 2002 Christian Toegel <christian.toegel@gmx.at>
+ * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
*
* This library is licensed under the GNU Lesser General Public License (LGPL),
* version 2.1 or later. See the file COPYING.LIB in the distribution for
* details.
+ *
+ *
+ * Contributions:
+ *
+ * Christian Toegel <christian.toegel@gmx.at>
+ * lock64 request
+ * transmit physical packet
+ * raw1394_echo_request, raw1394_wake_up (interrupt blocking wait)
+ *
+ * Manfred Weihs <weihs@ict.tuwien.ac.at>
+ * raw1394_start_async_send, raw1394_async_send
*/
#include <config.h>
#include <unistd.h>
#include <errno.h>
+#include <string.h>
#include "raw1394.h"
#include "kernel-raw1394.h"
@@ -150,6 +164,44 @@ int raw1394_start_lock(struct raw1394_handle *handle, nodeid_t node,
req->length = 8;
break;
}
+ return (int)write(handle->fd, req, sizeof(*req));
+}
+
+int raw1394_start_lock64(struct raw1394_handle *handle, nodeid_t node,
+ nodeaddr_t addr, unsigned int extcode, octlet_t data,
+ octlet_t arg, octlet_t *result, unsigned long tag)
+{
+ struct raw1394_request *req = &handle->req;
+ octlet_t sendbuf[2];
+
+ if ((extcode > 7) || (extcode == 0)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_LOCK64;
+ req->generation = handle->generation;
+ req->tag = tag;
+
+ req->address = ((__u64)node << 48) | addr;
+ req->sendb = ptr2int(sendbuf);
+ req->recvb = ptr2int(result);
+ req->misc = extcode;
+
+ switch (extcode) {
+ case 3: /* EXTCODE_FETCH_ADD */
+ case 4: /* EXTCODE_LITTLE_ADD */
+ sendbuf[0] = data;
+ req->length = 8;
+ break;
+ default:
+ sendbuf[0] = arg;
+ sendbuf[1] = data;
+ req->length = 16;
+ break;
+ }
return (int)write(handle->fd, req, sizeof(*req));
}
@@ -197,6 +249,25 @@ int raw1394_start_iso_write(struct raw1394_handle *handle, unsigned int channel,
return (int)write(handle->fd, req, sizeof(*req));
}
+int raw1394_start_async_send(struct raw1394_handle *handle,
+ size_t length, size_t header_length, unsigned int expect_response,
+ quadlet_t *data, unsigned long rawtag)
+{
+ struct raw1394_request *req = &handle->req;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_ASYNC_SEND;
+ req->generation = handle->generation;
+ req->tag = rawtag;
+
+ req->length = length;
+ req->misc = (expect_response << 16) | (header_length & 0xffff);
+ req->sendb = ptr2int(data);
+
+ return (int)write(handle->fd, req, sizeof(*req));
+}
+
#define SYNCFUNC_VARS \
struct sync_cb_data sd = { 0, 0 }; \
@@ -247,6 +318,19 @@ int raw1394_lock(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
SYNCFUNC_BODY;
}
+int raw1394_lock64(struct raw1394_handle *handle, nodeid_t node, nodeaddr_t addr,
+ unsigned int extcode, octlet_t data, octlet_t arg,
+ octlet_t *result)
+{
+ SYNCFUNC_VARS;
+
+ err = raw1394_start_lock64(handle, node, addr, extcode, data, arg, result,
+ (unsigned long)&rh);
+
+ SYNCFUNC_BODY;
+}
+
+
int raw1394_iso_write(struct raw1394_handle *handle, unsigned int channel,
unsigned int tag, unsigned int sy, unsigned int speed,
size_t length, quadlet_t *data)
@@ -259,5 +343,66 @@ int raw1394_iso_write(struct raw1394_handle *handle, unsigned int channel,
SYNCFUNC_BODY;
}
+int raw1394_async_send(struct raw1394_handle *handle ,
+ size_t length, size_t header_length, unsigned int expect_response,
+ quadlet_t *data)
+{
+ SYNCFUNC_VARS;
+
+ err = raw1394_start_async_send(handle, length, header_length, expect_response,
+ data, (unsigned long)&rh);
+
+ SYNCFUNC_BODY;
+}
+
+
+
+int raw1394_start_phy_packet_write(struct raw1394_handle *handle,
+ quadlet_t data, unsigned long tag)
+{
+ struct raw1394_request *req = &handle->req;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_PHYPACKET;
+ req->generation = handle->generation;
+ req->tag = tag;
+
+ req->sendb = data;
+
+ return (int)write(handle->fd, req, sizeof(*req));
+}
+
+int raw1394_phy_packet_write (struct raw1394_handle *handle, quadlet_t data)
+{
+ SYNCFUNC_VARS;
+
+ err = raw1394_start_phy_packet_write(handle, data, (unsigned long)&rh);
+
+ SYNCFUNC_BODY; /* return 0 on success */
+}
+
+int raw1394_echo_request(struct raw1394_handle *handle, quadlet_t data)
+{
+ struct raw1394_request *req = &handle->req;
+ int retval=0;
+
+ CLEAR_REQ(req);
+
+ req->type = RAW1394_REQ_ECHO;
+ req->misc = data;
+
+ retval = (int)write(handle->fd, req, sizeof(*req));
+ if (retval == sizeof(*req)) {
+ return 0; /* succcess */
+ }
+ return -1;
+}
+
+int raw1394_wake_up(raw1394handle_t handle)
+{
+ return raw1394_echo_request(handle, 0);
+}
+
#undef SYNCFUNC_VARS
#undef SYNCFUNC_BODY