153 lines
5.3 KiB
C
153 lines
5.3 KiB
C
/*
|
|
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
|
|
*
|
|
* Copyright (C) 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
|
|
* 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.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "raw1394.h"
|
|
#include "kernel-raw1394.h"
|
|
#include "raw1394_private.h"
|
|
|
|
/*
|
|
* 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 ieee1394_arm_register(struct ieee1394_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)
|
|
{
|
|
int retval=0;
|
|
struct raw1394_request req;
|
|
|
|
if (((start & ~(0xFFFFFFFF)) != 0) ||
|
|
(((start + length) & ~(0xFFFFFFFF)) != 0)) {
|
|
errno = EINVAL;
|
|
return (-1);
|
|
}
|
|
CLEAR_REQ(&req);
|
|
req.type = RAW1394_REQ_ARM_REGISTER;
|
|
req.generation = handle->generation; /* not necessary */
|
|
req.address = start;
|
|
req.length = length;
|
|
req.tag = arm_tag;
|
|
req.recvb = ptr2int(handle->buffer); /* arm_handle on success */
|
|
req.misc = ((client_transactions & 0x0f) << 8)|((notification_options & 0x0F) << 4)|(access_rights & 0x0F)
|
|
|((ARM_REC_LENGTH & 0xFFFF) << 16);
|
|
req.sendb = ptr2int(initial_value);
|
|
retval = (int) write(handle->fd, &req, sizeof(req));
|
|
return (retval == sizeof(req)) ? 0:-1;
|
|
}
|
|
|
|
/*
|
|
* 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 ieee1394_arm_unregister (struct ieee1394_handle *handle, nodeaddr_t start)
|
|
{
|
|
int retval;
|
|
struct raw1394_request req;
|
|
|
|
CLEAR_REQ(&req);
|
|
req.type = RAW1394_REQ_ARM_UNREGISTER;
|
|
req.generation = handle->generation; /* not necessary */
|
|
req.address = start;
|
|
retval = write(handle->fd, &req, sizeof(req));
|
|
return (retval == sizeof(req)) ? 0:-1;
|
|
}
|
|
|
|
|
|
/*
|
|
* AdressRangeMapping SET BUFFER:
|
|
* start, length .... identifies addressrange
|
|
* buf .............. pointer to buffer
|
|
*
|
|
* This function copies 'length' bytes from user memory area 'buf'
|
|
* to one ARM block in kernel memory area
|
|
* with start offset 'start'.
|
|
*
|
|
* returnvalue: 0 ... success
|
|
* <0 ... failure, and errno - error code
|
|
*/
|
|
int ieee1394_arm_set_buf (struct ieee1394_handle *handle, nodeaddr_t start,
|
|
size_t length, void *buf)
|
|
{
|
|
struct raw1394_request req;
|
|
|
|
CLEAR_REQ(&req);
|
|
|
|
req.type = RAW1394_REQ_ARM_SET_BUF;
|
|
req.sendb = ptr2int(buf);
|
|
req.length = length;
|
|
req.address = start;
|
|
|
|
if (write(handle->fd, &req, sizeof(req)) < 0) return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* AdressRangeMapping GET BUFFER:
|
|
* start, length .... identifies addressrange
|
|
* buf .............. pointer to buffer
|
|
*
|
|
* This function copies 'length' bytes from one
|
|
* ARM block in kernel memory area with start offset `start`
|
|
* to user memory area 'buf'
|
|
*
|
|
* returnvalue: 0 ... success
|
|
* <0 ... failure, and errno - error code
|
|
*/
|
|
int ieee1394_arm_get_buf (struct ieee1394_handle *handle, nodeaddr_t start,
|
|
size_t length, void *buf)
|
|
{
|
|
struct raw1394_request req;
|
|
|
|
CLEAR_REQ(&req);
|
|
|
|
req.type = RAW1394_REQ_ARM_GET_BUF;
|
|
req.recvb = ptr2int(buf);
|
|
req.length = length;
|
|
req.address = start;
|
|
|
|
if (write(handle->fd, &req, sizeof(req)) < 0) return -1;
|
|
|
|
return 0;
|
|
}
|