/*
 * 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;
}
