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