aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2012-06-18 00:03:37 +0200
committerStefan Richter <stefanr@s5r6.in-berlin.de>2012-06-18 00:19:23 +0200
commit56056a9607b454322759793e260e5d4db9db240e (patch)
treec023dc428c0d3ee9c62a77ce957a4cb4623561cc
parentf3c9af36c29428caa872fa67f20c958d52a5fb21 (diff)
downloadlibraw1394-56056a9607b454322759793e260e5d4db9db240e.tar.gz
Tweak raw1394_add_config_rom_descriptor() API, add documentation and test case
To conform with 'size' arguments of other libraw1394 calls, change the one in raw1394_add_config_rom_descriptor() from quadlets to bytes. This breaks runtime compatibility with potential clients that were written against B.J.'s original patch, hence reorder arguments just to break compatibility also at compile time. Change errno to ENOSYS (function not implemented) when called while running on top of raw1394. Allow &token to be NULL for convenience of clients which don't require raw1394_remove_config_rom_descriptor(). Add exhaustive documentation. Much of it is copied from the documentation of the underlying ioctl. Add example code which doubles as unit test in testlibraw. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--src/dispatch.c19
-rw-r--r--src/fw.c31
-rw-r--r--src/fw.h11
-rw-r--r--src/raw1394.h63
-rw-r--r--tools/testlibraw.c45
5 files changed, 128 insertions, 41 deletions
diff --git a/src/dispatch.c b/src/dispatch.c
index 1cc8e6a..601ee78 100644
--- a/src/dispatch.c
+++ b/src/dispatch.c
@@ -519,27 +519,24 @@ int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
new_rom, size, rom_version);
}
-int raw1394_add_config_rom_descriptor(raw1394handle_t handle,
- const quadlet_t immediate_key,
- const quadlet_t key,
- const quadlet_t *new_rom_directory,
- size_t size,
- __u32 *out_token)
+int raw1394_add_config_rom_descriptor(raw1394handle_t handle, u_int32_t *token,
+ quadlet_t immediate_key, quadlet_t key,
+ const quadlet_t *data, size_t size)
{
if (!handle) {
errno = EINVAL;
return -1;
}
if (handle->is_fw)
- return fw_add_config_rom_descriptor(handle->mode.fw,
- immediate_key, key, new_rom_directory, size, out_token);
+ return fw_add_config_rom_descriptor(handle->mode.fw, token,
+ immediate_key, key, data, size);
else {
- errno = EINVAL;
+ errno = ENOSYS;
return -1;
}
}
-int raw1394_remove_config_rom_descriptor(raw1394handle_t handle, __u32 token)
+int raw1394_remove_config_rom_descriptor(raw1394handle_t handle, u_int32_t token)
{
if (!handle) {
errno = EINVAL;
@@ -548,7 +545,7 @@ int raw1394_remove_config_rom_descriptor(raw1394handle_t handle, __u32 token)
if (handle->is_fw)
return fw_remove_config_rom_descriptor(handle->mode.fw, token);
else {
- errno = EINVAL;
+ errno = ENOSYS;
return -1;
}
}
diff --git a/src/fw.c b/src/fw.c
index da275c5..877a6ad 100644
--- a/src/fw.c
+++ b/src/fw.c
@@ -1543,35 +1543,34 @@ fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
}
int
-fw_add_config_rom_descriptor(fw_handle_t handle,
- const quadlet_t immediate_key,
- const quadlet_t key,
- const quadlet_t *new_rom_directory,
- size_t size,
- __u32 *out_token)
+fw_add_config_rom_descriptor(fw_handle_t handle, u_int32_t *token,
+ quadlet_t immediate_key, quadlet_t key,
+ const quadlet_t *data, size_t size)
{
struct fw_cdev_add_descriptor request;
- int retval;
+ int err;
request.immediate = immediate_key;
request.key = key;
- request.data = ptr_to_u64(new_rom_directory);
- request.length = size;
+ request.data = ptr_to_u64(data);
+ request.length = size / 4;
request.handle = 0;
- retval = ioctl(handle->local_device->fd, FW_CDEV_IOC_ADD_DESCRIPTOR,
- &request);
- if (retval < 0)
- return -1;
+ err = ioctl(handle->local_device->fd, FW_CDEV_IOC_ADD_DESCRIPTOR,
+ &request);
+ if (err)
+ return err;
+
+ if (token)
+ *token = request.handle;
- *out_token = request.handle;
return 0;
}
int
-fw_remove_config_rom_descriptor(fw_handle_t handle, __u32 token)
+fw_remove_config_rom_descriptor(fw_handle_t handle, u_int32_t token)
{
- struct fw_cdev_remove_descriptor request = {token};
+ struct fw_cdev_remove_descriptor request = {.handle = token};
return ioctl(handle->local_device->fd, FW_CDEV_IOC_REMOVE_DESCRIPTOR,
&request);
diff --git a/src/fw.h b/src/fw.h
index e64b2f3..cb1df01 100644
--- a/src/fw.h
+++ b/src/fw.h
@@ -202,13 +202,10 @@ int fw_start_fcp_listen(fw_handle_t handle);
int fw_stop_fcp_listen(fw_handle_t handle);
int fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
size_t size, unsigned char rom_version);
-int fw_add_config_rom_descriptor(fw_handle_t handle,
- const quadlet_t immediate_key,
- const quadlet_t key,
- const quadlet_t *new_rom_directory,
- size_t size,
- __u32 *out_token);
-int fw_remove_config_rom_descriptor(fw_handle_t handle, __u32 token);
+int fw_add_config_rom_descriptor(fw_handle_t handle, u_int32_t *token,
+ quadlet_t immediate_key, quadlet_t key,
+ const quadlet_t *data, size_t size);
+int fw_remove_config_rom_descriptor(fw_handle_t handle, u_int32_t token);
int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
size_t buffersize, size_t *rom_size,
unsigned char *rom_version);
diff --git a/src/raw1394.h b/src/raw1394.h
index 7239de3..312c3b3 100644
--- a/src/raw1394.h
+++ b/src/raw1394.h
@@ -1160,18 +1160,69 @@ const char *raw1394_get_libversion(void);
* Returns: -1 (failure) if the version is incorrect,
* -2 (failure) if the new rom version is too big, or
* 0 for success
+ *
+ * This function always fails on current kernels.
**/
int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
*new_rom, size_t size, unsigned char rom_version);
-int raw1394_add_config_rom_descriptor(raw1394handle_t handle,
- const quadlet_t immediate_key,
- const quadlet_t key,
- const quadlet_t *new_rom_directory,
- size_t size,
- u_int32_t *out_token);
+/**
+ * raw1394_add_config_rom_descriptor - add contents to local Configuration ROM
+ * @handle: libraw1394 handle
+ * @token: handle of the Configuration ROM contents, written by libraw1394
+ * @immediate_key: if non-zero, immediate key to insert before pointer
+ * @key: upper 8 bits of root directory pointer
+ * @data: pointer to contents of descriptor block
+ * @size: size of descriptor block data, in bytes
+ *
+ * Add a directory, descriptor, or leaf block and optionally a preceding
+ * immediate key to the local node's Configuration ROM. If successful, the
+ * kernel adds the descriptor and generates a bus reset to signal the change of
+ * the Configuration ROM to other nodes. Note, on a system with multiple cards
+ * (multiple libraw1394 ports), the Configuration ROM of all local nodes is
+ * changed, not just the one which corresponds to the @handle.
+ *
+ * The changes to the Configuration ROM will be reverted when the client exits,
+ * or by raw1394_destroy_handle(), or by raw1394_remove_config_rom_descriptor().
+ * In order to be able to call the latter, the client needs to provide @token as
+ * pointer to an u_int32_t variable; otherwise @token may be NULL.
+ *
+ * @key specifies the upper 8 bits of the descriptor root directory pointer and
+ * @data and @size specify the contents. The @key should be of the form
+ * 0xXX000000. The offset part of the root directory entry will be filled in by
+ * the kernel.
+ *
+ * If not 0, @immediate_key specifies an immediate key which will be inserted
+ * before the root directory pointer.
+ *
+ * A directory can be added together with further subdirectories or descriptors
+ * or other leaves; just provide all data concatenated in @data and set the
+ * respective offsets in your directory entries.
+ *
+ * The CRC in the first quadlet of any directory, subdirectory, leaf or
+ * descriptor may be left blank. The kernel will compute and fill in these
+ * CRCs.
+ *
+ * @immediate_key, @key, and @data array elements are host-endian quadlets.
+ *
+ * Returns: 0 on success or -1 on failure (sets errno)
+ *
+ * History: New function in libraw1394 v2.1.0.
+ **/
+int raw1394_add_config_rom_descriptor(raw1394handle_t handle, u_int32_t *token,
+ quadlet_t immediate_key, quadlet_t key,
+ const quadlet_t *data, size_t size);
+/**
+ * raw1394_remove_config_rom_descriptor - remove contents from Configuration ROM
+ * @handle: libraw1394 handle
+ * @token: handle of the Configuration ROM contents
+ *
+ * Returns: 0 on success or -1 on failure (sets errno)
+ *
+ * History: New function in libraw1394 v2.1.0.
+ **/
int raw1394_remove_config_rom_descriptor(raw1394handle_t handle,
u_int32_t token);
diff --git a/tools/testlibraw.c b/tools/testlibraw.c
index 6547c00..8fe8b26 100644
--- a/tools/testlibraw.c
+++ b/tools/testlibraw.c
@@ -15,6 +15,7 @@
#include <sys/poll.h>
#include <stdlib.h>
#include <time.h>
+#include <unistd.h>
#include <arpa/inet.h>
#include "../src/raw1394.h"
@@ -117,10 +118,36 @@ read_topology_map(raw1394handle_t handle)
printf(" 0x%08x\n", ntohl(map[3 + i]));
}
+static const quadlet_t unit_directory_data[] = {
+ 0x00060000, /* directory_length (CRC left blank) */
+ 0x1258595a, /* a bogus unit_specifier_id: XYZ */
+ 0x13616263, /* unit_sw_version: abc */
+ 0x036c7277, /* a bogus vendor OUI: lrw */
+ 0x81000003, /* textual descriptor offset */
+ 0x17000001, /* model: 1 */
+ 0x81000007, /* textual descriptor offset */
+
+ 0x00050000, /* descriptor_length (CRC left blank) */
+ 0x00000000, /* descriptor_type: text */
+ 0x00000000, /* minimal ASCII, English */
+ 0x6c696272, /* "libr" */
+ 0x61773133, /* "aw13" */
+ 0x39340000, /* "94" */
+
+ 0x00050000, /* descriptor_length (CRC left blank) */
+ 0x00000000, /* descriptor_type: text */
+ 0x00000000, /* minimal ASCII, English */
+ 0x74657374, /* "test" */
+ 0x6c696272, /* "libr" */
+ 0x61770000, /* "aw" */
+};
+#define IEEE1212_KEY_UNIT_DIRECTORY 0xd1000000
+
static void
test_config_rom(raw1394handle_t handle)
{
quadlet_t rom[0x100] = { 0, };
+ u_int32_t token;
size_t rom_size;
unsigned char rom_version;
int i, retval;
@@ -135,7 +162,23 @@ test_config_rom(raw1394handle_t handle)
printf(" 0x%08x\n", rom[i]);
retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
- printf(" update_config_rom returned %d\n", retval);
+ perror(" raw1394_update_config_rom failed with error");
+
+ retval = raw1394_add_config_rom_descriptor(handle, &token,
+ 0, IEEE1212_KEY_UNIT_DIRECTORY,
+ unit_directory_data, sizeof(unit_directory_data));
+ if (retval) {
+ printf(" raw1394_add_config_rom_descriptor failed with error");
+ return;
+ }
+
+ printf(" added unit '0x58595a:0x616263', reverting in 5 seconds\n");
+ sleep(5);
+ retval = raw1394_remove_config_rom_descriptor(handle, token);
+ if (retval)
+ printf(" raw1394_remove_config_rom_descriptor failed with error");
+ else
+ printf(" unit '0x58595a:0x616263' removed\n");
}
static void