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>
This commit is contained in:
parent
f3c9af36c2
commit
56056a9607
|
@ -519,27 +519,24 @@ int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
|
||||||
new_rom, size, rom_version);
|
new_rom, size, rom_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
int raw1394_add_config_rom_descriptor(raw1394handle_t handle,
|
int raw1394_add_config_rom_descriptor(raw1394handle_t handle, u_int32_t *token,
|
||||||
const quadlet_t immediate_key,
|
quadlet_t immediate_key, quadlet_t key,
|
||||||
const quadlet_t key,
|
const quadlet_t *data, size_t size)
|
||||||
const quadlet_t *new_rom_directory,
|
|
||||||
size_t size,
|
|
||||||
__u32 *out_token)
|
|
||||||
{
|
{
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (handle->is_fw)
|
if (handle->is_fw)
|
||||||
return fw_add_config_rom_descriptor(handle->mode.fw,
|
return fw_add_config_rom_descriptor(handle->mode.fw, token,
|
||||||
immediate_key, key, new_rom_directory, size, out_token);
|
immediate_key, key, data, size);
|
||||||
else {
|
else {
|
||||||
errno = EINVAL;
|
errno = ENOSYS;
|
||||||
return -1;
|
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) {
|
if (!handle) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
@ -548,7 +545,7 @@ int raw1394_remove_config_rom_descriptor(raw1394handle_t handle, __u32 token)
|
||||||
if (handle->is_fw)
|
if (handle->is_fw)
|
||||||
return fw_remove_config_rom_descriptor(handle->mode.fw, token);
|
return fw_remove_config_rom_descriptor(handle->mode.fw, token);
|
||||||
else {
|
else {
|
||||||
errno = EINVAL;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
src/fw.c
29
src/fw.c
|
@ -1543,35 +1543,34 @@ fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fw_add_config_rom_descriptor(fw_handle_t handle,
|
fw_add_config_rom_descriptor(fw_handle_t handle, u_int32_t *token,
|
||||||
const quadlet_t immediate_key,
|
quadlet_t immediate_key, quadlet_t key,
|
||||||
const quadlet_t key,
|
const quadlet_t *data, size_t size)
|
||||||
const quadlet_t *new_rom_directory,
|
|
||||||
size_t size,
|
|
||||||
__u32 *out_token)
|
|
||||||
{
|
{
|
||||||
struct fw_cdev_add_descriptor request;
|
struct fw_cdev_add_descriptor request;
|
||||||
int retval;
|
int err;
|
||||||
|
|
||||||
request.immediate = immediate_key;
|
request.immediate = immediate_key;
|
||||||
request.key = key;
|
request.key = key;
|
||||||
request.data = ptr_to_u64(new_rom_directory);
|
request.data = ptr_to_u64(data);
|
||||||
request.length = size;
|
request.length = size / 4;
|
||||||
request.handle = 0;
|
request.handle = 0;
|
||||||
|
|
||||||
retval = ioctl(handle->local_device->fd, FW_CDEV_IOC_ADD_DESCRIPTOR,
|
err = ioctl(handle->local_device->fd, FW_CDEV_IOC_ADD_DESCRIPTOR,
|
||||||
&request);
|
&request);
|
||||||
if (retval < 0)
|
if (err)
|
||||||
return -1;
|
return err;
|
||||||
|
|
||||||
|
if (token)
|
||||||
|
*token = request.handle;
|
||||||
|
|
||||||
*out_token = request.handle;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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,
|
return ioctl(handle->local_device->fd, FW_CDEV_IOC_REMOVE_DESCRIPTOR,
|
||||||
&request);
|
&request);
|
||||||
|
|
11
src/fw.h
11
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_stop_fcp_listen(fw_handle_t handle);
|
||||||
int fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
|
int fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom,
|
||||||
size_t size, unsigned char rom_version);
|
size_t size, unsigned char rom_version);
|
||||||
int fw_add_config_rom_descriptor(fw_handle_t handle,
|
int fw_add_config_rom_descriptor(fw_handle_t handle, u_int32_t *token,
|
||||||
const quadlet_t immediate_key,
|
quadlet_t immediate_key, quadlet_t key,
|
||||||
const quadlet_t key,
|
const quadlet_t *data, size_t size);
|
||||||
const quadlet_t *new_rom_directory,
|
int fw_remove_config_rom_descriptor(fw_handle_t handle, u_int32_t token);
|
||||||
size_t size,
|
|
||||||
__u32 *out_token);
|
|
||||||
int fw_remove_config_rom_descriptor(fw_handle_t handle, __u32 token);
|
|
||||||
int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
||||||
size_t buffersize, size_t *rom_size,
|
size_t buffersize, size_t *rom_size,
|
||||||
unsigned char *rom_version);
|
unsigned char *rom_version);
|
||||||
|
|
|
@ -1160,18 +1160,69 @@ const char *raw1394_get_libversion(void);
|
||||||
* Returns: -1 (failure) if the version is incorrect,
|
* Returns: -1 (failure) if the version is incorrect,
|
||||||
* -2 (failure) if the new rom version is too big, or
|
* -2 (failure) if the new rom version is too big, or
|
||||||
* 0 for success
|
* 0 for success
|
||||||
|
*
|
||||||
|
* This function always fails on current kernels.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
|
int raw1394_update_config_rom(raw1394handle_t handle, const quadlet_t
|
||||||
*new_rom, size_t size, unsigned char rom_version);
|
*new_rom, size_t size, unsigned char rom_version);
|
||||||
|
|
||||||
int raw1394_add_config_rom_descriptor(raw1394handle_t handle,
|
/**
|
||||||
const quadlet_t immediate_key,
|
* raw1394_add_config_rom_descriptor - add contents to local Configuration ROM
|
||||||
const quadlet_t key,
|
* @handle: libraw1394 handle
|
||||||
const quadlet_t *new_rom_directory,
|
* @token: handle of the Configuration ROM contents, written by libraw1394
|
||||||
size_t size,
|
* @immediate_key: if non-zero, immediate key to insert before pointer
|
||||||
u_int32_t *out_token);
|
* @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,
|
int raw1394_remove_config_rom_descriptor(raw1394handle_t handle,
|
||||||
u_int32_t token);
|
u_int32_t token);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "../src/raw1394.h"
|
#include "../src/raw1394.h"
|
||||||
|
@ -117,10 +118,36 @@ read_topology_map(raw1394handle_t handle)
|
||||||
printf(" 0x%08x\n", ntohl(map[3 + i]));
|
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
|
static void
|
||||||
test_config_rom(raw1394handle_t handle)
|
test_config_rom(raw1394handle_t handle)
|
||||||
{
|
{
|
||||||
quadlet_t rom[0x100] = { 0, };
|
quadlet_t rom[0x100] = { 0, };
|
||||||
|
u_int32_t token;
|
||||||
size_t rom_size;
|
size_t rom_size;
|
||||||
unsigned char rom_version;
|
unsigned char rom_version;
|
||||||
int i, retval;
|
int i, retval;
|
||||||
|
@ -135,7 +162,23 @@ test_config_rom(raw1394handle_t handle)
|
||||||
printf(" 0x%08x\n", rom[i]);
|
printf(" 0x%08x\n", rom[i]);
|
||||||
|
|
||||||
retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
|
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
|
static void
|
||||||
|
|
Reference in New Issue