diff --git a/libraw1394-juju.patch b/libraw1394-juju.patch index b49312b..e18e779 100644 --- a/libraw1394-juju.patch +++ b/libraw1394-juju.patch @@ -1,164 +1,21 @@ -Index: tools/testlibraw.c -=================================================================== ---- tools/testlibraw.c (revision 171) -+++ tools/testlibraw.c (working copy) -@@ -1,4 +1,5 @@ --/* -+/* -*- c-basic-offset: 8 -*- -+ * - * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. - * - * Copyright (C) 1999,2000 Andreas Bombe -@@ -13,12 +14,13 @@ - #include - #include - #include -+#include - - #include "../src/raw1394.h" - #include "../src/csr.h" - - --#define TESTADDR (CSR_REGISTER_BASE + CSR_CYCLE_TIME) -+#define TESTADDR (CSR_REGISTER_BASE + CSR_CONFIG_ROM) - - const char not_compatible[] = "\ - This libraw1394 does not work with your version of Linux. You need a different\n\ -@@ -45,12 +47,18 @@ - return 0; - } - -+static const unsigned char fcp_data[] = -+ { 0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; -+ - int my_fcp_handler(raw1394handle_t handle, nodeid_t nodeid, int response, - size_t length, unsigned char *data) - { - printf("got fcp %s from node %d of %d bytes:", - (response ? "response" : "command"), nodeid & 0x3f, length); - -+ if (memcmp(fcp_data, data, sizeof fcp_data) != 0) -+ printf("ERROR: fcp payload not correct\n"); -+ - while (length) { - printf(" %02x", *data); - data++; -@@ -62,7 +70,48 @@ - return 0; - } - -+static void -+test_fcp(raw1394handle_t handle) -+{ -+ printf("\ntesting FCP monitoring on local node\n"); -+ raw1394_set_fcp_handler(handle, my_fcp_handler); -+ raw1394_start_fcp_listen(handle); -+ raw1394_write(handle, raw1394_get_local_id(handle), -+ CSR_REGISTER_BASE + CSR_FCP_COMMAND, sizeof(fcp_data), -+ (quadlet_t *)fcp_data); -+ raw1394_write(handle, raw1394_get_local_id(handle), -+ CSR_REGISTER_BASE + CSR_FCP_RESPONSE, sizeof(fcp_data), -+ (quadlet_t *)fcp_data); -+} - -+static void -+read_topology_map(raw1394handle_t handle) -+{ -+ quadlet_t map[70]; -+ nodeid_t local_id; -+ int node_count, self_id_count, i, retval; -+ -+ local_id = raw1394_get_local_id(handle) | 0xffc0; -+ -+ retval = raw1394_read(handle, local_id, -+ CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP, 12, &map[0]); -+ if (retval < 0) -+ perror("topology map: raw1394_read failed with error"); -+ -+ self_id_count = ntohl(map[2]) & 0xffff; -+ node_count = ntohl(map[2]) >> 16; -+ retval = raw1394_read(handle, local_id, -+ CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP + 12, -+ self_id_count * sizeof map[0], &map[3]); -+ if (retval < 0) -+ perror("topology map: raw1394_read failed with error"); -+ -+ printf("topology map: %d nodes, %d self ids, generation %d\n", -+ node_count, self_id_count, ntohl(map[1])); -+ for (i = 0; i < self_id_count; i++) -+ printf(" 0x%08x\n", ntohl(map[3 + i])); -+} -+ - int main(int argc, char **argv) - { - raw1394handle_t handle; -@@ -73,7 +122,6 @@ - int retval; - - struct pollfd pfd; -- unsigned char fcp_test[] = { 0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; - quadlet_t rom[0x100]; - size_t rom_size; - unsigned char rom_version; -@@ -150,18 +198,9 @@ - } - } - -- printf("\ntesting FCP monitoring on local node\n"); -- raw1394_set_fcp_handler(handle, my_fcp_handler); -- raw1394_start_fcp_listen(handle); -- raw1394_write(handle, raw1394_get_local_id(handle), -- CSR_REGISTER_BASE + CSR_FCP_COMMAND, sizeof(fcp_test), -- (quadlet_t *)fcp_test); -- raw1394_write(handle, raw1394_get_local_id(handle), -- CSR_REGISTER_BASE + CSR_FCP_RESPONSE, sizeof(fcp_test), -- (quadlet_t *)fcp_test); -+ test_fcp(handle); -+ read_topology_map(handle); - -- -- - printf("testing config rom stuff\n"); - retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version); - printf("get_config_rom returned %d, romsize %d, rom_version %d\n",retval,rom_size,rom_version); -@@ -176,16 +215,19 @@ - retval=raw1394_update_config_rom(handle, rom, rom_size, rom_version); - printf("update_config_rom returned %d\n",retval); - -+ printf("\nposting 0xdeadbeef as an echo request\n"); -+ raw1394_echo_request(handle, 0xdeadbeef); - -- -- printf("\npolling for leftover messages\n"); -+ printf("polling for leftover messages\n"); - pfd.fd = raw1394_get_fd(handle); - pfd.events = POLLIN; - pfd.revents = 0; - while (1) { - retval = poll(&pfd, 1, 10); - if (retval < 1) break; -- raw1394_loop_iterate(handle); -+ retval = raw1394_loop_iterate(handle); -+ if (retval != 0) -+ printf("raw1394_loop_iterate() returned 0x%08x\n", retval); - } +diff --git a/Makefile.am b/Makefile.am +index 04ed38a..21df527 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,6 +1,7 @@ + # process this file with automake to create a Makefile.in - if (retval < 0) perror("poll failed"); -Index: tools/Makefile.am -=================================================================== ---- tools/Makefile.am (revision 171) -+++ tools/Makefile.am (working copy) -@@ -2,4 +2,4 @@ +-SUBDIRS = src tools doc debian ++SUBDIRS = $(LIB_SUBDIR) tools doc debian ++DIST_SUBDIRS = src juju - # testlibraw - bin_PROGRAMS = testlibraw sendiso dumpiso --LDADD = ../src/libraw1394.la -+LDADD = ../$(LIB_SUBDIR)/libraw1394.la -Index: configure.ac -=================================================================== ---- configure.ac (revision 171) -+++ configure.ac (working copy) -@@ -24,13 +24,35 @@ + pkgconfigdir = @libdir@/pkgconfig + pkgconfig_DATA = libraw1394.pc +diff --git a/configure.ac b/configure.ac +index fe23ca8..7e5dd66 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -24,6 +24,27 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) @@ -171,7 +28,7 @@ Index: configure.ac + LIB_SUBDIR=src +fi +AC_SUBST(LIB_SUBDIR) - ++ +AC_ARG_WITH(fw-device-prefix, + [ --with-fw-device-prefix= Prefix of firewire device file names (default "fw").], + [FW_DEVICE_PREFIX="\"$withval\""], [FW_DEVICE_PREFIX="\"fw\""]) @@ -183,10 +40,10 @@ Index: configure.ac + [Prefix of firewire device file names.]) +AC_DEFINE_UNQUOTED(FW_DEVICE_DIR, $FW_DEVICE_DIR, + [Directory to watch for firewire device files.]) -+ + #CFLAGS=${CFLAGS:-"-Wall"} AC_OUTPUT([ - Makefile +@@ -31,6 +52,7 @@ Makefile libraw1394.pc libraw1394.spec src/Makefile @@ -194,24 +51,175 @@ Index: configure.ac tools/Makefile doc/Makefile doc/testlibraw.1 -Index: Makefile.am -=================================================================== ---- Makefile.am (revision 171) -+++ Makefile.am (working copy) -@@ -1,6 +1,7 @@ - # process this file with automake to create a Makefile.in - --SUBDIRS = src tools doc debian -+SUBDIRS = $(LIB_SUBDIR) tools doc debian -+DIST_SUBDIRS = src juju - - pkgconfigdir = @libdir@/pkgconfig - pkgconfig_DATA = libraw1394.pc -Index: juju/raw1394-iso.c -=================================================================== ---- juju/raw1394-iso.c (revision 0) -+++ juju/raw1394-iso.c (revision 0) -@@ -0,0 +1,385 @@ +diff --git a/juju/Makefile.am b/juju/Makefile.am +new file mode 100644 +index 0000000..6fd6a5e +--- /dev/null ++++ b/juju/Makefile.am +@@ -0,0 +1,8 @@ ++lib_LTLIBRARIES = libraw1394.la ++ ++INCLUDES = -I$(JUJU_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 +new file mode 100644 +index 0000000..8c18630 +--- /dev/null ++++ b/juju/juju.h +@@ -0,0 +1,143 @@ ++/* -*- c-basic-offset: 8 -*- ++ * ++ * juju.h -- Internal header file for raw1394 emulation ++ * ++ * Copyright (C) 2007 Kristian Hoegsberg ++ * ++ * 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 ++#include ++#include ++#include "../src/raw1394.h" ++#include "../src/csr.h" ++#include "config.h" ++ ++#define ACK_COMPLETE 1 ++ ++#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 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 raw1394_handle { ++ struct port ports[MAX_PORTS]; ++ int port_count; ++ int err; ++ int generation; ++ void *user_data; ++ 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 buf_packets; ++ int max_packet_size; ++ int packet_header_index; ++ 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]; ++}; ++ ++#endif +diff --git a/juju/raw1394-iso.c b/juju/raw1394-iso.c +new file mode 100644 +index 0000000..bbf49f0 +--- /dev/null ++++ b/juju/raw1394-iso.c +@@ -0,0 +1,547 @@ +/* -*- c-basic-offset: 8 -*- + * + * raw1394-iso.c -- Emulation of the raw1394 rawiso API on the juju stack @@ -238,75 +246,89 @@ Index: juju/raw1394-iso.c +#include +#include +#include ++#include +#include +#include + +#include "juju.h" + -+static int -+refill_xmit_buffer(raw1394handle_t handle, struct fw_cdev_queue_iso *queue_iso) ++static enum raw1394_iso_disposition ++queue_xmit_packets(raw1394handle_t handle) +{ -+ int i; + struct fw_cdev_iso_packet *p = handle->iso.packets; ++ struct fw_cdev_queue_iso queue_iso; + enum raw1394_iso_disposition d; + unsigned int len, dropped; -+ unsigned char tag, sy, *data, *buffer; -+ int cycle; -+ -+ buffer = handle->iso.buffer + -+ handle->iso.packet_index * handle->iso.max_packet_size; -+ data = buffer; ++ unsigned char tag, sy, *first_payload; ++ int cycle, i; + ++ first_payload = handle->iso.head; + for (i = 0; i < handle->iso.irq_interval; i++) { + cycle = -1; + dropped = 0; -+ d = handle->iso.xmit_handler(handle, data, ++ ++ if (handle->iso.head + handle->iso.max_packet_size > ++ handle->iso.buffer_end) { ++ handle->iso.head = handle->iso.buffer; ++ break; ++ } ++ ++ d = handle->iso.xmit_handler(handle, handle->iso.head, + &len, &tag, &sy, cycle, dropped); -+ /* FIXME: handle the different dispositions. */ ++ if (d != RAW1394_ISO_OK) ++ break; + + p->payload_length = len; -+ p->interrupt = handle->iso.packet_phase == 0; ++ p->interrupt = ++ handle->iso.packet_phase == handle->iso.irq_interval - 1; + p->skip = 0; + p->tag = tag; + p->sy = sy; + p->header_length = 0; + -+ data += handle->iso.max_packet_size; -+ handle->iso.packet_index++; -+ if (handle->iso.packet_index == handle->iso.buf_packets) { -+ handle->iso.packet_index = 0; -+ break; -+ } -+ ++ handle->iso.head += len; ++ handle->iso.packet_count++; + handle->iso.packet_phase++; ++ + if (handle->iso.packet_phase == handle->iso.irq_interval) + handle->iso.packet_phase = 0; -+ + } + -+ queue_iso->packets = ptr_to_u64(handle->iso.packets); -+ queue_iso->size = -+ handle->iso.irq_interval * sizeof handle->iso.packets[0]; -+ queue_iso->data = ptr_to_u64(buffer); ++ queue_iso.packets = ptr_to_u64(handle->iso.packets); ++ queue_iso.size = i * sizeof handle->iso.packets[0]; ++ queue_iso.data = ptr_to_u64(first_payload); + -+ return 0; ++ len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); ++ if (len < 0) ++ return RAW1394_ISO_ERROR; ++ ++ return d; +} + +static int +flush_xmit_packets(raw1394handle_t handle, int limit) +{ -+ struct fw_cdev_queue_iso queue_iso; ++ enum raw1394_iso_disposition d; + int len; + -+ while (handle->iso.packet_index + handle->iso.irq_interval <= limit) { -+ if (handle->iso.queue_iso.size == 0) -+ refill_xmit_buffer(handle, &queue_iso); -+ len = ioctl(handle->iso.fd, -+ FW_CDEV_IOC_QUEUE_ISO, &queue_iso); -+ if (len < 0) ++ if (handle->iso.xmit_handler == NULL) ++ return 0; ++ ++ if (limit < handle->iso.irq_interval) ++ limit = handle->iso.irq_interval; ++ ++ while (handle->iso.packet_count + handle->iso.irq_interval <= limit) { ++ d = queue_xmit_packets(handle); ++ switch (d) { ++ case RAW1394_ISO_DEFER: ++ case RAW1394_ISO_AGAIN: ++ return 0; ++ case RAW1394_ISO_ERROR: + return -1; -+ if (handle->iso.queue_iso.size > 0) -+ break; ++ case RAW1394_ISO_STOP: ++ raw1394_iso_stop(handle); ++ return 0; ++ } + } + + return 0; @@ -318,23 +340,72 @@ Index: juju/raw1394-iso.c + struct fw_cdev_start_iso start_iso; + int retval; + -+ if (prebuffer_packets == -1) -+ prebuffer_packets = handle->iso.irq_interval; ++ if (prebuffer_packets == -1) ++ prebuffer_packets = handle->iso.irq_interval; ++ ++ handle->iso.prebuffer = prebuffer_packets; ++ handle->iso.start_on_cycle = start_on_cycle; ++ ++ flush_xmit_packets(handle, prebuffer_packets); ++ ++ if (handle->iso.prebuffer <= handle->iso.packet_count) { ++ start_iso.cycle = start_on_cycle; ++ ++ retval = ioctl(handle->iso.fd, ++ FW_CDEV_IOC_START_ISO, &start_iso); ++ if (retval < 0) ++ return retval; ++ } ++ ++ return flush_xmit_packets(handle, handle->iso.buf_packets); ++} ++ ++static int ++queue_recv_packets(raw1394handle_t handle) ++{ ++ struct fw_cdev_queue_iso queue_iso; ++ struct fw_cdev_iso_packet *p = handle->iso.packets; ++ unsigned int len; ++ unsigned char *first_payload; ++ int i; ++ ++ first_payload = handle->iso.head; ++ for (i = 0; i < handle->iso.irq_interval; i++, p++) { ++ if (handle->iso.head + handle->iso.max_packet_size > ++ handle->iso.buffer_end) { ++ handle->iso.head = handle->iso.buffer; ++ break; ++ } ++ ++ p->payload_length = handle->iso.max_packet_size; ++ p->interrupt = handle->iso.packet_phase == handle->iso.irq_interval - 1; ++ p->skip = 0; ++ p->tag = 0; ++ p->sy = 0; ++ p->header_length = 4; + -+ flush_xmit_packets(handle, prebuffer_packets); ++ handle->iso.head += handle->iso.max_packet_size; ++ handle->iso.packet_count++; ++ handle->iso.packet_phase++; + -+ start_iso.cycle = start_on_cycle; ++ if (handle->iso.packet_phase == handle->iso.irq_interval) ++ handle->iso.packet_phase = 0; ++ } + -+ retval = ioctl(handle->iso.fd, FW_CDEV_IOC_START_ISO, &start_iso); -+ if (retval < 0) -+ return retval; ++ queue_iso.packets = ptr_to_u64(handle->iso.packets); ++ queue_iso.size = i * sizeof handle->iso.packets[0]; ++ queue_iso.data = ptr_to_u64(first_payload); + -+ return flush_xmit_packets(handle, handle->iso.buf_packets); ++ len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); ++ if (len < 0) ++ return -1; ++ ++ return 0; +} + -+static int -+handle_recv_packets(raw1394handle_t handle, -+ struct fw_cdev_event_iso_interrupt *interrupt) ++static enum raw1394_iso_disposition ++flush_recv_packets(raw1394handle_t handle, ++ struct fw_cdev_event_iso_interrupt *interrupt) +{ + enum raw1394_iso_disposition d; + quadlet_t header, *p, *end; @@ -345,20 +416,46 @@ Index: juju/raw1394-iso.c + p = interrupt->header; + end = (void *) interrupt->header + interrupt->header_length; + cycle = interrupt->cycle; -+ data = NULL; ++ dropped = 0; + + while (p < end) { + header = be32_to_cpu(*p++); -+ len = header >> 8; -+ channel = header >> 8; -+ tag = header >> 8; -+ sy = header >> 8; -+ -+ d = handle->iso.recv_handler(handle, data, len, channel, -+ tag, sy, cycle, dropped); ++ len = header >> 16; ++ tag = (header >> 14) & 0x3; ++ channel = (header >> 8) & 0x3f; ++ sy = header & 0x0f; ++ ++ d = handle->iso.recv_handler(handle, handle->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++; ++ ++ handle->iso.tail += handle->iso.max_packet_size; ++ handle->iso.packet_count--; ++ if (handle->iso.tail == handle->iso.buffer_end) ++ handle->iso.tail = handle->iso.buffer; ++ } ++ ++ switch (d) { ++ case RAW1394_ISO_OK: ++ case RAW1394_ISO_DEFER: ++ break; ++ ++ case RAW1394_ISO_ERROR: ++ return -1; ++ ++ case RAW1394_ISO_STOP: ++ raw1394_iso_stop(handle); ++ return 0; + } + ++ while (handle->iso.packet_count + handle->iso.irq_interval <= ++ handle->iso.buf_packets) ++ queue_recv_packets(handle); ++ + return 0; +} + @@ -367,6 +464,10 @@ Index: juju/raw1394-iso.c +{ + struct fw_cdev_start_iso start_iso; + ++ while (handle->iso.packet_count + handle->iso.irq_interval <= ++ handle->iso.buf_packets) ++ 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; @@ -387,15 +488,15 @@ Index: juju/raw1394-iso.c + return -1; + + interrupt = (struct fw_cdev_event_iso_interrupt *) handle->buffer; -+ if (interrupt->type != FW_CDEV_EVENT_BUS_RESET) ++ if (interrupt->type != FW_CDEV_EVENT_ISO_INTERRUPT) + return 0; + + switch (handle->iso.type) { + case FW_CDEV_ISO_CONTEXT_TRANSMIT: -+ handle->iso.packet_index -= handle->iso.irq_interval; ++ handle->iso.packet_count -= handle->iso.irq_interval; + return flush_xmit_packets(handle, handle->iso.buf_packets); + case FW_CDEV_ISO_CONTEXT_RECEIVE: -+ return handle_recv_packets(handle, interrupt); ++ return flush_recv_packets(handle, interrupt); + default: + /* Doesn't happen. */ + return -1; @@ -406,25 +507,81 @@ Index: juju/raw1394-iso.c + unsigned int len, unsigned char tag, + unsigned char sy) +{ -+ struct fw_cdev_iso_packet packet; ++ struct fw_cdev_queue_iso queue_iso; ++ struct fw_cdev_start_iso start_iso; ++ struct fw_cdev_iso_packet *p; ++ ++ { ++ int i; ++ __u32 *p = (__u32 *) data; + -+ packet.payload_length = len; -+ packet.interrupt = handle->iso.packet_phase == 0; -+ packet.skip = 0; -+ packet.tag = tag; -+ packet.sy = sy; -+ packet.header_length = 0; ++ for (i = 0; i < 10; i++) ++ fprintf(stderr, "0x%08x ", p[i]); ++ fprintf(stderr, "\n"); ++ } ++ ++ if (len > handle->iso.max_packet_size) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ /* Block until we have space for another packet. */ ++ while (handle->iso.packet_count + handle->iso.irq_interval > ++ handle->iso.buf_packets) ++ raw1394_loop_iterate(handle); ++ ++ p = &handle->iso.packets[handle->iso.packet_header_index]; ++ p->payload_length = len; ++ p->interrupt = ++ handle->iso.packet_phase == handle->iso.irq_interval - 1; ++ p->skip = 0; ++ p->tag = tag; ++ p->sy = sy; ++ p->header_length = 0; ++ ++ memcpy(handle->iso.head, data, len); + ++ handle->iso.head += len; ++ handle->iso.packet_count++; + handle->iso.packet_phase++; ++ handle->iso.packet_header_index++; ++ + if (handle->iso.packet_phase == handle->iso.irq_interval) + handle->iso.packet_phase = 0; + -+ /* FIXME: circular buffer goo. */ ++ if (handle->iso.head + handle->iso.max_packet_size > handle->iso.buffer_end) ++ handle->iso.head = handle->iso.buffer; + -+ memcpy(handle->iso.head, data, len); -+ handle->iso.head += len; ++ /* Queue the packets in the kernel if we filled up the packets ++ * array or wrapped the payload buffer. */ ++ if (handle->iso.packet_header_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_header_index * sizeof handle->iso.packets[0]; ++ queue_iso.data = ptr_to_u64(handle->iso.first_payload); ++ handle->iso.packet_header_index = 0; ++ handle->iso.first_payload = handle->iso.head; + -+ return -1; ++ len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); ++ if (len < 0) ++ return -1; ++ } ++ ++ /* Start the streaming if it's not already running and if ++ * we've buffered up enough packets. */ ++ if (handle->iso.prebuffer > 0 && ++ handle->iso.packet_count >= handle->iso.prebuffer) { ++ /* Set this to 0 to indicate that we're running. */ ++ handle->iso.prebuffer = 0; ++ start_iso.cycle = handle->iso.start_on_cycle; ++ ++ len = ioctl(handle->iso.fd, ++ FW_CDEV_IOC_START_ISO, &start_iso); ++ if (len < 0) ++ return len; ++ } ++ ++ return 0; +} + +int raw1394_iso_xmit_sync(raw1394handle_t handle) @@ -441,33 +598,38 @@ Index: juju/raw1394-iso.c + return 0; +} + -+int raw1394_iso_xmit_init(raw1394handle_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) ++static int ++iso_init(raw1394handle_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; ++ int retval, prot; + + if (handle->iso.fd != -1) { + errno = EBUSY; + return -1; + } + -+ handle->iso.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ handle->iso.irq_interval = irq_interval; -+ handle->iso.xmit_handler = handler; ++ 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 = max_packet_size; -+ handle->iso.packet_index = 0; + handle->iso.packet_phase = 0; -+ handle->iso.queue_iso.size = 0; ++ handle->iso.packet_count = 0; + handle->iso.packets = -+ malloc(irq_interval * sizeof handle->iso.packets[0]); ++ malloc(handle->iso.irq_interval * sizeof handle->iso.packets[0]); + if (handle->iso.packets == NULL) + return -1; + @@ -487,9 +649,10 @@ Index: juju/raw1394-iso.c + return -1; + } + -+ create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; ++ 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); @@ -499,266 +662,117 @@ Index: juju/raw1394-iso.c + return retval; + } + ++ switch (type) { ++ case FW_CDEV_ISO_CONTEXT_TRANSMIT: ++ prot = PROT_READ | PROT_WRITE; ++ break; ++ case FW_CDEV_ISO_CONTEXT_RECEIVE: ++ prot = PROT_READ; ++ break; ++ } ++ + handle->iso.buffer = + mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ | PROT_WRITE, MAP_SHARED, handle->iso.fd, 0); ++ prot, MAP_SHARED, handle->iso.fd, 0); + + if (handle->iso.buffer == MAP_FAILED) { + close(handle->iso.fd); + free(handle->iso.packets); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int raw1394_iso_recv_init(raw1394handle_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) -+{ -+ struct fw_cdev_create_iso_context create; -+ -+ if (handle->iso.fd != -1) { -+ errno = EBUSY; -+ return -1; -+ } -+ -+ /* FIXME: Do we need this? When would you ever want this...? */ -+ if (mode == RAW1394_DMA_PACKET_PER_BUFFER) -+ return -1; -+ -+ handle->iso.buffer = -+ mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ, MAP_SHARED, handle->iso.fd, 0); -+ -+ if (handle->iso.buffer == MAP_FAILED) -+ return -1; -+ -+ create.type = FW_CDEV_ISO_CONTEXT_RECEIVE; -+ create.channel = channel; -+ create.speed = 0; -+ create.header_size = 0; /* Never strip any headers. */ -+ -+ handle->iso.type = FW_CDEV_ISO_CONTEXT_RECEIVE; -+ handle->iso.irq_interval = irq_interval; -+ handle->iso.recv_handler = handler; -+ -+ return ioctl(handle->iso.fd, -+ FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); -+} -+ -+int raw1394_iso_multichannel_recv_init(raw1394handle_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 raw1394_iso_recv_listen_channel(raw1394handle_t handle, -+ unsigned char channel) -+{ -+ /* FIXME: multichannel */ -+ errno = ENOSYS; -+ return -1; -+} -+ -+int raw1394_iso_recv_unlisten_channel(raw1394handle_t handle, -+ unsigned char channel) -+{ -+ /* FIXME: multichannel */ -+ errno = ENOSYS; -+ return -1; -+} -+ -+int raw1394_iso_recv_set_channel_mask(raw1394handle_t handle, u_int64_t mask) -+{ -+ /* FIXME: multichannel */ -+ errno = ENOSYS; -+ return -1; -+} -+ -+void raw1394_iso_stop(raw1394handle_t handle) -+{ -+ ioctl(handle->iso.fd, FW_CDEV_IOC_STOP_ISO); -+} -+ -+void raw1394_iso_shutdown(raw1394handle_t handle) -+{ -+ munmap(handle->iso.buffer, -+ handle->iso.buf_packets * handle->iso.max_packet_size); -+ close(handle->iso.fd); -+ free(handle->iso.packets); -+} -Index: juju/juju.h -=================================================================== ---- juju/juju.h (revision 0) -+++ juju/juju.h (revision 0) -@@ -0,0 +1,139 @@ -+/* -*- c-basic-offset: 8 -*- -+ * -+ * juju.h -- Internal header file for raw1394 emulation -+ * -+ * Copyright (C) 2007 Kristian Hoegsberg -+ * -+ * 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 -+#include -+#include -+#include "../src/raw1394.h" -+#include "../src/csr.h" -+#include "config.h" -+ -+#define ACK_COMPLETE 1 -+ -+#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 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 raw1394_handle { -+ struct port ports[MAX_PORTS]; -+ int port_count; -+ int err; -+ int generation; -+ void *user_data; -+ 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; -+ struct allocation *allocations; -+ -+ int epoll_fd; -+ int inotify_fd; -+ int inotify_watch; -+ int pipe_fds[2]; ++ return -1; ++ } + -+ struct epoll_closure pipe_closure; -+ struct epoll_closure inotify_closure; ++ handle->iso.buffer_end = handle->iso.buffer + ++ buf_packets * max_packet_size; ++ handle->iso.head = handle->iso.buffer; ++ handle->iso.tail = handle->iso.buffer; ++ handle->iso.first_payload = handle->iso.buffer; + -+ struct device devices[MAX_DEVICES]; -+ int nodes[MAX_DEVICES]; -+ int local_fd; -+ char local_filename[FILENAME_SIZE]; ++ return 0; ++} + -+ struct fw_cdev_event_bus_reset reset; ++int raw1394_iso_xmit_init(raw1394handle_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); ++} + -+ struct { -+ struct epoll_closure closure; -+ int fd; -+ int type; -+ int irq_interval; -+ int packet_index; -+ int packet_phase; -+ int buf_packets; -+ int max_packet_size; -+ 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, *head, *tail; ++int raw1394_iso_recv_init(raw1394handle_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); ++} + -+ struct fw_cdev_queue_iso queue_iso; -+ struct fw_cdev_iso_packet *packets; -+ } iso; ++int raw1394_iso_multichannel_recv_init(raw1394handle_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; ++} + -+ char buffer[BUFFER_SIZE]; -+}; ++int raw1394_iso_recv_listen_channel(raw1394handle_t handle, ++ unsigned char channel) ++{ ++ /* FIXME: multichannel */ ++ errno = ENOSYS; ++ return -1; ++} + -+#endif -Index: juju/Makefile.am -=================================================================== ---- juju/Makefile.am (revision 0) -+++ juju/Makefile.am (revision 0) -@@ -0,0 +1,8 @@ -+lib_LTLIBRARIES = libraw1394.la ++int raw1394_iso_recv_unlisten_channel(raw1394handle_t handle, ++ unsigned char channel) ++{ ++ /* FIXME: multichannel */ ++ errno = ENOSYS; ++ return -1; ++} + -+INCLUDES = -I$(JUJU_DIR) -+libraw1394_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ ++int raw1394_iso_recv_set_channel_mask(raw1394handle_t handle, u_int64_t mask) ++{ ++ /* FIXME: multichannel */ ++ errno = ENOSYS; ++ return -1; ++} + -+libraw1394_la_SOURCES = raw1394.c raw1394-iso.c juju.h ++void raw1394_iso_stop(raw1394handle_t handle) ++{ ++ 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; ++} + -+pkginclude_HEADERS = ../src/raw1394.h ../src/csr.h ../src/ieee1394.h -Index: juju/raw1394.c -=================================================================== ---- juju/raw1394.c (revision 0) -+++ juju/raw1394.c (revision 0) -@@ -0,0 +1,1364 @@ ++void raw1394_iso_shutdown(raw1394handle_t handle) ++{ ++ munmap(handle->iso.buffer, ++ handle->iso.buf_packets * handle->iso.max_packet_size); ++ close(handle->iso.fd); ++ free(handle->iso.packets); ++} +diff --git a/juju/raw1394.c b/juju/raw1394.c +new file mode 100644 +index 0000000..fd5756d +--- /dev/null ++++ b/juju/raw1394.c +@@ -0,0 +1,1440 @@ +/* -*- c-basic-offset: 8 -*- + * + * raw1394.c -- Emulation of the raw1394 API on the juju stack @@ -980,7 +994,7 @@ Index: juju/raw1394.c + struct fw_cdev_send_response response; + int is_response; + -+ response.serial = request->serial; ++ response.handle = request->handle; + response.rcode = RCODE_COMPLETE; + response.length = 0; + response.data = 0; @@ -1011,11 +1025,7 @@ Index: juju/raw1394.c +handle_device_event(raw1394handle_t handle, + struct epoll_closure *ec, __uint32_t events) +{ -+ union { -+ struct fw_cdev_event_bus_reset bus_reset; -+ struct fw_cdev_event_response response; -+ struct fw_cdev_event_request request; -+ } *u; ++ union fw_cdev_event *u; + struct device *device = (struct device *) ec; + struct address_closure *ac; + struct request_closure *rc; @@ -1033,7 +1043,7 @@ Index: juju/raw1394.c + return -1; + + u = (void *) handle->buffer; -+ switch (u->response.type) { ++ switch (u->common.type) { + case FW_CDEV_EVENT_BUS_RESET: + /* Clear old entry, unless it's been overwritten. */ + phy_id = handle->devices[i].node_id & 0x3f; @@ -1483,6 +1493,7 @@ Index: juju/raw1394.c +struct allocation { + struct address_closure closure; + struct allocation *next; ++ __u32 handle; + byte_t *buffer; + octlet_t tag; + arm_options_t access_rights; @@ -1505,7 +1516,7 @@ Index: juju/raw1394.c + int offset; + + offset = request->offset - allocation->offset; -+ response.serial = request->serial; ++ response.handle = request->handle; + + switch (request->tcode) { + case TCODE_WRITE_QUADLET_REQUEST: @@ -1632,6 +1643,7 @@ Index: juju/raw1394.c + return -1; + } + ++ allocation->handle = request.handle; + allocation->next = handle->allocations; + handle->allocations = allocation; + @@ -1668,10 +1680,9 @@ Index: juju/raw1394.c + return -1; + } + ++ request.handle = allocation->handle; + free(allocation); + -+ request.offset = start; -+ + return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request); +} + @@ -2055,6 +2066,8 @@ Index: juju/raw1394.c + if (ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0) + return -1; + ++ handle->fcp_allocation_handle = request.handle; ++ + return 0; +} + @@ -2063,7 +2076,7 @@ Index: juju/raw1394.c +{ + struct fw_cdev_deallocate request; + -+ request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND; ++ request.handle = handle->fcp_allocation_handle; + + return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request); +} @@ -2104,22 +2117,253 @@ Index: juju/raw1394.c + return 0; +} + ++#define MAXIMUM_BANDWIDTH 4915 ++ +int -+raw1394_bandwidth_modify (raw1394handle_t handle, unsigned int bandwidth, ++raw1394_bandwidth_modify (raw1394handle_t handle, ++ unsigned int bandwidth, + enum raw1394_modify_mode mode) +{ -+ /* FIXME: copy and audit the libraw1394 version */ ++ 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; + -+ errno = ENOSYS; -+ return -1; ++ 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 -+raw1394_channel_modify (raw1394handle_t handle, unsigned int channel, ++raw1394_channel_modify (raw1394handle_t handle, ++ unsigned int channel, + enum raw1394_modify_mode mode) +{ -+ /* FIXME: copy and audit the libraw1394 version */ ++ 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; + -+ errno = ENOSYS; -+ return -1; ++ 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; ++} +diff --git a/tools/Makefile.am b/tools/Makefile.am +index 29b250e..5be1b6f 100644 +--- a/tools/Makefile.am ++++ b/tools/Makefile.am +@@ -2,4 +2,4 @@ MAINTAINERCLEANFILES = Makefile.in + + # testlibraw + bin_PROGRAMS = testlibraw sendiso dumpiso +-LDADD = ../src/libraw1394.la ++LDADD = ../$(LIB_SUBDIR)/libraw1394.la +diff --git a/tools/testlibraw.c b/tools/testlibraw.c +index 5f73bd9..2f02a6d 100644 +--- a/tools/testlibraw.c ++++ b/tools/testlibraw.c +@@ -1,4 +1,5 @@ +-/* ++/* -*- c-basic-offset: 8 -*- ++ * + * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. + * + * Copyright (C) 1999,2000 Andreas Bombe +@@ -13,12 +14,13 @@ + #include + #include + #include ++#include + + #include "../src/raw1394.h" + #include "../src/csr.h" + + +-#define TESTADDR (CSR_REGISTER_BASE + CSR_CYCLE_TIME) ++#define TESTADDR (CSR_REGISTER_BASE + CSR_CONFIG_ROM) + + const char not_compatible[] = "\ + This libraw1394 does not work with your version of Linux. You need a different\n\ +@@ -45,12 +47,18 @@ int my_tag_handler(raw1394handle_t handle, unsigned long tag, + return 0; + } + ++static const unsigned char fcp_data[] = ++ { 0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; ++ + int my_fcp_handler(raw1394handle_t handle, nodeid_t nodeid, int response, + size_t length, unsigned char *data) + { + printf("got fcp %s from node %d of %d bytes:", + (response ? "response" : "command"), nodeid & 0x3f, length); + ++ if (memcmp(fcp_data, data, sizeof fcp_data) != 0) ++ printf("ERROR: fcp payload not correct\n"); ++ + while (length) { + printf(" %02x", *data); + data++; +@@ -62,6 +70,47 @@ int my_fcp_handler(raw1394handle_t handle, nodeid_t nodeid, int response, + return 0; + } + ++static void ++test_fcp(raw1394handle_t handle) ++{ ++ printf("\ntesting FCP monitoring on local node\n"); ++ raw1394_set_fcp_handler(handle, my_fcp_handler); ++ raw1394_start_fcp_listen(handle); ++ raw1394_write(handle, raw1394_get_local_id(handle), ++ CSR_REGISTER_BASE + CSR_FCP_COMMAND, sizeof(fcp_data), ++ (quadlet_t *)fcp_data); ++ raw1394_write(handle, raw1394_get_local_id(handle), ++ CSR_REGISTER_BASE + CSR_FCP_RESPONSE, sizeof(fcp_data), ++ (quadlet_t *)fcp_data); ++} ++ ++static void ++read_topology_map(raw1394handle_t handle) ++{ ++ quadlet_t map[70]; ++ nodeid_t local_id; ++ int node_count, self_id_count, i, retval; ++ ++ local_id = raw1394_get_local_id(handle) | 0xffc0; ++ ++ retval = raw1394_read(handle, local_id, ++ CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP, 12, &map[0]); ++ if (retval < 0) ++ perror("topology map: raw1394_read failed with error"); ++ ++ self_id_count = ntohl(map[2]) & 0xffff; ++ node_count = ntohl(map[2]) >> 16; ++ retval = raw1394_read(handle, local_id, ++ CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP + 12, ++ self_id_count * sizeof map[0], &map[3]); ++ if (retval < 0) ++ perror("topology map: raw1394_read failed with error"); ++ ++ printf("topology map: %d nodes, %d self ids, generation %d\n", ++ node_count, self_id_count, ntohl(map[1])); ++ for (i = 0; i < self_id_count; i++) ++ printf(" 0x%08x\n", ntohl(map[3 + i])); +} + + int main(int argc, char **argv) + { +@@ -73,7 +122,6 @@ int main(int argc, char **argv) + int retval; + + struct pollfd pfd; +- unsigned char fcp_test[] = { 0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; + quadlet_t rom[0x100]; + size_t rom_size; + unsigned char rom_version; +@@ -150,17 +198,8 @@ int main(int argc, char **argv) + } + } + +- printf("\ntesting FCP monitoring on local node\n"); +- raw1394_set_fcp_handler(handle, my_fcp_handler); +- raw1394_start_fcp_listen(handle); +- raw1394_write(handle, raw1394_get_local_id(handle), +- CSR_REGISTER_BASE + CSR_FCP_COMMAND, sizeof(fcp_test), +- (quadlet_t *)fcp_test); +- raw1394_write(handle, raw1394_get_local_id(handle), +- CSR_REGISTER_BASE + CSR_FCP_RESPONSE, sizeof(fcp_test), +- (quadlet_t *)fcp_test); +- +- ++ test_fcp(handle); ++ read_topology_map(handle); + + printf("testing config rom stuff\n"); + retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version); +@@ -176,16 +215,19 @@ int main(int argc, char **argv) + retval=raw1394_update_config_rom(handle, rom, rom_size, rom_version); + printf("update_config_rom returned %d\n",retval); + ++ printf("\nposting 0xdeadbeef as an echo request\n"); ++ raw1394_echo_request(handle, 0xdeadbeef); + +- +- printf("\npolling for leftover messages\n"); ++ printf("polling for leftover messages\n"); + pfd.fd = raw1394_get_fd(handle); + pfd.events = POLLIN; + pfd.revents = 0; + while (1) { + retval = poll(&pfd, 1, 10); + if (retval < 1) break; +- raw1394_loop_iterate(handle); ++ retval = raw1394_loop_iterate(handle); ++ if (retval != 0) ++ printf("raw1394_loop_iterate() returned 0x%08x\n", retval); + } + + if (retval < 0) perror("poll failed"); diff --git a/libraw1394.spec b/libraw1394.spec index c85c29a..3c5a578 100644 --- a/libraw1394.spec +++ b/libraw1394.spec @@ -1,7 +1,7 @@ Summary: Library providing low-level IEEE-1394 access Name: libraw1394 Version: 1.2.1 -Release: 3%{?dist} +Release: 4%{?dist} License: LGPL Group: System Environment/Libraries Source: http://www.linux1394.org/dl/libraw1394-%{version}.tar.gz @@ -75,6 +75,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Apr 3 2007 Kristian Høgsberg - 1.2.1-4 +- Update juju patch with rawiso support. + * Mon Mar 19 2007 Kristian Høgsberg 1.2.1-3 - Add support for new stack (juju).