diff options
| author | 2008-04-30 14:37:28 -0700 | |
|---|---|---|
| committer | 2008-04-30 14:37:28 -0700 | |
| commit | f9681ff59da0acca543ad5d15213c6253114f0ce (patch) | |
| tree | ea1da14c7a5fba1c6c6f1fceff1fb76c25ef8551 /juju | |
| parent | libraw1394.sgml, raw1394.h: remove information about deprecated isochronous (diff) | |
Move the source code files in the juju directory into the src directory and
give them 'fw' names instead of 'juju.'
Diffstat (limited to 'juju')
| -rw-r--r-- | juju/Makefile.am | 8 | ||||
| -rw-r--r-- | juju/juju.h | 257 | ||||
| -rw-r--r-- | juju/raw1394-iso.c | 529 | ||||
| -rw-r--r-- | juju/raw1394.c | 1369 |
4 files changed, 0 insertions, 2163 deletions
diff --git a/juju/Makefile.am b/juju/Makefile.am deleted file mode 100644 index af7501a..0000000 --- a/juju/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -lib_LTLIBRARIES = libraw1394.la - -INCLUDES = -I$(FW_DIR) -libraw1394_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ - -libraw1394_la_SOURCES = raw1394.c raw1394-iso.c juju.h - -pkginclude_HEADERS = ../src/raw1394.h ../src/csr.h ../src/ieee1394.h diff --git a/juju/juju.h b/juju/juju.h deleted file mode 100644 index fc0eba1..0000000 --- a/juju/juju.h +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - * - * juju.h -- Internal header file for raw1394 emulation - * - * Copyright (C) 2007 Kristian Hoegsberg <krh@bitplanet.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __juju_h -#define __juju_h - -#include <stdlib.h> -#include <byteswap.h> -#include <linux/firewire-cdev.h> -#include "../src/raw1394.h" -#include "../src/csr.h" -#include "config.h" - -#define ptr_to_u64(p) ((__u64)(unsigned long)(p)) -#define u64_to_ptr(p) ((void *)(unsigned long)(p)) - -static inline __u32 -be32_to_cpu(__u32 q) -{ - union { char c[4]; __u32 q; } u = { { 1, 0, 0, 0 } }; - - return u.q == 1 ? bswap_32(q) : q; -} - -static inline __u32 -cpu_to_be32(__u32 q) -{ - return be32_to_cpu(q); -} - -#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) - -#define BUFFER_SIZE (16 * 1024) - -#define MAX_PORTS 16 - -struct fw_handle; - -struct epoll_closure { - int (*func)(raw1394handle_t handle, - struct epoll_closure *closure, __uint32_t events); -}; - -struct port { - char device_file[32]; - char *name; - int node_count; - int card; -}; - -#define MAX_DEVICES 63 -#define FILENAME_SIZE 16 - -struct device { - struct epoll_closure closure; - int fd; - int node_id; - int generation; - char filename[FILENAME_SIZE]; -}; - -struct request_closure { - void *data; - size_t length; - unsigned long tag; - struct raw1394_reqhandle reqhandle; -}; - -struct allocation; - -struct fw_handle { - struct port ports[MAX_PORTS]; - int port_count; - int err; - int generation; - void *userdata; - int notify_bus_reset; - - bus_reset_handler_t bus_reset_handler; - tag_handler_t tag_handler; - arm_tag_handler_t arm_tag_handler; - fcp_handler_t fcp_handler; - __u32 fcp_allocation_handle; - struct allocation *allocations; - - int epoll_fd; - int inotify_fd; - int inotify_watch; - int pipe_fds[2]; - - struct epoll_closure pipe_closure; - struct epoll_closure inotify_closure; - - struct device devices[MAX_DEVICES]; - int nodes[MAX_DEVICES]; - int local_fd; - char local_filename[FILENAME_SIZE]; - - struct fw_cdev_event_bus_reset reset; - - struct { - struct epoll_closure closure; - int fd; - int type; - int irq_interval; - int packet_phase; - int packet_count; - int packet_index; - int buf_packets; - int max_packet_size; - int prebuffer; - int start_on_cycle; - enum raw1394_iso_dma_recv_mode recv_mode; - raw1394_iso_xmit_handler_t xmit_handler; - raw1394_iso_recv_handler_t recv_handler; - unsigned char *buffer, *buffer_end, *head; - unsigned char *tail, *first_payload; - - struct fw_cdev_iso_packet *packets; - } iso; - - char buffer[BUFFER_SIZE]; -}; -typedef struct fw_handle *fw_handle_t; - -int fw_loop_iterate(raw1394handle_t handle); -fw_handle_t fw_new_handle(void); -void fw_destroy_handle(fw_handle_t handle); -fw_handle_t fw_new_handle_on_port(int port); -int fw_busreset_notify (fw_handle_t handle, int off_on_switch); -int fw_get_fd(fw_handle_t handle); -nodeid_t fw_get_local_id(fw_handle_t handle); -nodeid_t fw_get_irm_id(fw_handle_t handle); -int fw_get_nodecount(fw_handle_t handle); -int fw_get_port_info(fw_handle_t handle, struct raw1394_portinfo *pinf, - int maxports); -int fw_set_port(fw_handle_t handle, int port); -int fw_reset_bus_new(fw_handle_t handle, int type); -int fw_arm_register(fw_handle_t 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 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); -int fw_arm_get_buf(fw_handle_t handle, nodeaddr_t start, - size_t length, void *buf); -int fw_echo_request(fw_handle_t handle, quadlet_t data); -int fw_wake_up(fw_handle_t handle); -int fw_phy_packet_write (fw_handle_t handle, quadlet_t data); -int fw_start_phy_packet_write(fw_handle_t handle, - quadlet_t data, unsigned long tag); -int fw_start_read(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *buffer, unsigned long tag); -int fw_start_write(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *data, unsigned long tag); -int fw_start_lock(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, quadlet_t data, quadlet_t arg, - quadlet_t *result, unsigned long tag); -int fw_start_lock64(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, octlet_t data, octlet_t arg, - octlet_t *result, unsigned long tag); -int fw_start_async_stream(fw_handle_t handle, unsigned int channel, - unsigned int tag, unsigned int sy, - unsigned int speed, size_t length, quadlet_t *data, - unsigned long rawtag); -int fw_start_async_send(fw_handle_t handle, - size_t length, size_t header_length, - unsigned int expect_response, - quadlet_t *data, unsigned long rawtag); -int fw_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *buffer); -int fw_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *data); -int fw_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, quadlet_t data, quadlet_t arg, - quadlet_t *result); -int fw_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, octlet_t data, octlet_t arg, - octlet_t *result); -int fw_async_stream(fw_handle_t handle, unsigned int channel, - unsigned int tag, unsigned int sy, unsigned int speed, - size_t length, quadlet_t *data); -int fw_async_send(fw_handle_t handle, - size_t length, size_t header_length, - unsigned int expect_response, - quadlet_t *data); -int fw_start_fcp_listen(fw_handle_t handle); -int fw_stop_fcp_listen(fw_handle_t handle); -int fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom, - size_t size, unsigned char rom_version); -int fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer, - size_t buffersize, size_t *rom_size, - unsigned char *rom_version); -int fw_bandwidth_modify (raw1394handle_t handle, - unsigned int bandwidth, - enum raw1394_modify_mode mode); -int fw_channel_modify (raw1394handle_t handle, - unsigned int channel, - enum raw1394_modify_mode mode); - -int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, - int prebuffer_packets); -int fw_iso_recv_start(fw_handle_t handle, int start_on_cycle, - int tag_mask, int sync); -int fw_iso_xmit_write(raw1394handle_t handle, unsigned char *data, - unsigned int len, unsigned char tag, - unsigned char sy); -int fw_iso_xmit_sync(raw1394handle_t handle); -int fw_iso_recv_flush(fw_handle_t handle); -int fw_iso_xmit_init(fw_handle_t handle, - raw1394_iso_xmit_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_speed speed, - int irq_interval); -int fw_iso_recv_init(fw_handle_t handle, - raw1394_iso_recv_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_dma_recv_mode mode, - int irq_interval); -int fw_iso_multichannel_recv_init(fw_handle_t handle, - raw1394_iso_recv_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - int irq_interval); -int fw_iso_recv_listen_channel(fw_handle_t handle, - unsigned char channel); -int fw_iso_recv_unlisten_channel(fw_handle_t handle, - unsigned char channel); -int fw_iso_recv_set_channel_mask(fw_handle_t handle, u_int64_t mask); -void fw_iso_stop(fw_handle_t handle); -void fw_iso_shutdown(fw_handle_t handle); - -#endif diff --git a/juju/raw1394-iso.c b/juju/raw1394-iso.c deleted file mode 100644 index 9fc8779..0000000 --- a/juju/raw1394-iso.c +++ /dev/null @@ -1,529 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - * - * raw1394-iso.c -- Emulation of the raw1394 rawiso API on the juju stack - * - * Copyright (C) 2007 Kristian Hoegsberg <krh@bitplanet.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <string.h> -#include <sys/mman.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <sys/epoll.h> -#include <sys/ioctl.h> - -#include "juju.h" -#include "../src/raw1394_private.h" - -static int -queue_packet(fw_handle_t handle, - unsigned int length, unsigned int header_length, - unsigned char tag, unsigned char sy) -{ - struct fw_cdev_queue_iso queue_iso; - struct fw_cdev_iso_packet *p; - int err; - - p = &handle->iso.packets[handle->iso.packet_index]; - p->control = - FW_CDEV_ISO_PAYLOAD_LENGTH(length) | - FW_CDEV_ISO_TAG(tag) | - FW_CDEV_ISO_SY(sy) | - FW_CDEV_ISO_HEADER_LENGTH(header_length); - - if (handle->iso.packet_phase == handle->iso.irq_interval - 1) - p->control |= FW_CDEV_ISO_INTERRUPT; - - handle->iso.head += length; - handle->iso.packet_count++; - handle->iso.packet_phase++; - handle->iso.packet_index++; - - if (handle->iso.packet_phase == handle->iso.irq_interval) - handle->iso.packet_phase = 0; - - if (handle->iso.head + handle->iso.max_packet_size > handle->iso.buffer_end) - handle->iso.head = handle->iso.buffer; - - /* Queue the packets in the kernel if we filled up the packets - * array or wrapped the payload buffer. */ - if (handle->iso.packet_index == handle->iso.irq_interval || - handle->iso.head == handle->iso.buffer) { - queue_iso.packets = ptr_to_u64(handle->iso.packets); - queue_iso.size = handle->iso.packet_index * sizeof handle->iso.packets[0]; - queue_iso.data = ptr_to_u64(handle->iso.first_payload); - queue_iso.handle = 0; - handle->iso.packet_index = 0; - handle->iso.first_payload = handle->iso.head; - - err = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); - if (err < 0) - return -1; - } -} - -static int -queue_xmit_packets(raw1394handle_t handle, int limit) -{ - fw_handle_t fwhandle = handle->mode.fw; - enum raw1394_iso_disposition d; - unsigned char tag, sy; - int len, cycle, dropped; - - if (fwhandle->iso.xmit_handler == NULL) - return 0; - - while (fwhandle->iso.packet_count < limit) { - - d = fwhandle->iso.xmit_handler(handle, fwhandle->iso.head, - &len, &tag, &sy, cycle, dropped); - - switch (d) { - case RAW1394_ISO_OK: - queue_packet(fwhandle, len, 0, tag, sy); - break; - case RAW1394_ISO_DEFER: - case RAW1394_ISO_AGAIN: - default: - return 0; - case RAW1394_ISO_ERROR: - return -1; - case RAW1394_ISO_STOP: - fw_iso_stop(fwhandle); - return 0; - } - } - - return 0; -} - -int fw_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, - int prebuffer_packets) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct fw_cdev_start_iso start_iso; - int retval; - - if (prebuffer_packets == -1) - prebuffer_packets = fwhandle->iso.irq_interval; - - fwhandle->iso.prebuffer = prebuffer_packets; - fwhandle->iso.start_on_cycle = start_on_cycle; - - queue_xmit_packets(handle, prebuffer_packets); - - if (fwhandle->iso.prebuffer <= fwhandle->iso.packet_count) { - start_iso.cycle = start_on_cycle; - start_iso.handle = 0; - - retval = ioctl(fwhandle->iso.fd, - FW_CDEV_IOC_START_ISO, &start_iso); - if (retval < 0) - return retval; - } - - return queue_xmit_packets(handle, fwhandle->iso.buf_packets); -} - -static int -queue_recv_packets(fw_handle_t handle) -{ - while (handle->iso.packet_count <= handle->iso.buf_packets) - queue_packet(handle, handle->iso.max_packet_size, 4, 0, 0); - - return 0; -} - -static enum raw1394_iso_disposition -flush_recv_packets(raw1394handle_t handle, - struct fw_cdev_event_iso_interrupt *interrupt) -{ - fw_handle_t fwhandle = handle->mode.fw; - enum raw1394_iso_disposition d; - quadlet_t header, *p, *end; - unsigned int len, cycle, dropped; - unsigned char channel, tag, sy; - - p = interrupt->header; - end = (void *) interrupt->header + interrupt->header_length; - cycle = interrupt->cycle; - dropped = 0; - d = RAW1394_ISO_OK; - - while (p < end) { - header = be32_to_cpu(*p++); - len = header >> 16; - tag = (header >> 14) & 0x3; - channel = (header >> 8) & 0x3f; - sy = header & 0x0f; - - d = fwhandle->iso.recv_handler(handle, fwhandle->iso.tail, len, - channel, tag, sy, cycle, dropped); - if (d != RAW1394_ISO_OK) - /* FIXME: we need to save the headers so we - * can restart this loop. */ - break; - cycle++; - - fwhandle->iso.tail += fwhandle->iso.max_packet_size; - fwhandle->iso.packet_count--; - - if (fwhandle->iso.tail + fwhandle->iso.max_packet_size > fwhandle->iso.buffer_end) - fwhandle->iso.tail = fwhandle->iso.buffer; - } - - switch (d) { - case RAW1394_ISO_OK: - case RAW1394_ISO_DEFER: - default: - break; - - case RAW1394_ISO_ERROR: - return -1; - - case RAW1394_ISO_STOP: - fw_iso_stop(fwhandle); - return 0; - } - - queue_recv_packets(fwhandle); - - return 0; -} - -int fw_iso_recv_start(fw_handle_t handle, int start_on_cycle, - int tag_mask, int sync) -{ - struct fw_cdev_start_iso start_iso; - - queue_recv_packets(handle); - - start_iso.cycle = start_on_cycle; - start_iso.tags = - tag_mask == -1 ? FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS : tag_mask; - /* sync is documented as 'not used' */ - start_iso.sync = 0; - start_iso.handle = 0; - - return ioctl(handle->iso.fd, FW_CDEV_IOC_START_ISO, &start_iso); -} - -static int handle_iso_event(raw1394handle_t handle, - struct epoll_closure *closure, __uint32_t events) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct fw_cdev_event_iso_interrupt *interrupt; - int len; - - len = read(fwhandle->iso.fd, fwhandle->buffer, sizeof fwhandle->buffer); - if (len < 0) - return -1; - - interrupt = (struct fw_cdev_event_iso_interrupt *) fwhandle->buffer; - if (interrupt->type != FW_CDEV_EVENT_ISO_INTERRUPT) - return 0; - - switch (fwhandle->iso.type) { - case FW_CDEV_ISO_CONTEXT_TRANSMIT: - fwhandle->iso.packet_count -= fwhandle->iso.irq_interval; - return queue_xmit_packets(handle, fwhandle->iso.buf_packets); - case FW_CDEV_ISO_CONTEXT_RECEIVE: - return flush_recv_packets(handle, interrupt); - default: - /* Doesn't happen. */ - return -1; - } -} - -int fw_iso_xmit_write(raw1394handle_t handle, unsigned char *data, - unsigned int len, unsigned char tag, - unsigned char sy) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct fw_cdev_queue_iso queue_iso; - struct fw_cdev_start_iso start_iso; - struct fw_cdev_iso_packet *p; - - if (len > fwhandle->iso.max_packet_size) { - errno = EINVAL; - return -1; - } - - /* Block until we have space for another packet. */ - while (fwhandle->iso.packet_count + fwhandle->iso.irq_interval > - fwhandle->iso.buf_packets) - fw_loop_iterate(handle); - - memcpy(fwhandle->iso.head, data, len); - if (queue_packet(fwhandle, len, 0, tag, sy) < 0) - return -1; - - /* Start the streaming if it's not already running and if - * we've buffered up enough packets. */ - if (fwhandle->iso.prebuffer > 0 && - fwhandle->iso.packet_count >= fwhandle->iso.prebuffer) { - /* Set this to 0 to indicate that we're running. */ - fwhandle->iso.prebuffer = 0; - start_iso.cycle = fwhandle->iso.start_on_cycle; - start_iso.handle = 0; - - len = ioctl(fwhandle->iso.fd, - FW_CDEV_IOC_START_ISO, &start_iso); - if (len < 0) - return len; - } - - return 0; -} - -int fw_iso_xmit_sync(raw1394handle_t handle) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct fw_cdev_iso_packet skip; - struct fw_cdev_queue_iso queue_iso; - int len; - - skip.control = FW_CDEV_ISO_INTERRUPT | FW_CDEV_ISO_SKIP; - queue_iso.packets = ptr_to_u64(&skip); - queue_iso.size = sizeof skip; - queue_iso.data = 0; - queue_iso.handle = 0; - - len = ioctl(fwhandle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); - if (len < 0) - return -1; - - /* Now that we've queued the skip packet, we'll get an - * interrupt when the transmit buffer is flushed, so all we do - * here is wait. */ - while (fwhandle->iso.packet_count > 0) - fw_loop_iterate(handle); - - /* The iso mainloop thinks that interrutps indicate another - * irq_interval number of packets was sent, so the skip - * interrupt makes it go out of whack. We just reset it. */ - fwhandle->iso.head = fwhandle->iso.buffer; - fwhandle->iso.tail = fwhandle->iso.buffer; - fwhandle->iso.first_payload = fwhandle->iso.buffer; - fwhandle->iso.packet_phase = 0; - fwhandle->iso.packet_count = 0; - - return 0; -} - -int fw_iso_recv_flush(fw_handle_t handle) -{ - /* FIXME: huh, we'll need kernel support here... */ - - return 0; -} - -static unsigned int -round_to_power_of_two(unsigned int value) -{ - unsigned int pot; - - pot = 1; - while (pot < value) - pot <<= 1; - - return pot; -} - -static int -iso_init(fw_handle_t handle, int type, - raw1394_iso_xmit_handler_t xmit_handler, - raw1394_iso_recv_handler_t recv_handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_speed speed, - int irq_interval) -{ - struct fw_cdev_create_iso_context create; - struct epoll_event ep; - int retval, prot; - - if (handle->iso.fd != -1) { - errno = EBUSY; - return -1; - } - - switch (type) { - case FW_CDEV_ISO_CONTEXT_TRANSMIT: - prot = PROT_READ | PROT_WRITE; - break; - case FW_CDEV_ISO_CONTEXT_RECEIVE: - prot = PROT_READ; - break; - default: - errno = EINVAL; - return -1; - } - - handle->iso.type = type; - if (irq_interval < 0) - handle->iso.irq_interval = 256; - else - handle->iso.irq_interval = irq_interval; - handle->iso.xmit_handler = xmit_handler; - handle->iso.recv_handler = recv_handler; - handle->iso.buf_packets = buf_packets; - handle->iso.max_packet_size = round_to_power_of_two(max_packet_size); - handle->iso.packet_phase = 0; - handle->iso.packet_count = 0; - handle->iso.packets = - malloc(handle->iso.irq_interval * sizeof handle->iso.packets[0]); - if (handle->iso.packets == NULL) - return -1; - - handle->iso.fd = open(handle->local_filename, O_RDWR); - if (handle->iso.fd < 0) { - free(handle->iso.packets); - handle->iso.packets = NULL; - return -1; - } - - handle->iso.closure.func = handle_iso_event; - ep.events = EPOLLIN; - ep.data.ptr = &handle->iso.closure; - if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, - handle->iso.fd, &ep) < 0) { - close(handle->iso.fd); - free(handle->iso.packets); - handle->iso.packets = NULL; - return -1; - } - - create.type = type; - create.channel = channel; - create.speed = speed; - create.header_size = 4; - - retval = ioctl(handle->iso.fd, - FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); - if (retval < 0) { - close(handle->iso.fd); - free(handle->iso.packets); - handle->iso.packets = NULL; - return retval; - } - - handle->iso.buffer = - mmap(NULL, buf_packets * handle->iso.max_packet_size, - prot, MAP_SHARED, handle->iso.fd, 0); - - if (handle->iso.buffer == MAP_FAILED) { - close(handle->iso.fd); - free(handle->iso.packets); - handle->iso.packets = NULL; - return -1; - } - - handle->iso.buffer_end = handle->iso.buffer + - buf_packets * handle->iso.max_packet_size; - handle->iso.head = handle->iso.buffer; - handle->iso.tail = handle->iso.buffer; - handle->iso.first_payload = handle->iso.buffer; - - return 0; -} - -int fw_iso_xmit_init(fw_handle_t handle, - raw1394_iso_xmit_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_speed speed, - int irq_interval) -{ - return iso_init(handle, FW_CDEV_ISO_CONTEXT_TRANSMIT, - handler, NULL, buf_packets, max_packet_size, - channel, speed, irq_interval); -} - -int fw_iso_recv_init(fw_handle_t handle, - raw1394_iso_recv_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_dma_recv_mode mode, - int irq_interval) -{ - return iso_init(handle, FW_CDEV_ISO_CONTEXT_RECEIVE, - NULL, handler, buf_packets, max_packet_size, - channel, 0, irq_interval); -} - -int fw_iso_multichannel_recv_init(fw_handle_t handle, - raw1394_iso_recv_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - int irq_interval) -{ - /* FIXME: gah */ - errno = ENOSYS; - return -1; -} - -int fw_iso_recv_listen_channel(fw_handle_t handle, - unsigned char channel) -{ - /* FIXME: multichannel */ - errno = ENOSYS; - return -1; -} - -int fw_iso_recv_unlisten_channel(fw_handle_t handle, - unsigned char channel) -{ - /* FIXME: multichannel */ - errno = ENOSYS; - return -1; -} - -int fw_iso_recv_set_channel_mask(fw_handle_t handle, u_int64_t mask) -{ - /* FIXME: multichannel */ - errno = ENOSYS; - return -1; -} - -void fw_iso_stop(fw_handle_t handle) -{ - struct fw_cdev_stop_iso stop_iso; - - stop_iso.handle = 0; - ioctl(handle->iso.fd, FW_CDEV_IOC_STOP_ISO); - - handle->iso.head = handle->iso.buffer; - handle->iso.tail = handle->iso.buffer; - handle->iso.first_payload = handle->iso.buffer; - handle->iso.packet_phase = 0; - handle->iso.packet_count = 0; -} - -void fw_iso_shutdown(fw_handle_t handle) -{ - munmap(handle->iso.buffer, - handle->iso.buf_packets * handle->iso.max_packet_size); - close(handle->iso.fd); - free(handle->iso.packets); - handle->iso.packets = NULL; -} diff --git a/juju/raw1394.c b/juju/raw1394.c deleted file mode 100644 index 73c8705..0000000 --- a/juju/raw1394.c +++ /dev/null @@ -1,1369 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - * - * raw1394.c -- Emulation of the raw1394 API on the fw stack - * - * Copyright (C) 2007 Kristian Hoegsberg <krh@bitplanet.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <dirent.h> -#include <sys/ioctl.h> -#include <sys/epoll.h> -#include <sys/inotify.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <arpa/inet.h> /* for ntohl and htonl */ - -#include "juju.h" -#include "../src/raw1394_private.h" - -int -fw_errcode_to_errno(raw1394_errcode_t errcode) -{ - switch (errcode) { - - case -RCODE_SEND_ERROR: - case -RCODE_CANCELLED: - case -RCODE_BUSY: - case -RCODE_GENERATION: - case -RCODE_NO_ACK: - return EAGAIN; - - case raw1394_make_errcode(ACK_COMPLETE, RCODE_COMPLETE): - return 0; - case raw1394_make_errcode(ACK_COMPLETE, RCODE_CONFLICT_ERROR): - return EAGAIN; - case raw1394_make_errcode(ACK_COMPLETE, RCODE_DATA_ERROR): - return EREMOTEIO; - case raw1394_make_errcode(ACK_COMPLETE, RCODE_TYPE_ERROR): - return EPERM; - case raw1394_make_errcode(ACK_COMPLETE, RCODE_ADDRESS_ERROR): - return EINVAL; - default: - return EINVAL; - } -} - -static int -fw_to_raw1394_errcode(int rcode) -{ - /* Best effort matching fw extended rcodes to raw1394 err - * code. Since the raw1394 errcode decoding are macros we try - * to convert the fw rcodes to something that looks enough - * like the raw1394 errcodes that we retain ABI compatibility. - * - * Juju rcodes less than 0x10 are standard ieee1394 rcodes, - * which we map to a raw1394 errcode by or'ing in an - * ACK_COMPLETE ack code in the upper 16 bits. Errors - * internal to raw1394 are negative values, but fw encodes - * these errors as rcodes greater than or equal to 0x10. In - * this case, we just the negated value, which will look like - * an raw1394 internal error code. */ - - if (rcode < 0x10) - return raw1394_make_errcode(ACK_COMPLETE, rcode); - else - return -rcode; -} - -static int -default_tag_handler(raw1394handle_t handle, - unsigned long tag, raw1394_errcode_t err) -{ - struct raw1394_reqhandle *rh = (struct raw1394_reqhandle *) tag; - - if (rh != NULL) - return rh->callback(handle, rh->data, err); - - return -1; -} - -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); -} - -static int -default_bus_reset_handler(raw1394handle_t handle, unsigned int gen) -{ - handle->mode.fw->generation = gen; - - return 0; -} - -static int -scan_devices(fw_handle_t handle) -{ - DIR *dir; - struct dirent *de; - char filename[32]; - struct fw_cdev_get_info get_info; - struct fw_cdev_event_bus_reset reset; - int fd, err, i; - struct port *ports; - - ports = handle->ports; - memset(ports, 0, sizeof handle->ports); - dir = opendir(FW_DEVICE_DIR); - if (dir == NULL) - return -1; - - i = 0; - while (1) { - de = readdir(dir); - if (de == NULL) - break; - - if (strncmp(de->d_name, - FW_DEVICE_PREFIX, strlen(FW_DEVICE_PREFIX)) != 0) - continue; - - snprintf(filename, sizeof filename, FW_DEVICE_DIR "/%s", de->d_name); - - fd = open(filename, O_RDWR); - if (fd < 0) - continue; - get_info.version = FW_CDEV_VERSION; - get_info.rom = 0; - get_info.rom_length = 0; - get_info.bus_reset = ptr_to_u64(&reset); - err = ioctl(fd, FW_CDEV_IOC_GET_INFO, &get_info); - close(fd); - - if (err < 0) - continue; - - if (i < MAX_PORTS && reset.node_id == reset.local_node_id) { - strncpy(ports[i].device_file, filename, - sizeof ports[i].device_file); - ports[i].node_count = (reset.root_node_id & 0x3f) + 1; - ports[i].card = get_info.card; - i++; - } - } - closedir(dir); - - handle->port_count = i; - - return 0; -} - -static int -handle_echo_pipe(raw1394handle_t handle, - struct epoll_closure *ec, __uint32_t events) -{ - quadlet_t value; - - if (read(handle->mode.fw->pipe_fds[0], &value, sizeof value) < 0) - return -1; - - return value; -} - -static int -handle_lost_device(fw_handle_t handle, int i) -{ - int phy_id; - - /* The device got unplugged, get rid of it. The fd is - * automatically dropped from the epoll context when we close it. */ - - close(handle->devices[i].fd); - phy_id = handle->devices[i].node_id & 0x3f; - if (handle->nodes[phy_id] == i) - handle->nodes[phy_id] = -1; - handle->devices[i].node_id = -1; - - return 0; -} - -struct address_closure { - int (*callback)(raw1394handle_t handle, struct address_closure *ac, - struct fw_cdev_event_request *request, int i); -}; - -static int -handle_fcp_request(raw1394handle_t handle, struct address_closure *ac, - struct fw_cdev_event_request *request, int i) -{ - struct fw_cdev_send_response response; - int is_response; - - response.handle = request->handle; - response.rcode = RCODE_COMPLETE; - response.length = 0; - response.data = 0; - - if (handle->mode.fw->fcp_handler == NULL) - response.rcode = RCODE_ADDRESS_ERROR; - - if (request->tcode >= TCODE_WRITE_RESPONSE) - response.rcode = RCODE_CONFLICT_ERROR; - - if (ioctl(handle->mode.fw->devices[i].fd, - FW_CDEV_IOC_SEND_RESPONSE, &response) < 0) - return -1; - - if (response.rcode != RCODE_COMPLETE) - return 0; - - is_response = request->offset >= CSR_REGISTER_BASE + CSR_FCP_RESPONSE; - - return handle->mode.fw->fcp_handler(handle, - handle->mode.fw->devices[i].node_id, - is_response, - request->length, - (unsigned char *) request->data); -} - -static int -handle_device_event(raw1394handle_t handle, - struct epoll_closure *ec, __uint32_t events) -{ - fw_handle_t fwhandle = handle->mode.fw; - union fw_cdev_event *u; - struct device *device = (struct device *) ec; - struct address_closure *ac; - struct request_closure *rc; - raw1394_errcode_t errcode; - int len, phy_id; - int i; - - i = device - fwhandle->devices; - if (events == EPOLLHUP) - return handle_lost_device(fwhandle, i); - - len = read(fwhandle->devices[i].fd, - fwhandle->buffer, sizeof fwhandle->buffer); - if (len < 0) - return -1; - - u = (void *) fwhandle->buffer; - switch (u->common.type) { - case FW_CDEV_EVENT_BUS_RESET: - /* Clear old entry, unless it's been overwritten. */ - phy_id = fwhandle->devices[i].node_id & 0x3f; - if (fwhandle->nodes[phy_id] == i) - fwhandle->nodes[phy_id] = -1; - fwhandle->nodes[u->bus_reset.node_id & 0x3f] = i; - fwhandle->devices[i].node_id = u->bus_reset.node_id; - fwhandle->devices[i].generation = u->bus_reset.generation; - - if (u->bus_reset.node_id != u->bus_reset.local_node_id) - return 0; - - memcpy(&fwhandle->reset, &u->bus_reset, sizeof fwhandle->reset); - return fwhandle->bus_reset_handler(handle, - u->bus_reset.generation); - - case FW_CDEV_EVENT_RESPONSE: - rc = u64_to_ptr(u->response.closure); - - if (rc->data != NULL) - memcpy(rc->data, u->response.data, rc->length); - - errcode = fw_to_raw1394_errcode(u->response.rcode); - - return fwhandle->tag_handler(handle, rc->tag, errcode); - - case FW_CDEV_EVENT_REQUEST: - ac = u64_to_ptr(u->request.closure); - return ac->callback(handle, ac, &u->request, i); - - default: - case FW_CDEV_EVENT_ISO_INTERRUPT: - /* Never happens. */ - return -1; - } -} - -static int -handle_inotify(raw1394handle_t handle, struct epoll_closure *ec, - __uint32_t events) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct inotify_event *event; - char filename[32]; - struct fw_cdev_get_info info; - struct fw_cdev_event_bus_reset reset; - struct epoll_event ep; - int i, len, fd, phy_id; - - event = (struct inotify_event *) fwhandle->buffer; - len = read(fwhandle->inotify_fd, event, BUFFER_SIZE); - if (!(event->mask & IN_CREATE)) - return -1; - if (strncmp(event->name, - FW_DEVICE_PREFIX, strlen(FW_DEVICE_PREFIX)) != 0) - return 0; - snprintf(filename, sizeof filename, FW_DEVICE_DIR "/%s", event->name); - fd = open(filename, O_RDWR); - if (fd < 0) { - switch (errno) { - case ENOENT: - /* Huh, it disappeared before we could - * open it. */ - return 0; - case EACCES: - /* We don't have permission to talk to - * this device, maybe it's a storage - * device. */ - return 0; - default: - /* Anything else is bad news. */ - return -1; - } - } - - info.version = FW_CDEV_VERSION; - info.rom = 0; - info.rom_length = 0; - info.bus_reset = ptr_to_u64(&reset); - if (ioctl(fd, FW_CDEV_IOC_GET_INFO, &info) < 0) { - close(fd); - return -1; - } - - for (i = 0; i < MAX_DEVICES; i++) - if (fwhandle->devices[i].node_id == -1) - break; - if (i == MAX_DEVICES) { - close(fd); - return -1; - } - - phy_id = reset.node_id & 0x3f; - fwhandle->nodes[phy_id] = i; - fwhandle->devices[i].node_id = reset.node_id; - fwhandle->devices[i].generation = reset.generation; - fwhandle->devices[i].fd = fd; - strncpy(fwhandle->devices[i].filename, filename, - sizeof fwhandle->devices[i].filename); - fwhandle->devices[i].closure.func = handle_device_event; - ep.events = EPOLLIN; - ep.data.ptr = &fwhandle->devices[i].closure; - if (epoll_ctl(fwhandle->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { - close(fd); - return -1; - } - - return 0; -} - -int fw_loop_iterate(raw1394handle_t handle) -{ - int i, count, retval = 0; - struct epoll_closure *closure; - struct epoll_event ep[32]; - - count = epoll_wait(handle->mode.fw->epoll_fd, ep, ARRAY_LENGTH(ep), -1); - if (count < 0) - return -1; - - for (i = 0; i < count; i++) { - closure = ep[i].data.ptr; - retval = closure->func(handle, closure, ep[i].events); - } - - /* It looks like we have to add this work-around to get epoll - * to recompute the POLLIN status of the epoll_fd. */ - epoll_wait(handle->mode.fw->epoll_fd, ep, ARRAY_LENGTH(ep), 0); - - return retval; -} - -fw_handle_t fw_new_handle(void) -{ - fw_handle_t handle; - struct epoll_event ep; - int i; - - handle = malloc(sizeof *handle); - - handle->tag_handler = default_tag_handler; - handle->arm_tag_handler = default_arm_tag_handler; - handle->allocations = NULL; - - handle->notify_bus_reset = RAW1394_NOTIFY_ON; - handle->bus_reset_handler = default_bus_reset_handler; - - handle->iso.fd = -1; - - handle->epoll_fd = epoll_create(16); - if (handle->epoll_fd < 0) - goto out_handle; - - if (pipe(handle->pipe_fds) < 0) - goto out_epoll; - - handle->inotify_fd = inotify_init(); - if (handle->inotify_fd < 0) - goto out_pipe; - - handle->inotify_watch = - inotify_add_watch(handle->inotify_fd, FW_DEVICE_DIR, IN_CREATE); - if (handle->inotify_watch < 0) - goto out_inotify; - - handle->pipe_closure.func = handle_echo_pipe; - ep.events = EPOLLIN; - ep.data.ptr = &handle->pipe_closure; - if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, - handle->pipe_fds[0], &ep) < 0) - goto out_inotify; - - handle->inotify_closure.func = handle_inotify; - ep.events = EPOLLIN; - ep.data.ptr = &handle->inotify_closure; - if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, - handle->inotify_fd, &ep) < 0) - goto out_inotify; - - for (i = 0; i < MAX_DEVICES; i++) { - handle->nodes[i] = -1; - handle->devices[i].node_id = -1; - } - - scan_devices(handle); - - return handle; - - out_inotify: - close(handle->inotify_fd); - out_pipe: - close(handle->pipe_fds[0]); - close(handle->pipe_fds[1]); - out_epoll: - close(handle->epoll_fd); - out_handle: - free(handle); - return NULL; -} - -void fw_destroy_handle(fw_handle_t handle) -{ - int i; - - close(handle->inotify_fd); - close(handle->pipe_fds[0]); - close(handle->pipe_fds[1]); - - for (i = 0; i < MAX_DEVICES; i++) { - if (handle->devices[i].node_id == -1) - continue; - - close(handle->devices[i].fd); - } - - close(handle->epoll_fd); - - free(handle); - - return; -} - -fw_handle_t fw_new_handle_on_port(int port) -{ - fw_handle_t handle; - - handle = fw_new_handle(); - if (handle == NULL) - return NULL; - - if (fw_set_port(handle, port) < 0) - return NULL; - - return handle; -} - -int fw_busreset_notify (fw_handle_t handle, int off_on_switch) -{ - handle->notify_bus_reset = off_on_switch; - - return 0; -} - -int fw_get_fd(fw_handle_t handle) -{ - return handle->epoll_fd; -} - -nodeid_t fw_get_local_id(fw_handle_t handle) -{ - return handle->reset.local_node_id; -} - -nodeid_t fw_get_irm_id(fw_handle_t handle) -{ - return handle->reset.irm_node_id; -} - -int fw_get_nodecount(fw_handle_t handle) -{ - return (handle->reset.root_node_id & 0x3f) + 1; -} - -int fw_get_port_info(fw_handle_t handle, - struct raw1394_portinfo *pinf, - int maxports) -{ - int i; - - if (maxports >= handle->port_count) - maxports = handle->port_count; - - for (i = 0; i < maxports; i++) { - pinf[i].nodes = handle->ports[i].node_count; - strncpy(pinf[i].name, handle->ports[i].device_file, - sizeof pinf[i].name); - } - - return handle->port_count; -} - -int fw_set_port(fw_handle_t handle, int port) -{ - struct fw_cdev_get_info get_info; - struct fw_cdev_event_bus_reset reset; - struct epoll_event ep; - struct dirent *de; - char filename[32]; - DIR *dir; - int i, fd, phy_id; - - if (port >= handle->port_count) { - errno = EINVAL; - return -1; - } - - dir = opendir("/dev"); - if (dir == NULL) - return -1; - - for (i = 0; i < MAX_DEVICES; ) { - de = readdir(dir); - if (de == NULL) - break; - - if (strncmp(de->d_name, "fw", 2) != 0) - continue; - - snprintf(filename, sizeof filename, "/dev/%s", de->d_name); - - fd = open(filename, O_RDWR); - if (fd < 0) - continue; - - get_info.version = FW_CDEV_VERSION; - get_info.rom = 0; - get_info.rom_length = 0; - get_info.bus_reset = ptr_to_u64(&reset); - if (ioctl(fd, FW_CDEV_IOC_GET_INFO, &get_info) < 0) { - close(fd); - continue; - } - - if (get_info.card != handle->ports[port].card) { - close(fd); - continue; - } - - phy_id = reset.node_id & 0x3f; - handle->nodes[phy_id] = i; - handle->devices[i].node_id = reset.node_id; - handle->devices[i].generation = reset.generation; - handle->devices[i].fd = fd; - strncpy(handle->devices[i].filename, filename, - sizeof handle->devices[i].filename); - - handle->devices[i].closure.func = handle_device_event; - ep.events = EPOLLIN; - ep.data.ptr = &handle->devices[i].closure; - if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { - close(fd); - return -1; - } - - handle->generation = reset.generation; - if (reset.node_id == reset.local_node_id) { - memcpy(&handle->reset, &reset, sizeof handle->reset); - handle->local_fd = fd; - strncpy(handle->local_filename, filename, - sizeof handle->local_filename); - } - - i++; - } - - return 0; -} - -int fw_reset_bus_new(fw_handle_t handle, int type) -{ - struct fw_cdev_initiate_bus_reset initiate; - - switch (type) { - case RAW1394_LONG_RESET: - initiate.type = FW_CDEV_LONG_RESET; - break; - case RAW1394_SHORT_RESET: - initiate.type = FW_CDEV_SHORT_RESET; - break; - } - - return ioctl(handle->local_fd, - FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate); -} - -struct request_response_block { - struct raw1394_arm_request_response request_response; - struct raw1394_arm_request request; - struct raw1394_arm_response response; - unsigned char data[0]; -}; - -struct allocation { - struct address_closure closure; - 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, - struct fw_cdev_event_request *request, int i) -{ - 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 offset; - - offset = request->offset - allocation->offset; - response.handle = request->handle; - - switch (request->tcode) { - case TCODE_WRITE_QUADLET_REQUEST: - case TCODE_WRITE_BLOCK_REQUEST: - printf("got write request, offset=0x%012llx, length=%d\n", - request->offset, request->length); - - type = RAW1394_ARM_WRITE; - in_length = request->length; - response.rcode = RCODE_COMPLETE; - response.length = 0; - response.data = 0; - break; - - case TCODE_READ_QUADLET_REQUEST: - case TCODE_READ_BLOCK_REQUEST: - printf("got read request, offset=0x%012llx, length=%d\n", - request->offset, request->length); - - type = RAW1394_ARM_READ; - in_length = 0; - response.rcode = RCODE_COMPLETE; - response.length = request->length; - response.data = ptr_to_u64(allocation->data + offset); - break; - - case TCODE_LOCK_REQUEST: - type = RAW1394_ARM_LOCK; - in_length = request->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->devices[i].fd, - FW_CDEV_IOC_SEND_RESPONSE, &response) < 0) - return -1; - } else if (!(allocation->client_transactions & type)) { - if (type == RAW1394_ARM_WRITE) - memcpy(allocation->data + offset, - request->data, request->length); - else if (type == RAW1394_ARM_LOCK) - /* FIXME: do lock ops here */; - - if (ioctl(fwhandle->devices[i].fd, - FW_CDEV_IOC_SEND_RESPONSE, &response) < 0) - return -1; - } - - if (!(allocation->notification_options & type)) - return 0; - - rrb = malloc(sizeof *rrb + in_length + response.length); - - 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 = fwhandle->devices[i].node_id; - rrb->request.destination_offset = request->offset; - rrb->request.tlabel = 0; - if (request->tcode < 0x10) { - rrb->request.tcode = request->tcode; - rrb->request.extended_transaction_code = 0; - } else { - rrb->request.tcode = TCODE_LOCK_REQUEST; - rrb->request.extended_transaction_code = request->tcode - 0x10; - } - rrb->request.generation = fwhandle->reset.generation; - rrb->request.buffer_length = in_length; - memcpy(rrb->request.buffer, request->data, in_length); - - rrb->response.response_code = response.rcode; - rrb->response.buffer_length = response.length; - memcpy(rrb->response.buffer, - allocation->data + offset, response.length); - - return fwhandle->arm_tag_handler(handle, allocation->tag, type, - request->length, - &rrb->request_response); -} - -int -fw_arm_register(fw_handle_t 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) -{ - struct fw_cdev_allocate request; - struct allocation *allocation; - int retval; - - allocation = malloc(sizeof *allocation + length); - if (allocation == NULL) - 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); - - request.offset = start; - request.length = length; - request.closure = ptr_to_u64(&allocation->closure); - - retval = ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request); - if (retval < 0) { - free(allocation); - return -1; - } - - allocation->handle = request.handle; - allocation->next = handle->allocations; - handle->allocations = allocation; - - return 0; -} - -static struct allocation * -lookup_allocation(fw_handle_t handle, nodeaddr_t start, int delete) -{ - struct allocation *a, **prev; - - prev = &handle->allocations; - for (a = handle->allocations; a != NULL; a = a->next) { - if (a->offset <= start && start < a->offset + a->length) - break; - prev = &a->next; - } - - if (a != NULL && delete) - *prev = a->next; - - return a; -} - -int -fw_arm_unregister(fw_handle_t handle, nodeaddr_t start) -{ - struct fw_cdev_deallocate request; - struct allocation *allocation; - - allocation = lookup_allocation(handle, start, 1); - if (allocation == NULL) { - errno = EINVAL; - return -1; - } - - request.handle = allocation->handle; - free(allocation); - - return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request); -} - -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); -} - -int fw_wake_up(fw_handle_t handle) -{ - return fw_echo_request(handle, 0); -} - -int fw_phy_packet_write (fw_handle_t handle, quadlet_t data) -{ - errno = ENOSYS; - return -1; -} - -int -fw_start_phy_packet_write(fw_handle_t handle, - quadlet_t data, unsigned long tag) -{ - errno = ENOSYS; - return -1; -} - -static int -send_request(fw_handle_t handle, int tcode, - nodeid_t node, nodeaddr_t addr, - size_t length, void *in, void *out, unsigned long tag) -{ - struct fw_cdev_send_request *request; - struct request_closure *closure; - int i; - - if (node > handle->reset.root_node_id) { - handle->err = -RCODE_NO_ACK; - errno = fw_errcode_to_errno(handle->err); - return -1; - } - - i = handle->nodes[node & 0x3f]; - if (i == -1) { - handle->err = -RCODE_NO_ACK; - errno = fw_errcode_to_errno(handle->err); - return -1; - } - - if (handle->generation != handle->devices[i].generation) { - handle->err = -RCODE_GENERATION; - errno = fw_errcode_to_errno(handle->err); - return -1; - } - - closure = malloc(sizeof *closure); - if (closure == NULL) { - handle->err = -RCODE_SEND_ERROR; - errno = fw_errcode_to_errno(handle->err); - return -1; - } - - closure->data = out; - closure->length = length; - closure->tag = tag; - - request = (struct fw_cdev_send_request *) handle->buffer; - request->tcode = tcode; - request->generation = handle->generation; - request->offset = addr; - request->length = length; - request->closure = ptr_to_u64(closure); - request->data = ptr_to_u64(in); - - return ioctl(handle->devices[i].fd, FW_CDEV_IOC_SEND_REQUEST, request); -} - -int -fw_start_read(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *buffer, unsigned long tag) -{ - int tcode; - - if (length == 4) - tcode = TCODE_READ_QUADLET_REQUEST; - else - tcode = TCODE_READ_BLOCK_REQUEST; - - return send_request(handle, tcode, - node, addr, length, NULL, buffer, tag); -} - -int -fw_start_write(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *data, unsigned long tag) -{ - int tcode; - - if (length == 4) - tcode = TCODE_WRITE_QUADLET_REQUEST; - else - tcode = TCODE_WRITE_BLOCK_REQUEST; - - return send_request(handle, tcode, - node, addr, length, data, NULL, tag); -} - -static int -setup_lock(int extcode, quadlet_t data, quadlet_t arg, quadlet_t *buffer) -{ - switch (extcode) { - case RAW1394_EXTCODE_FETCH_ADD: - case RAW1394_EXTCODE_LITTLE_ADD: - buffer[0] = data; - return sizeof buffer[0]; - - case RAW1394_EXTCODE_MASK_SWAP: - case RAW1394_EXTCODE_COMPARE_SWAP: - case RAW1394_EXTCODE_BOUNDED_ADD: - case RAW1394_EXTCODE_WRAP_ADD: - buffer[0] = arg; - buffer[1] = data; - return 2 * sizeof buffer[0]; - - default: - errno = EINVAL; - return -1; - } -} - -static int -setup_lock64(int extcode, octlet_t data, octlet_t arg, octlet_t *buffer) -{ - switch (extcode) { - case RAW1394_EXTCODE_FETCH_ADD: - case RAW1394_EXTCODE_LITTLE_ADD: - buffer[0] = data; - return sizeof buffer[0]; - - case RAW1394_EXTCODE_MASK_SWAP: - case RAW1394_EXTCODE_COMPARE_SWAP: - case RAW1394_EXTCODE_BOUNDED_ADD: - case RAW1394_EXTCODE_WRAP_ADD: - buffer[0] = arg; - buffer[1] = data; - return 2 * sizeof buffer[0]; - - default: - errno = EINVAL; - return -1; - } -} - -int -fw_start_lock(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, quadlet_t data, quadlet_t arg, - quadlet_t *result, unsigned long tag) -{ - quadlet_t buffer[2]; - int length; - - length = setup_lock(extcode, data, arg, buffer); - if (length < 0) - return length; - - return send_request(handle, 16 + extcode, - node, addr, length, buffer, result, tag); -} - -int -fw_start_lock64(fw_handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, octlet_t data, octlet_t arg, - octlet_t *result, unsigned long tag) -{ - octlet_t buffer[2]; - int length; - - length = setup_lock64(extcode, data, arg, buffer); - if (length < 0) - return length; - - return send_request(handle, 16 + extcode, - node, addr, length, buffer, result, tag); -} - -int -fw_start_async_stream(fw_handle_t handle, unsigned int channel, - unsigned int tag, unsigned int sy, - unsigned int speed, size_t length, quadlet_t *data, - unsigned long rawtag) -{ - /* FIXME: implement this? */ - return -1; -} - - -int -fw_start_async_send(fw_handle_t handle, - size_t length, size_t header_length, - unsigned int expect_response, - quadlet_t *data, unsigned long rawtag) -{ - /* FIXME: implement this? */ - return -1; -} - -struct sync_data { - raw1394_errcode_t err; - int done; -}; - -static int -sync_callback(raw1394handle_t handle, void *data, raw1394_errcode_t err) -{ - struct sync_data *sd = data; - - sd->err = err; - sd->done = 1; - - return 0; -} - -static int -send_request_sync(raw1394handle_t handle, int tcode, - nodeid_t node, nodeaddr_t addr, - size_t length, void *in, void *out) -{ - fw_handle_t fwhandle = handle->mode.fw; - struct raw1394_reqhandle reqhandle; - struct sync_data sd = { 0, 0 }; - int err; - - reqhandle.callback = sync_callback; - reqhandle.data = &sd; - - err = send_request(fwhandle, tcode, node, addr, - length, in, out, (unsigned long) &reqhandle); - - while (!sd.done) { - if (err < 0) - return err; - err = fw_loop_iterate(handle); - } - - fwhandle->err = sd.err; - errno = fw_errcode_to_errno(sd.err); - - return (errno ? -1 : 0); -} - -int -fw_read(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *buffer) -{ - int tcode; - - if (length == 4) - tcode = TCODE_READ_QUADLET_REQUEST; - else - tcode = TCODE_READ_BLOCK_REQUEST; - - return send_request_sync(handle, tcode, - node, addr, length, NULL, buffer); -} - -int -fw_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - size_t length, quadlet_t *data) -{ - int tcode; - - if (length == 4) - tcode = TCODE_WRITE_QUADLET_REQUEST; - else - tcode = TCODE_WRITE_BLOCK_REQUEST; - - return send_request_sync(handle, tcode, - node, addr, length, data, NULL); -} - -int -fw_lock(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, quadlet_t data, quadlet_t arg, - quadlet_t *result) -{ - quadlet_t buffer[2]; - size_t length; - - length = setup_lock(extcode, data, arg, buffer); - if (length < 0) - return length; - - return send_request_sync(handle, 16 + extcode, node, addr, - length, buffer, result); -} - -int -fw_lock64(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr, - unsigned int extcode, octlet_t data, octlet_t arg, - octlet_t *result) -{ - octlet_t buffer[2]; - size_t length; - - length = setup_lock64(extcode, data, arg, buffer); - if (length < 0) - return length; - - return send_request_sync(handle, 16 + extcode, node, addr, - length, buffer, result); -} - -int -fw_async_stream(fw_handle_t handle, unsigned int channel, - unsigned int tag, unsigned int sy, unsigned int speed, - size_t length, quadlet_t *data) -{ - /* FIXME: implement this? */ - return -1; -} - -int -fw_async_send(fw_handle_t handle, - size_t length, size_t header_length, - unsigned int expect_response, - quadlet_t *data) -{ - /* FIXME: implement this? */ - return -1; -} - -int -fw_start_fcp_listen(fw_handle_t handle) -{ - struct fw_cdev_allocate request; - struct address_closure *closure; - - closure = malloc(sizeof *closure); - if (closure == NULL) - return -1; - - closure->callback = handle_fcp_request; - - request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND; - request.length = CSR_FCP_END - CSR_FCP_COMMAND; - request.closure = ptr_to_u64(closure); - if (ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0) - return -1; - - handle->fcp_allocation_handle = request.handle; - - return 0; -} - -int -fw_stop_fcp_listen(fw_handle_t handle) -{ - struct fw_cdev_deallocate request; - - request.handle = handle->fcp_allocation_handle; - - return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request); -} - -int -fw_update_config_rom(fw_handle_t handle, const quadlet_t *new_rom, - size_t size, unsigned char rom_version) -{ - return -1; -} - -int -fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer, - size_t buffersize, size_t *rom_size, - unsigned char *rom_version) -{ - struct fw_cdev_get_info get_info; - int err; - - get_info.version = FW_CDEV_VERSION; - get_info.rom = ptr_to_u64(buffer); - get_info.rom_length = buffersize; - get_info.bus_reset = 0; - - err = ioctl(handle->local_fd, FW_CDEV_IOC_GET_INFO, &get_info); - if (err) - return err; - - *rom_size = get_info.rom_length; - *rom_version = 0; - - return 0; -} - -#define MAXIMUM_BANDWIDTH 4915 - -int -fw_bandwidth_modify (raw1394handle_t handle, - unsigned int bandwidth, - enum raw1394_modify_mode mode) -{ - quadlet_t buffer, compare, swap; - nodeaddr_t addr; - int result; - - if (bandwidth == 0) - return 0; - - addr = CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE; - /* Read current bandwidth usage from IRM. */ - result = raw1394_read (handle, raw1394_get_irm_id (handle), addr, - sizeof buffer, &buffer); - if (result < 0) - return -1; - - compare = ntohl (buffer); - switch (mode) { - case RAW1394_MODIFY_ALLOC: - swap = compare - bandwidth; - if (swap < 0) - return -1; - break; - - case RAW1394_MODIFY_FREE: - swap = compare + bandwidth; - if (swap > MAXIMUM_BANDWIDTH) - swap = MAXIMUM_BANDWIDTH; - break; - - default: - return -1; - } - - result = raw1394_lock(handle, raw1394_get_irm_id (handle), addr, - RAW1394_EXTCODE_COMPARE_SWAP, - htonl(swap), htonl(compare), &buffer); - if (result < 0 || ntohl(buffer) != compare) - return -1; - - return 0; -} - -int -fw_channel_modify (raw1394handle_t handle, - unsigned int channel, - enum raw1394_modify_mode mode) -{ - quadlet_t buffer, compare, swap, bit; - nodeaddr_t addr; - int result; - - if (channel >= 64) - return -1; - addr = CSR_REGISTER_BASE + - CSR_CHANNELS_AVAILABLE_HI + 4 * (channel / 32); - /* Read currently available channels from IRM. */ - result = raw1394_read(handle, raw1394_get_irm_id (handle), addr, - sizeof buffer, &buffer); - if (result < 0) - return -1; - - /* IEEE numbers bits from MSB (0) to LSB (31). */ - bit = 1 << (31 - (channel & 31)); - compare = ntohl(buffer); - switch (mode) { - case RAW1394_MODIFY_ALLOC: - if ((compare & bit) == 0) - return -1; - swap = buffer & ~bit; - break; - - case RAW1394_MODIFY_FREE: - if ((buffer & bit) != 0) - return -1; - swap = buffer | bit; - break; - - default: - return -1; - } - - result = raw1394_lock (handle, raw1394_get_irm_id (handle), addr, - RAW1394_EXTCODE_COMPARE_SWAP, - htonl(swap), htonl(compare), &buffer); - - if (result < 0 || ntohl(buffer) != compare) - return -1; - - return 0; -} |
