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 | 720 ++++++++++++++++++++++++++++-------------- 1 file changed, 480 insertions(+), 240 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,119 +235,127 @@ Index: juju/raw1394-iso.c + +#include +#include ++#include ++#include ++#include ++#include ++#include + +#include "juju.h" + -+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 ++refill_xmit_buffer(raw1394handle_t handle, struct fw_cdev_queue_iso *queue_iso) +{ -+ struct fw_cdev_create_iso_context create; ++ 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; + -+ handle->iso.buffer = -+ mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ | PROT_WRITE, MAP_SHARED, handle->local_fd, 0); ++ buffer = handle->iso.buffer + ++ handle->iso.packet_index * handle->iso.max_packet_size; ++ data = buffer; + -+ if (handle->iso.buffer == MAP_FAILED) -+ return -1; ++ 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. */ + -+ create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ create.channel = channel; -+ create.speed = speed; ++ p->payload_length = len; ++ p->interrupt = handle->iso.packet_phase == 0; ++ p->skip = 0; ++ p->tag = tag; ++ p->sy = sy; ++ p->header_length = 0; + -+ handle->iso.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ handle->iso.irq_interval = irq_interval; -+ handle->iso.xmit_handler = handler; ++ 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; ++ } + -+ return ioctl(handle->local_fd, -+ FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); ++ 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); +} + -+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) ++static int ++flush_xmit_packets(raw1394handle_t handle, int limit) +{ -+ struct fw_cdev_create_iso_context create; ++ struct fw_cdev_queue_iso queue_iso; ++ int len; + -+ /* FIXME: Do we need this? When would you ever want this...? */ -+ if (mode == RAW1394_DMA_PACKET_PER_BUFFER) -+ return -1; ++ 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; ++ } + -+ handle->iso.buffer = -+ mmap(NULL, buf_packets * max_packet_size, -+ PROT_READ, MAP_SHARED, handle->local_fd, 0); -+ -+ if (handle->iso.buffer == MAP_FAILED) -+ return -1; -+ -+ create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ create.channel = channel; -+ create.speed = 0; -+ create.header_size = 0; /* Never strip any headers. */ -+ -+ handle->iso.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; -+ handle->iso.irq_interval = irq_interval; -+ handle->iso.recv_handler = handler; -+ -+ return ioctl(handle->local_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 */ -+ return -1; -+} -+ -+int raw1394_iso_recv_listen_channel(raw1394handle_t handle, -+ unsigned char channel) -+{ -+ /* FIXME: multichannel */ -+ return -1; -+} -+ -+int raw1394_iso_recv_unlisten_channel(raw1394handle_t handle, -+ unsigned char channel) -+{ -+ /* FIXME: multichannel */ -+ return -1; -+} -+ -+int raw1394_iso_recv_set_channel_mask(raw1394handle_t handle, u_int64_t mask) -+{ -+ /* FIXME: multichannel */ -+ return -1; ++ 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; + -+ handle->iso.start_cycle = start_on_cycle; + if (prebuffer_packets == -1) -+ handle->iso.prebuffer = 64; -+ else -+ handle->iso.prebuffer = prebuffer_packets; ++ prebuffer_packets = handle->iso.irq_interval; + -+ if (handle->iso.buffered_packet_count < handle->iso.prebuffer) -+ return 0; ++ flush_xmit_packets(handle, prebuffer_packets); + -+ start_iso.cycle = handle->iso.start_cycle; ++ start_iso.cycle = start_on_cycle; + -+ return ioctl(handle->local_fd, FW_CDEV_IOC_START_ISO, &start_iso); ++ 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, @@ -361,7 +369,33 @@ Index: juju/raw1394-iso.c + /* sync is documented as 'not used' */ + start_iso.sync = 0; + -+ return ioctl(handle->local_fd, FW_CDEV_IOC_START_ISO, &start_iso); ++ 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, @@ -399,21 +433,167 @@ Index: juju/raw1394-iso.c + /* 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, ++ 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->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,7 +944,128 @@ Index: juju/raw1394.c +} + +static int -+handle_new_device(raw1394handle_t handle) ++handle_lost_device(raw1394handle_t handle, int i) ++{ ++ int phy_id; ++ ++ /* The device got unplugged, get rid of it. The fd is ++ * automatically dropped from the epoll context when we close it. */ ++ ++ close(handle->devices[i].fd); ++ phy_id = handle->devices[i].node_id & 0x3f; ++ if (handle->nodes[phy_id] == i) ++ handle->nodes[phy_id] = -1; ++ handle->devices[i].node_id = -1; ++ ++ return 0; ++} ++ ++struct address_closure { ++ int (*callback)(raw1394handle_t handle, struct address_closure *ac, ++ struct fw_cdev_event_request *request, int i); ++}; ++ ++static int ++handle_fcp_request(raw1394handle_t handle, struct address_closure *ac, ++ struct fw_cdev_event_request *request, int i) ++{ ++ struct fw_cdev_send_response response; ++ int is_response; ++ ++ response.serial = request->serial; ++ response.rcode = RCODE_COMPLETE; ++ response.length = 0; ++ response.data = 0; ++ ++ if (handle->fcp_handler == NULL) ++ response.rcode = RCODE_ADDRESS_ERROR; ++ ++ if (request->tcode >= TCODE_WRITE_RESPONSE) ++ response.rcode = RCODE_CONFLICT_ERROR; ++ ++ if (ioctl(handle->devices[i].fd, ++ FW_CDEV_IOC_SEND_RESPONSE, &response) < 0) ++ return -1; ++ ++ if (response.rcode != RCODE_COMPLETE) ++ return 0; ++ ++ is_response = request->offset >= CSR_REGISTER_BASE + CSR_FCP_RESPONSE; ++ ++ return handle->fcp_handler(handle, ++ handle->devices[i].node_id, ++ is_response, ++ request->length, ++ (unsigned char *) request->data); ++} ++ ++static int ++handle_device_event(raw1394handle_t handle, ++ struct epoll_closure *ec, __uint32_t events) ++{ ++ union { ++ struct fw_cdev_event_bus_reset bus_reset; ++ struct fw_cdev_event_response response; ++ struct fw_cdev_event_request request; ++ } *u; ++ struct device *device = (struct device *) ec; ++ struct address_closure *ac; ++ struct request_closure *rc; ++ raw1394_errcode_t errcode; ++ int len, phy_id; ++ int i; ++ ++ i = device - handle->devices; ++ if (events == EPOLLHUP) ++ return handle_lost_device(handle, i); ++ ++ len = read(handle->devices[i].fd, ++ handle->buffer, sizeof handle->buffer); ++ if (len < 0) ++ return -1; ++ ++ u = (void *) handle->buffer; ++ switch (u->response.type) { ++ case FW_CDEV_EVENT_BUS_RESET: ++ /* Clear old entry, unless it's been overwritten. */ ++ phy_id = handle->devices[i].node_id & 0x3f; ++ if (handle->nodes[phy_id] == i) ++ handle->nodes[phy_id] = -1; ++ handle->nodes[u->bus_reset.node_id & 0x3f] = i; ++ handle->devices[i].node_id = u->bus_reset.node_id; ++ handle->devices[i].generation = u->bus_reset.generation; ++ ++ if (u->bus_reset.node_id != u->bus_reset.local_node_id) ++ return 0; ++ ++ memcpy(&handle->reset, &u->bus_reset, sizeof handle->reset); ++ return handle->bus_reset_handler(handle, ++ u->bus_reset.generation); ++ ++ case FW_CDEV_EVENT_RESPONSE: ++ rc = u64_to_ptr(u->response.closure); ++ ++ if (rc->data != NULL) ++ memcpy(rc->data, u->response.data, rc->length); ++ ++ errcode = juju_to_raw1394_errcode(u->response.rcode); ++ ++ 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]; @@ -790,8 +1124,9 @@ Index: juju/raw1394.c + 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.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; @@ -800,123 +1135,10 @@ Index: juju/raw1394.c + return 0; +} + -+static int -+handle_lost_device(raw1394handle_t handle, int i) -+{ -+ int phy_id; -+ -+ /* The device got unplugged, get rid of it. The fd is -+ * automatically dropped from the epoll context when we close it. */ -+ -+ close(handle->devices[i].fd); -+ phy_id = handle->devices[i].node_id & 0x3f; -+ if (handle->nodes[phy_id] == i) -+ handle->nodes[phy_id] = -1; -+ handle->devices[i].node_id = -1; -+ -+ return 0; -+} -+ -+struct address_closure { -+ int (*callback)(raw1394handle_t handle, struct address_closure *ac, -+ struct fw_cdev_event_request *request, int i); -+}; -+ -+static int -+handle_fcp_request(raw1394handle_t handle, struct address_closure *ac, -+ struct fw_cdev_event_request *request, int i) -+{ -+ struct fw_cdev_send_response response; -+ int is_response; -+ -+ response.serial = request->serial; -+ response.rcode = RCODE_COMPLETE; -+ response.length = 0; -+ response.data = 0; -+ -+ if (handle->fcp_handler == NULL) -+ response.rcode = RCODE_ADDRESS_ERROR; -+ -+ if (request->tcode >= TCODE_WRITE_RESPONSE) -+ response.rcode = RCODE_CONFLICT_ERROR; -+ -+ if (ioctl(handle->devices[i].fd, -+ FW_CDEV_IOC_SEND_RESPONSE, &response) < 0) -+ return -1; -+ -+ if (response.rcode != RCODE_COMPLETE) -+ return 0; -+ -+ is_response = request->offset >= CSR_REGISTER_BASE + CSR_FCP_RESPONSE; -+ -+ 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) -+{ -+ 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 address_closure *ac; -+ struct closure *closure; -+ raw1394_errcode_t errcode; -+ int fd, last, len, phy_id; -+ -+ len = read(handle->devices[i].fd, -+ handle->buffer, sizeof handle->buffer); -+ if (len < 0) -+ return -1; -+ -+ u = (void *) handle->buffer; -+ switch (u->response.type) { -+ case FW_CDEV_EVENT_BUS_RESET: -+ /* Clear old entry, unless it's been overwritten. */ -+ phy_id = handle->devices[i].node_id & 0x3f; -+ if (handle->nodes[phy_id] == i) -+ handle->nodes[phy_id] = -1; -+ handle->nodes[u->bus_reset.node_id & 0x3f] = i; -+ handle->devices[i].node_id = u->bus_reset.node_id; -+ handle->devices[i].generation = u->bus_reset.generation; -+ -+ if (u->bus_reset.node_id != u->bus_reset.local_node_id) -+ return 0; -+ -+ memcpy(&handle->reset, &u->bus_reset, sizeof handle->reset); -+ return handle->bus_reset_handler(handle, -+ u->bus_reset.generation); -+ -+ case FW_CDEV_EVENT_RESPONSE: -+ closure = u64_to_ptr(u->response.closure); -+ -+ if (closure->data != NULL) -+ memcpy(closure->data, -+ u->response.data, closure->length); -+ -+ errcode = juju_to_raw1394_errcode(u->response.rcode); -+ -+ return handle->tag_handler(handle, closure->tag, errcode); -+ -+ case FW_CDEV_EVENT_REQUEST: -+ ac = u64_to_ptr(u->request.closure); -+ return ac->callback(handle, ac, &u->request, i); -+ -+ case FW_CDEV_EVENT_ISO_INTERRUPT: -+ 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; +}