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 +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 - #include "../src/raw1394.h" - #include "../src/csr.h" +-SUBDIRS = src tools doc debian ++SUBDIRS = $(LIB_SUBDIR) tools doc debian ++DIST_SUBDIRS = src juju - --#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); - } - - if (retval < 0) perror("poll failed"); -Index: tools/Makefile.am -=================================================================== ---- tools/Makefile.am (revision 171) -+++ tools/Makefile.am (working copy) -@@ -2,4 +2,4 @@ - - # 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,414 +51,26 @@ 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 @@ -+/* -*- c-basic-offset: 8 -*- -+ * -+ * raw1394-iso.c -- Emulation of the raw1394 rawiso API on the juju stack -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "juju.h" -+ -+static int -+refill_xmit_buffer(raw1394handle_t handle, struct fw_cdev_queue_iso *queue_iso) -+{ -+ int i; -+ struct fw_cdev_iso_packet *p = handle->iso.packets; -+ 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; -+ -+ for (i = 0; i < handle->iso.irq_interval; i++) { -+ cycle = -1; -+ dropped = 0; -+ d = handle->iso.xmit_handler(handle, data, -+ &len, &tag, &sy, cycle, dropped); -+ /* FIXME: handle the different dispositions. */ -+ -+ p->payload_length = len; -+ p->interrupt = handle->iso.packet_phase == 0; -+ 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.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); -+ -+ return 0; -+} -+ -+static int -+flush_xmit_packets(raw1394handle_t handle, int limit) -+{ -+ struct fw_cdev_queue_iso queue_iso; -+ 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) -+ return -1; -+ if (handle->iso.queue_iso.size > 0) -+ break; -+ } -+ -+ return 0; -+} -+ -+int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, -+ int prebuffer_packets) -+{ -+ struct fw_cdev_start_iso start_iso; -+ int retval; -+ -+ if (prebuffer_packets == -1) -+ prebuffer_packets = handle->iso.irq_interval; -+ -+ flush_xmit_packets(handle, prebuffer_packets); -+ -+ 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 -+handle_recv_packets(raw1394handle_t handle, -+ struct fw_cdev_event_iso_interrupt *interrupt) -+{ -+ enum raw1394_iso_disposition d; -+ quadlet_t header, *p, *end; -+ unsigned int len, cycle, dropped; -+ unsigned char channel, tag, sy; -+ unsigned char *data; -+ -+ p = interrupt->header; -+ end = (void *) interrupt->header + interrupt->header_length; -+ cycle = interrupt->cycle; -+ data = NULL; -+ -+ 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); -+ cycle++; -+ } -+ -+ return 0; -+} -+ -+int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle, -+ int tag_mask, int sync) -+{ -+ struct fw_cdev_start_iso start_iso; -+ -+ 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; -+ -+ 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) -+{ -+ struct fw_cdev_event_iso_interrupt *interrupt; -+ int len; -+ -+ len = read(handle->iso.fd, handle->buffer, sizeof handle->buffer); -+ if (len < 0) -+ return -1; -+ -+ interrupt = (struct fw_cdev_event_iso_interrupt *) handle->buffer; -+ if (interrupt->type != FW_CDEV_EVENT_BUS_RESET) -+ return 0; -+ -+ switch (handle->iso.type) { -+ case FW_CDEV_ISO_CONTEXT_TRANSMIT: -+ handle->iso.packet_index -= 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); -+ default: -+ /* Doesn't happen. */ -+ return -1; -+ } -+} -+ -+int raw1394_iso_xmit_write(raw1394handle_t handle, unsigned char *data, -+ unsigned int len, unsigned char tag, -+ unsigned char sy) -+{ -+ struct fw_cdev_iso_packet packet; -+ -+ packet.payload_length = len; -+ packet.interrupt = handle->iso.packet_phase == 0; -+ packet.skip = 0; -+ packet.tag = tag; -+ packet.sy = sy; -+ packet.header_length = 0; -+ -+ handle->iso.packet_phase++; -+ if (handle->iso.packet_phase == handle->iso.irq_interval) -+ handle->iso.packet_phase = 0; -+ -+ /* FIXME: circular buffer goo. */ -+ -+ memcpy(handle->iso.head, data, len); -+ handle->iso.head += len; -+ -+ return -1; -+} -+ -+int raw1394_iso_xmit_sync(raw1394handle_t handle) -+{ -+ /* FIXME: queue a skip packet and wait for that interrupt. */ -+ -+ return 0; -+} -+ -+int raw1394_iso_recv_flush(raw1394handle_t handle) -+{ -+ /* FIXME: huh, we'll need kernel support here... */ -+ -+ 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) -+{ -+ struct fw_cdev_create_iso_context create; -+ struct epoll_event ep; -+ int retval; -+ -+ 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.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.packets = -+ malloc(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); -+ 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); -+ return -1; -+ } -+ -+ create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ create.channel = channel; -+ create.speed = speed; -+ -+ retval = ioctl(handle->iso.fd, -+ FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); -+ if (retval < 0) { -+ close(handle->iso.fd); -+ free(handle->iso.packets); -+ return retval; -+ } -+ -+ handle->iso.buffer = -+ mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ | PROT_WRITE, 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 @@ +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 @@ -702,6 +171,7 @@ Index: juju/juju.h + 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; @@ -724,16 +194,19 @@ Index: juju/juju.h + int fd; + int type; + int irq_interval; -+ int packet_index; + 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, *head, *tail; ++ unsigned char *buffer, *buffer_end, *head; ++ unsigned char *tail, *first_payload; + -+ struct fw_cdev_queue_iso queue_iso; + struct fw_cdev_iso_packet *packets; + } iso; + @@ -741,24 +214,565 @@ Index: juju/juju.h +}; + +#endif -Index: juju/Makefile.am -=================================================================== ---- juju/Makefile.am (revision 0) -+++ juju/Makefile.am (revision 0) -@@ -0,0 +1,8 @@ -+lib_LTLIBRARIES = libraw1394.la +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 ++ * ++ * 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. ++ */ + -+INCLUDES = -I$(JUJU_DIR) -+libraw1394_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+libraw1394_la_SOURCES = raw1394.c raw1394-iso.c juju.h ++#include "juju.h" + -+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 @@ ++static enum raw1394_iso_disposition ++queue_xmit_packets(raw1394handle_t handle) ++{ ++ 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, *first_payload; ++ int cycle, i; ++ ++ first_payload = handle->iso.head; ++ for (i = 0; i < handle->iso.irq_interval; i++) { ++ cycle = -1; ++ dropped = 0; ++ ++ 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); ++ if (d != RAW1394_ISO_OK) ++ break; ++ ++ 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; ++ ++ 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 = i * sizeof handle->iso.packets[0]; ++ queue_iso.data = ptr_to_u64(first_payload); ++ ++ 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) ++{ ++ enum raw1394_iso_disposition d; ++ int len; ++ ++ 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; ++ case RAW1394_ISO_STOP: ++ raw1394_iso_stop(handle); ++ return 0; ++ } ++ } ++ ++ return 0; ++} ++ ++int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, ++ int prebuffer_packets) ++{ ++ struct fw_cdev_start_iso start_iso; ++ int retval; ++ ++ 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; ++ ++ handle->iso.head += handle->iso.max_packet_size; ++ 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 = i * sizeof handle->iso.packets[0]; ++ queue_iso.data = ptr_to_u64(first_payload); ++ ++ len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); ++ if (len < 0) ++ return -1; ++ ++ return 0; ++} ++ ++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; ++ unsigned int len, cycle, dropped; ++ unsigned char channel, tag, sy; ++ unsigned char *data; ++ ++ p = interrupt->header; ++ end = (void *) interrupt->header + interrupt->header_length; ++ cycle = interrupt->cycle; ++ dropped = 0; ++ ++ while (p < end) { ++ header = be32_to_cpu(*p++); ++ 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; ++} ++ ++int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle, ++ int tag_mask, int sync) ++{ ++ 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; ++ /* sync is documented as 'not used' */ ++ start_iso.sync = 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) ++{ ++ struct fw_cdev_event_iso_interrupt *interrupt; ++ int len; ++ ++ len = read(handle->iso.fd, handle->buffer, sizeof handle->buffer); ++ if (len < 0) ++ return -1; ++ ++ interrupt = (struct fw_cdev_event_iso_interrupt *) handle->buffer; ++ if (interrupt->type != FW_CDEV_EVENT_ISO_INTERRUPT) ++ return 0; ++ ++ switch (handle->iso.type) { ++ case FW_CDEV_ISO_CONTEXT_TRANSMIT: ++ handle->iso.packet_count -= handle->iso.irq_interval; ++ return flush_xmit_packets(handle, handle->iso.buf_packets); ++ case FW_CDEV_ISO_CONTEXT_RECEIVE: ++ return flush_recv_packets(handle, interrupt); ++ default: ++ /* Doesn't happen. */ ++ return -1; ++ } ++} ++ ++int raw1394_iso_xmit_write(raw1394handle_t handle, unsigned char *data, ++ unsigned int len, unsigned char tag, ++ unsigned char sy) ++{ ++ 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; ++ ++ 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; ++ ++ 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_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; ++ ++ 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) ++{ ++ /* FIXME: queue a skip packet and wait for that interrupt. */ ++ ++ return 0; ++} ++ ++int raw1394_iso_recv_flush(raw1394handle_t handle) ++{ ++ /* FIXME: huh, we'll need kernel support here... */ ++ ++ return 0; ++} ++ ++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, prot; ++ ++ if (handle->iso.fd != -1) { ++ errno = EBUSY; ++ 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 = 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); ++ 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); ++ 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); ++ 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, MAP_SHARED, handle->iso.fd, 0); ++ ++ if (handle->iso.buffer == MAP_FAILED) { ++ close(handle->iso.fd); ++ free(handle->iso.packets); ++ return -1; ++ } ++ ++ 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; ++ ++ 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) ++{ ++ return iso_init(handle, FW_CDEV_ISO_CONTEXT_TRANSMIT, ++ handler, NULL, buf_packets, max_packet_size, ++ channel, speed, irq_interval); ++} ++ ++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); ++} ++ ++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); ++ 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 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; + -+ errno = ENOSYS; -+ return -1; ++ 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 -+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).