summaryrefslogtreecommitdiffstats
path: root/src/fw.c
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2022-09-20 00:53:10 -0400
committerGravatar Peter McGoron 2022-09-20 00:58:16 -0400
commit48b2af0507fa99bad3b771325b232ad89e60de0a (patch)
treed87f8679fc40e6448430e9a4c913821bc9aa9f39 /src/fw.c
parentconfigure.ac, Changelog, NEWS: update to version 2.1.2 (diff)
Implement virtual memory for ARM manager
Instead of allocating memory for address range mappings (ARM) and handling all reads and writes to said memory, the new ARM manager calls a function for each received request with the data, transaction code, and allocation information. The ARM tag manager now must handle validation of memory accesses and retreive/write the data. This allows implementations to use network resources or generated data as memory. The ARM manager no longer automatically sends response packets. It is the responsibility of the user to send response packets using raw1394_send_rw_response(). The interface is not implemented for raw1394 and will probably never be implemented for raw1394. It is for firewire-cdev (modern Linux) only.
Diffstat (limited to '')
-rw-r--r--src/fw.c221
1 files changed, 53 insertions, 168 deletions
diff --git a/src/fw.c b/src/fw.c
index b9c203d..27eb8b6 100644
--- a/src/fw.c
+++ b/src/fw.c
@@ -31,6 +31,13 @@
*/
#define IMPLEMENTED_CDEV_ABI_VERSION 4
+struct address_closure {
+ int (*callback)(raw1394handle_t handle, struct address_closure *ac,
+ int tcode, unsigned long long offset,
+ int source_node_id, int card, unsigned kernel_handle,
+ size_t length, void *data);
+};
+
int
fw_errcode_to_errno(raw1394_errcode_t errcode)
{
@@ -92,18 +99,25 @@ default_tag_handler(raw1394handle_t handle,
return -1;
}
+/* do nothing */
static int
-default_arm_tag_handler(raw1394handle_t handle, unsigned long arm_tag,
- byte_t type, unsigned int length, void *data)
-{
- struct raw1394_arm_reqhandle *rh;
-
- if (arm_tag == 0)
- return -1;
-
- rh = (struct raw1394_arm_reqhandle *) arm_tag;
-
- return rh->arm_callback(handle, data, length, rh->pcontext, type);
+default_arm_tag_handler(
+ raw1394handle_t handle, raw1394_arm_allocation_t *arm,
+ int tcode, unsigned long long offset, int source_node_id,
+ int card, unsigned kernel_handle, size_t length, void *data
+)
+{
+ (void)handle;
+ (void)arm;
+ (void)tcode;
+ (void)offset;
+ (void)source_node_id;
+ (void)card;
+ (void)kernel_handle;
+ (void)length;
+ (void)data;
+
+ return 0;
}
static int
@@ -214,13 +228,6 @@ handle_lost_device(fw_handle_t handle, int i)
return 0;
}
-struct address_closure {
- int (*callback)(raw1394handle_t handle, struct address_closure *ac,
- int tcode, unsigned long long offset,
- int source_node_id, int card, unsigned kernel_handle,
- size_t length, void *data);
-};
-
static int
handle_fcp_request(raw1394handle_t handle, struct address_closure *ac,
int tcode, unsigned long long offset, int source_node_id,
@@ -310,9 +317,9 @@ handle_device_event(raw1394handle_t handle,
return fwhandle->tag_handler(handle, tag, errcode);
- case FW_CDEV_EVENT_REQUEST:
- ac = u64_to_ptr(u->request.closure);
- return ac->callback(handle, ac, u->request.tcode,
+ case FW_CDEV_EVENT_REQUEST: {
+ raw1394_arm_allocation_t *al = u64_to_ptr(u->response.closure);
+ return fwhandle->arm_tag_handler(handle, al, u->request.tcode,
u->request.offset,
/* wild guess, but can't do better */
fwhandle->devices[i].node_id,
@@ -320,15 +327,15 @@ handle_device_event(raw1394handle_t handle,
u->request.handle,
u->request.length, u->request.data);
- case FW_CDEV_EVENT_REQUEST2:
- ac = u64_to_ptr(u->request.closure);
- return ac->callback(handle, ac, u->request2.tcode,
+ } case FW_CDEV_EVENT_REQUEST2: {
+ raw1394_arm_allocation_t *al = u64_to_ptr(u->response.closure);
+ return fwhandle->arm_tag_handler(handle, al, u->request2.tcode,
u->request2.offset,
u->request2.source_node_id,
u->request2.card,
u->request2.handle,
u->request2.length, u->request2.data);
-
+ }
case FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED:
case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED:
memcpy(u64_to_ptr(u->iso_resource.closure), u,
@@ -769,40 +776,26 @@ struct request_response_block {
};
struct allocation {
- struct address_closure closure; /* must be first member */
+ raw1394_arm_allocation_t info;
struct allocation *next;
__u32 handle;
- byte_t *buffer;
- octlet_t tag;
- arm_options_t access_rights;
- arm_options_t notification_options;
- arm_options_t client_transactions;
- nodeaddr_t offset;
- size_t length;
- unsigned char data[0];
};
-static int
-handle_arm_request(raw1394handle_t handle, struct address_closure *ac,
- int tcode, unsigned long long offset, int source_node_id,
- int card, unsigned kernel_handle, size_t length, void *data)
+int
+fw_send_rw_response(fw_handle_t fwhandle, int tcode, void *data, size_t len,
+ unsigned kernel_handle)
{
- fw_handle_t fwhandle = handle->mode.fw;
- struct allocation *allocation = (struct allocation *) ac;
- struct request_response_block *rrb;
struct fw_cdev_send_response response;
- arm_options_t type;
- size_t in_length;
- int pos, retval;
- pos = offset - allocation->offset;
- response.handle = kernel_handle;
+ if (data == NULL)
+ len = 0;
+ response.handle = kernel_handle;
+ response.data = ptr_to_u64(data);
+ response.length = len;
switch (tcode) {
case TCODE_WRITE_QUADLET_REQUEST:
case TCODE_WRITE_BLOCK_REQUEST:
- type = RAW1394_ARM_WRITE;
- in_length = length;
response.rcode = RCODE_COMPLETE;
response.length = 0;
response.data = 0;
@@ -810,11 +803,7 @@ handle_arm_request(raw1394handle_t handle, struct address_closure *ac,
case TCODE_READ_QUADLET_REQUEST:
case TCODE_READ_BLOCK_REQUEST:
- type = RAW1394_ARM_READ;
- in_length = 0;
response.rcode = RCODE_COMPLETE;
- response.length = length;
- response.data = ptr_to_u64(allocation->data + pos);
break;
case TCODE_LOCK_REQUEST:
@@ -829,84 +818,18 @@ handle_arm_request(raw1394handle_t handle, struct address_closure *ac,
case TCODE_LOCK_BOUNDED_ADD:
case TCODE_LOCK_WRAP_ADD:
case TCODE_LOCK_VENDOR_DEPENDENT:
- type = RAW1394_ARM_LOCK;
- in_length = length;
response.length = 4;
break;
-
- default:
- in_length = 0;
- type = 0;
- break;
}
- if (!(allocation->access_rights & type)) {
- response.rcode = RCODE_TYPE_ERROR;
- response.length = 0;
- response.data = 0;
- if (ioctl(fwhandle->ioctl_fd,
- FW_CDEV_IOC_SEND_RESPONSE, &response) < 0)
- return -1;
- } else if (!(allocation->client_transactions & type)) {
- if (type == RAW1394_ARM_WRITE)
- memcpy(allocation->data + pos, data, length);
- else if (type == RAW1394_ARM_LOCK)
- /* FIXME: do lock ops here */;
-
- if (ioctl(fwhandle->ioctl_fd,
- FW_CDEV_IOC_SEND_RESPONSE, &response) < 0)
- return -1;
- }
-
- /*
- * libraw1394 clients do not expect requests from nodes on
- * a card other than the one set by raw1394_set_port().
- */
- if (card != fwhandle->card)
- return 0;
-
- if (!(allocation->notification_options & type))
- return 0;
-
- rrb = malloc(sizeof *rrb + in_length + response.length);
- if (rrb == NULL) {
- errno = ENOMEM;
+ if (ioctl(fwhandle->ioctl_fd, FW_CDEV_IOC_SEND_RESPONSE, &response) < 0)
return -1;
- }
-
- rrb->request_response.request = &rrb->request;
- rrb->request_response.response = &rrb->response;
-
- rrb->request.destination_nodeid = fwhandle->reset.local_node_id;
- rrb->request.source_nodeid = source_node_id;
- rrb->request.destination_offset = offset;
- rrb->request.tlabel = 0;
- if (tcode < 0x10) {
- rrb->request.tcode = tcode;
- rrb->request.extended_transaction_code = 0;
- } else {
- rrb->request.tcode = TCODE_LOCK_REQUEST;
- rrb->request.extended_transaction_code = tcode - 0x10;
- }
- rrb->request.generation = fwhandle->reset.generation;
- rrb->request.buffer_length = in_length;
- rrb->request.buffer = rrb->data;
- memcpy(rrb->request.buffer, data, in_length);
-
- rrb->response.response_code = response.rcode;
- rrb->response.buffer_length = response.length;
- rrb->response.buffer = rrb->data + in_length;
- memcpy(rrb->response.buffer, allocation->data + pos, response.length);
-
- retval = fwhandle->arm_tag_handler(handle, allocation->tag, type,
- length, &rrb->request_response);
- free(rrb);
- return retval;
+ return 0;
}
int
fw_arm_register(fw_handle_t handle, nodeaddr_t start,
- size_t length, byte_t *initial_value,
+ size_t length,
octlet_t arm_tag, arm_options_t access_rights,
arm_options_t notification_options,
arm_options_t client_transactions)
@@ -915,26 +838,22 @@ fw_arm_register(fw_handle_t handle, nodeaddr_t start,
struct allocation *allocation;
int retval;
- allocation = malloc(sizeof *allocation + length);
+ allocation = malloc(sizeof *allocation);
if (allocation == NULL) {
errno = ENOMEM;
return -1;
}
- allocation->closure.callback = handle_arm_request;
- allocation->buffer = initial_value;
- allocation->tag = arm_tag;
- allocation->access_rights = access_rights;
- allocation->notification_options = notification_options;
- allocation->client_transactions = client_transactions;
- allocation->offset = start;
- allocation->length = length;
- if (initial_value != NULL)
- memcpy(allocation->data, initial_value, length);
+ allocation->info.tag = arm_tag;
+ allocation->info.access_rights = access_rights;
+ allocation->info.notification_options = notification_options;
+ allocation->info.client_transactions = client_transactions;
+ allocation->info.offset = start;
+ allocation->info.length = length;
request.offset = start;
request.length = length;
- request.closure = ptr_to_u64(&allocation->closure);
+ request.closure = ptr_to_u64(allocation);
request.region_end = start + length;
retval = ioctl(handle->ioctl_fd, FW_CDEV_IOC_ALLOCATE, &request);
@@ -957,7 +876,7 @@ lookup_allocation(fw_handle_t handle, nodeaddr_t start, int delete)
prev = &handle->allocations;
for (a = handle->allocations; a != NULL; a = a->next) {
- if (a->offset <= start && start < a->offset + a->length)
+ if (a->info.offset <= start && start < a->info.offset + a->info.length)
break;
prev = &a->next;
}
@@ -987,40 +906,6 @@ fw_arm_unregister(fw_handle_t handle, nodeaddr_t start)
}
int
-fw_arm_set_buf(fw_handle_t handle, nodeaddr_t start,
- size_t length, void *buf)
-{
- struct allocation *allocation;
-
- allocation = lookup_allocation(handle, start, 0);
- if (allocation == NULL) {
- errno = ENOENT;
- return -1;
- }
-
- memcpy(allocation->data + allocation->offset - start, buf, length);
-
- return 0;
-}
-
-int
-fw_arm_get_buf(fw_handle_t handle, nodeaddr_t start,
- size_t length, void *buf)
-{
- struct allocation *allocation;
-
- allocation = lookup_allocation(handle, start, 0);
- if (allocation == NULL) {
- errno = ENOENT;
- return -1;
- }
-
- memcpy(buf, allocation->data + allocation->offset - start, length);
-
- return 0;
-}
-
-int
fw_echo_request(fw_handle_t handle, quadlet_t data)
{
return write(handle->pipe_fds[1], &data, sizeof data);