From c7c35b57d16156fbcf9603acb2d72f6946266f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 20 Mar 2007 16:14:44 +0000 Subject: [PATCH] Update juju patch. --- libraw1394-juju.patch | 642 +++++++++++++++++++++++++++++------------- 1 file changed, 441 insertions(+), 201 deletions(-) diff --git a/libraw1394-juju.patch b/libraw1394-juju.patch index c04f781..0f4d039 100644 --- a/libraw1394-juju.patch +++ b/libraw1394-juju.patch @@ -211,7 +211,7 @@ Index: juju/raw1394-iso.c =================================================================== --- juju/raw1394-iso.c (revision 0) +++ juju/raw1394-iso.c (revision 0) -@@ -0,0 +1,197 @@ +@@ -0,0 +1,377 @@ +/* -*- c-basic-offset: 8 -*- + * + * raw1394-iso.c -- Emulation of the raw1394 rawiso API on the juju stack @@ -235,9 +235,204 @@ Index: juju/raw1394-iso.c + +#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); ++} ++ ++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++; ++ } ++} ++ ++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: ++ break; ++ default: ++ /* Doesn't happen. */ ++ break; ++ } ++} ++ ++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. */ ++} ++ ++int raw1394_iso_recv_flush(raw1394handle_t handle) ++{ ++ /* FIXME: huh, we'll need kernel support here... */ ++} ++ +int raw1394_iso_xmit_init(raw1394handle_t handle, + raw1394_iso_xmit_handler_t handler, + unsigned int buf_packets, @@ -247,24 +442,66 @@ Index: juju/raw1394-iso.c + int irq_interval) +{ + struct fw_cdev_create_iso_context create; ++ struct epoll_event ep; ++ int retval; + -+ handle->iso.buffer = -+ mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ | PROT_WRITE, MAP_SHARED, handle->local_fd, 0); ++ if (handle->iso.fd != -1) { ++ errno = EBUSY; ++ return -1; ++ } + -+ if (handle->iso.buffer == MAP_FAILED) ++ 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; + -+ handle->iso.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ handle->iso.irq_interval = irq_interval; -+ handle->iso.xmit_handler = handler; ++ 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; ++ } + -+ return ioctl(handle->local_fd, -+ FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); ++ 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, @@ -277,27 +514,32 @@ Index: juju/raw1394-iso.c +{ + 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->local_fd, 0); ++ PROT_READ, MAP_SHARED, handle->iso.fd, 0); + + if (handle->iso.buffer == MAP_FAILED) + return -1; + -+ create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; ++ 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_TRANSMIT; ++ handle->iso.type = FW_CDEV_ISO_CONTEXT_RECEIVE; + handle->iso.irq_interval = irq_interval; + handle->iso.recv_handler = handler; + -+ return ioctl(handle->local_fd, ++ return ioctl(handle->iso.fd, + FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); +} + @@ -308,6 +550,7 @@ Index: juju/raw1394-iso.c + int irq_interval) +{ + /* FIXME: gah */ ++ errno = ENOSYS; + return -1; +} + @@ -315,6 +558,7 @@ Index: juju/raw1394-iso.c + unsigned char channel) +{ + /* FIXME: multichannel */ ++ errno = ENOSYS; + return -1; +} + @@ -322,98 +566,34 @@ Index: juju/raw1394-iso.c + 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; +} + -+int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, -+ int prebuffer_packets) -+{ -+ struct fw_cdev_start_iso start_iso; -+ -+ handle->iso.start_cycle = start_on_cycle; -+ if (prebuffer_packets == -1) -+ handle->iso.prebuffer = 64; -+ else -+ handle->iso.prebuffer = prebuffer_packets; -+ -+ if (handle->iso.buffered_packet_count < handle->iso.prebuffer) -+ return 0; -+ -+ start_iso.cycle = handle->iso.start_cycle; -+ -+ return ioctl(handle->local_fd, FW_CDEV_IOC_START_ISO, &start_iso); -+} -+ -+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->local_fd, FW_CDEV_IOC_START_ISO, &start_iso); -+} -+ -+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. */ -+} -+ -+int raw1394_iso_recv_flush(raw1394handle_t handle) -+{ -+ /* FIXME: huh, we'll need kernel support here... */ -+} -+ +void raw1394_iso_stop(raw1394handle_t handle) +{ -+ ioctl(handle->local_fd, FW_CDEV_IOC_STOP_ISO); ++ ioctl(handle->iso.fd, FW_CDEV_IOC_STOP_ISO); +} + +void raw1394_iso_shutdown(raw1394handle_t handle) +{ -+ /* Maybe we should just open a new fd for the local device and -+ * close that here... */ ++ 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,107 @@ +@@ -0,0 +1,139 @@ +/* -*- c-basic-offset: 8 -*- + * + * juju.h -- Internal header file for raw1394 emulation @@ -439,6 +619,7 @@ Index: juju/juju.h +#define __juju_h + +#include ++#include +#include +#include "../src/raw1394.h" +#include "../src/csr.h" @@ -449,12 +630,31 @@ Index: juju/juju.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 epoll_closure { ++ int (*func)(raw1394handle_t handle, ++ struct epoll_closure *closure, __uint32_t events); ++}; ++ +struct port { + char device_file[32]; + char *name; @@ -463,23 +663,25 @@ Index: juju/juju.h +}; + +#define MAX_DEVICES 63 -+#define INOTIFY_INDEX 64 -+#define PIPE_INDEX 65 ++#define FILENAME_SIZE 16 + +struct device { ++ struct epoll_closure closure; + int fd; + int node_id; + int generation; -+ char filename[16]; ++ char filename[FILENAME_SIZE]; +}; + -+struct closure { ++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; @@ -492,29 +694,39 @@ Index: juju/juju.h + 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]; + ++ 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 prebuffer; -+ int start_cycle; -+ int buffered_packet_count; ++ 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; ++ ++ struct fw_cdev_queue_iso queue_iso; ++ struct fw_cdev_iso_packet *packets; + } iso; + + char buffer[BUFFER_SIZE]; @@ -538,7 +750,7 @@ Index: juju/raw1394.c =================================================================== --- juju/raw1394.c (revision 0) +++ juju/raw1394.c (revision 0) -@@ -0,0 +1,1336 @@ +@@ -0,0 +1,1364 @@ +/* -*- c-basic-offset: 8 -*- + * + * raw1394.c -- Emulation of the raw1394 API on the juju stack @@ -564,6 +776,7 @@ Index: juju/raw1394.c +#include +#include +#include ++#include +#include +#include +#include @@ -650,7 +863,7 @@ Index: juju/raw1394.c + + rh = (struct raw1394_arm_reqhandle *) arm_tag; + -+ rh->arm_callback(handle, data, length, rh->pcontext, type); ++ return rh->arm_callback(handle, data, length, rh->pcontext, type); +} + +static int @@ -671,7 +884,6 @@ Index: juju/raw1394.c + struct fw_cdev_event_bus_reset reset; + int fd, err, i; + struct port *ports; -+ size_t size; + + ports = handle->ports; + memset(ports, 0, sizeof handle->ports); @@ -720,7 +932,8 @@ Index: juju/raw1394.c +} + +static int -+handle_echo_pipe(raw1394handle_t handle) ++handle_echo_pipe(raw1394handle_t handle, ++ struct epoll_closure *ec, __uint32_t events) +{ + quadlet_t value; + @@ -731,76 +944,6 @@ Index: juju/raw1394.c +} + +static int -+handle_new_device(raw1394handle_t handle) -+{ -+ 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 *) handle->buffer; -+ len = read(handle->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 (handle->devices[i].node_id == -1) -+ break; -+ if (i == MAX_DEVICES) { -+ close(fd); -+ return -1; -+ } -+ -+ 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); -+ ep.events = EPOLLIN; -+ ep.data.u32 = i; -+ if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { -+ close(fd); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int +handle_lost_device(raw1394handle_t handle, int i) +{ + int phy_id; @@ -849,26 +992,32 @@ Index: juju/raw1394.c + + is_response = request->offset >= CSR_REGISTER_BASE + CSR_FCP_RESPONSE; + -+ handle->fcp_handler(handle, -+ handle->devices[i].node_id, -+ is_response, -+ request->length, -+ (unsigned char *) request->data); ++ return handle->fcp_handler(handle, ++ handle->devices[i].node_id, ++ is_response, ++ request->length, ++ (unsigned char *) request->data); +} + +static int -+handle_device_event(raw1394handle_t handle, int i) ++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; -+ struct fw_cdev_event_iso_interrupt interrupt; + } *u; ++ struct device *device = (struct device *) ec; + struct address_closure *ac; -+ struct closure *closure; ++ struct request_closure *rc; + raw1394_errcode_t errcode; -+ int fd, last, len, phy_id; ++ int len, phy_id; ++ int i; ++ ++ i = device - handle->devices; ++ if (events == EPOLLHUP) ++ return handle_lost_device(handle, i); + + len = read(handle->devices[i].fd, + handle->buffer, sizeof handle->buffer); @@ -894,29 +1043,102 @@ Index: juju/raw1394.c + u->bus_reset.generation); + + case FW_CDEV_EVENT_RESPONSE: -+ closure = u64_to_ptr(u->response.closure); ++ rc = u64_to_ptr(u->response.closure); + -+ if (closure->data != NULL) -+ memcpy(closure->data, -+ u->response.data, closure->length); ++ if (rc->data != NULL) ++ memcpy(rc->data, u->response.data, rc->length); + + errcode = juju_to_raw1394_errcode(u->response.rcode); + -+ return handle->tag_handler(handle, closure->tag, errcode); ++ return handle->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) ++{ ++ 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 *) handle->buffer; ++ len = read(handle->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 (handle->devices[i].node_id == -1) ++ break; ++ if (i == MAX_DEVICES) { ++ close(fd); ++ return -1; ++ } ++ ++ 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; ++ } ++ ++ return 0; +} + +int raw1394_loop_iterate(raw1394handle_t handle) +{ -+ int i, last, count, retval = 0; -+ ++ int i, count, retval = 0; ++ struct epoll_closure *closure; + struct epoll_event ep[32]; + + count = epoll_wait(handle->epoll_fd, ep, ARRAY_LENGTH(ep), -1); @@ -924,14 +1146,8 @@ Index: juju/raw1394.c + return -1; + + for (i = 0; i < count; i++) { -+ if (ep[i].data.u32 == PIPE_INDEX) -+ retval = handle_echo_pipe(handle); -+ else if (ep[i].data.u32 == INOTIFY_INDEX) -+ retval = handle_new_device(handle); -+ else if (ep[i].events & EPOLLHUP) -+ retval = handle_lost_device(handle, ep[i].data.u32); -+ else if (ep[i].events & EPOLLIN) -+ retval = handle_device_event(handle, ep[i].data.u32); ++ 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 @@ -951,10 +1167,13 @@ Index: juju/raw1394.c + + 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; @@ -971,14 +1190,16 @@ Index: juju/raw1394.c + if (handle->inotify_watch < 0) + goto out_inotify; + ++ handle->pipe_closure.func = handle_echo_pipe; + ep.events = EPOLLIN; -+ ep.data.u32 = PIPE_INDEX; ++ 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.u32 = INOTIFY_INDEX; ++ ep.data.ptr = &handle->inotify_closure; + if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, + handle->inotify_fd, &ep) < 0) + goto out_inotify; @@ -1150,8 +1371,9 @@ Index: juju/raw1394.c + strncpy(handle->devices[i].filename, filename, + sizeof handle->devices[i].filename); + ++ handle->devices[i].closure.func = handle_device_event; + ep.events = EPOLLIN; -+ ep.data.u32 = i; ++ ep.data.ptr = &handle->devices[i].closure; + if (epoll_ctl(handle->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { + close(fd); + return -1; @@ -1161,6 +1383,8 @@ Index: juju/raw1394.c + 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++; @@ -1171,7 +1395,7 @@ Index: juju/raw1394.c + +int raw1394_reset_bus(raw1394handle_t handle) +{ -+ raw1394_reset_bus_new(handle, RAW1394_LONG_RESET); ++ return raw1394_reset_bus_new(handle, RAW1394_LONG_RESET); +} + +int raw1394_reset_bus_new(raw1394handle_t handle, int type) @@ -1187,7 +1411,8 @@ Index: juju/raw1394.c + break; + } + -+ return ioctl(handle->local_fd, FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate); ++ return ioctl(handle->local_fd, ++ FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate); +} + +bus_reset_handler_t raw1394_set_bus_reset_handler(raw1394handle_t handle, @@ -1249,6 +1474,7 @@ Index: juju/raw1394.c + +struct allocation { + struct address_closure closure; ++ struct allocation *next; + byte_t *buffer; + octlet_t tag; + arm_options_t access_rights; @@ -1266,7 +1492,6 @@ Index: juju/raw1394.c + struct allocation *allocation = (struct allocation *) ac; + struct request_response_block *rrb; + struct fw_cdev_send_response response; -+ struct raw1394_arm_request_response *arm_req_resp; + arm_options_t type; + size_t in_length; + int offset; @@ -1306,6 +1531,7 @@ Index: juju/raw1394.c + break; + + default: ++ in_length = 0; + type = 0; + break; + } @@ -1357,8 +1583,9 @@ Index: juju/raw1394.c + memcpy(rrb->response.buffer, + allocation->data + offset, response.length); + -+ handle->arm_tag_handler(handle, allocation->tag, type, -+ request->length, &rrb->request_response); ++ return handle->arm_tag_handler(handle, allocation->tag, type, ++ request->length, ++ &rrb->request_response); +} + +int @@ -1370,6 +1597,7 @@ Index: juju/raw1394.c +{ + struct fw_cdev_allocate request; + struct allocation *allocation; ++ int retval; + + allocation = malloc(sizeof *allocation + length); + if (allocation == NULL) @@ -1486,12 +1714,16 @@ Index: juju/raw1394.c + +int raw1394_phy_packet_write (raw1394handle_t handle, quadlet_t data) +{ ++ errno = ENOSYS; ++ return -1; +} + +int +raw1394_start_phy_packet_write(raw1394handle_t handle, + quadlet_t data, unsigned long tag) +{ ++ errno = ENOSYS; ++ return -1; +} + +static int @@ -1500,8 +1732,8 @@ Index: juju/raw1394.c + size_t length, void *in, void *out, unsigned long tag) +{ + struct fw_cdev_send_request *request; -+ struct closure *closure; -+ int i, fd; ++ struct request_closure *closure; ++ int i; + + if (node > handle->reset.root_node_id) { + handle->err = -RCODE_NO_ACK; @@ -1685,6 +1917,8 @@ Index: juju/raw1394.c + + sd->err = err; + sd->done = 1; ++ ++ return 0; +} + +static int @@ -1867,6 +2101,9 @@ Index: juju/raw1394.c + enum raw1394_modify_mode mode) +{ + /* FIXME: copy and audit the libraw1394 version */ ++ ++ errno = ENOSYS; ++ return -1; +} + +int @@ -1874,4 +2111,7 @@ Index: juju/raw1394.c + enum raw1394_modify_mode mode) +{ + /* FIXME: copy and audit the libraw1394 version */ ++ ++ errno = ENOSYS; ++ return -1; +}