| /* |
| * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. |
| * |
| * Copyright (C) 1999,2000,2001,2002 Andreas Bombe |
| * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at> |
| * 2002 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. |
| * |
| * |
| * Contributions: |
| * |
| * Manfred Weihs <weihs@ict.tuwien.ac.at> |
| * address range mapping |
| * Christian Toegel <christian.toegel@gmx.at> |
| * address range mapping |
| */ |
| |
| #include <config.h> |
| #include <unistd.h> |
| #include <byteswap.h> |
| #include <errno.h> |
| |
| #include "raw1394.h" |
| #include "kernel-raw1394.h" |
| #include "raw1394_private.h" |
| |
| |
| int ieee1394_loop_iterate(struct raw1394_handle *handle) |
| { |
| struct raw1394_request req; |
| ieee1394handle_t ihandle = handle->mode.ieee1394; |
| int retval = 0; |
| |
| while (read(ihandle->fd, &req, sizeof(req)) < 0) { |
| if (errno != EINTR) return -1; |
| } |
| |
| switch (req.type) { |
| case RAW1394_REQ_BUS_RESET: |
| if (ihandle->protocol_version == 3) { |
| ihandle->num_of_nodes = req.misc & 0xffff; |
| ihandle->local_id = req.misc >> 16; |
| } else { |
| ihandle->num_of_nodes = req.misc & 0xff; |
| ihandle->irm_id = ((req.misc >> 8) & 0xff) | 0xffc0; |
| ihandle->local_id = req.misc >> 16; |
| } |
| |
| if (ihandle->bus_reset_handler) { |
| retval = ihandle->bus_reset_handler(handle, |
| req.generation); |
| } |
| break; |
| |
| case RAW1394_REQ_FCP_REQUEST: |
| if (ihandle->fcp_handler) { |
| retval = ihandle->fcp_handler(handle, req.misc & 0xffff, |
| req.misc >> 16, |
| req.length, |
| (unsigned char *)ihandle->buffer); |
| } |
| break; |
| |
| case RAW1394_REQ_ARM: |
| if (ihandle->arm_tag_handler) { |
| retval = ihandle->arm_tag_handler(handle, req.tag, |
| (req.misc & (0xFF)), |
| ((req.misc >> 16) & (0xFFFF)), |
| int2ptr(req.recvb)); |
| } |
| break; |
| |
| case RAW1394_REQ_ECHO: |
| retval=req.misc; |
| break; |
| |
| case RAW1394_REQ_RAWISO_ACTIVITY: |
| retval = _ieee1394_iso_iterate(handle); |
| break; |
| |
| default: |
| if (ihandle->tag_handler) { |
| retval = ihandle->tag_handler(handle, req.tag, |
| req.error); |
| } |
| break; |
| } |
| |
| return retval; |
| } |
| |
| |
| bus_reset_handler_t raw1394_set_bus_reset_handler(struct raw1394_handle *handle, |
| bus_reset_handler_t new) |
| { |
| bus_reset_handler_t old; |
| if (!handle) { |
| errno = EINVAL; |
| return NULL; |
| } |
| if (handle->is_fw) { |
| old = handle->mode.fw->bus_reset_handler; |
| handle->mode.fw->bus_reset_handler = new; |
| } |
| else { |
| old = handle->mode.ieee1394->bus_reset_handler; |
| handle->mode.ieee1394->bus_reset_handler = new; |
| } |
| return old; |
| } |
| |
| tag_handler_t raw1394_set_tag_handler(struct raw1394_handle *handle, |
| tag_handler_t new) |
| { |
| tag_handler_t old; |
| if (!handle) { |
| errno = EINVAL; |
| return NULL; |
| } |
| if (handle->is_fw) { |
| old = handle->mode.fw->tag_handler; |
| handle->mode.fw->tag_handler = new; |
| } |
| else { |
| old = handle->mode.ieee1394->tag_handler; |
| handle->mode.ieee1394->tag_handler = new; |
| } |
| return old; |
| } |
| |
| arm_tag_handler_t raw1394_set_arm_tag_handler(struct raw1394_handle *handle, |
| arm_tag_handler_t new) |
| { |
| arm_tag_handler_t old; |
| if (!handle) { |
| errno = EINVAL; |
| return NULL; |
| } |
| if (handle->is_fw) { |
| old = handle->mode.fw->arm_tag_handler; |
| handle->mode.fw->arm_tag_handler = new; |
| } |
| else { |
| old = handle->mode.ieee1394->arm_tag_handler; |
| handle->mode.ieee1394->arm_tag_handler = new; |
| } |
| return old; |
| } |
| |
| fcp_handler_t raw1394_set_fcp_handler(struct raw1394_handle *handle, |
| fcp_handler_t new) |
| { |
| fcp_handler_t old; |
| if (!handle) { |
| errno = EINVAL; |
| return NULL; |
| } |
| if (handle->is_fw) { |
| old = handle->mode.fw->fcp_handler; |
| handle->mode.fw->fcp_handler = new; |
| } |
| else { |
| old = handle->mode.ieee1394->fcp_handler; |
| handle->mode.ieee1394->fcp_handler = new; |
| } |
| return old; |
| } |