From 429167e36a4ebb994c838eaf44b7cfb7571cdf4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 28 Mar 2007 22:55:21 -0400 Subject: [PATCH] Get rawiso receive a little closer to working. --- juju/juju.h | 2 + juju/raw1394-iso.c | 170 +++++++++++++++++++++++++++++++-------------- juju/raw1394.c | 13 ++-- 3 files changed, 127 insertions(+), 58 deletions(-) diff --git a/juju/juju.h b/juju/juju.h index 5299cbf..882a131 100644 --- a/juju/juju.h +++ b/juju/juju.h @@ -98,6 +98,7 @@ struct raw1394_handle { 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; @@ -122,6 +123,7 @@ struct raw1394_handle { int irq_interval; int packet_index; int packet_phase; + int packet_tail; int buf_packets; int max_packet_size; enum raw1394_iso_dma_recv_mode recv_mode; diff --git a/juju/raw1394-iso.c b/juju/raw1394-iso.c index 6427d39..893d36a 100644 --- a/juju/raw1394-iso.c +++ b/juju/raw1394-iso.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -59,12 +60,12 @@ refill_xmit_buffer(raw1394handle_t handle, struct fw_cdev_queue_iso *queue_iso) data += handle->iso.max_packet_size; handle->iso.packet_index++; + handle->iso.packet_phase++; + 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; @@ -84,11 +85,12 @@ flush_xmit_packets(raw1394handle_t handle, int limit) struct fw_cdev_queue_iso queue_iso; int len; + handle->iso.packet_index -= handle->iso.irq_interval; + 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); + len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); if (len < 0) return -1; if (handle->iso.queue_iso.size > 0) @@ -117,10 +119,53 @@ int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, return flush_xmit_packets(handle, handle->iso.buf_packets); } + +static int +queue_recv_packets(raw1394handle_t handle) +{ + int i; + struct fw_cdev_queue_iso queue_iso; + struct fw_cdev_iso_packet *p = handle->iso.packets; + unsigned int len; + unsigned char *data, *buffer; + + buffer = handle->iso.buffer + + handle->iso.packet_index * handle->iso.max_packet_size; + data = buffer; + + for (i = 0; i < handle->iso.irq_interval; i++, p++) { + 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; + + data += handle->iso.max_packet_size; + handle->iso.packet_index++; + handle->iso.packet_phase++; + + if (handle->iso.packet_index == handle->iso.buf_packets) + handle->iso.packet_index = 0; + 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); + + len = ioctl(handle->iso.fd, FW_CDEV_IOC_QUEUE_ISO, &queue_iso); + if (len < 0) + return -1; + + return 0; +} static int -handle_recv_packets(raw1394handle_t handle, - struct fw_cdev_event_iso_interrupt *interrupt) +flush_recv_packets(raw1394handle_t handle, + struct fw_cdev_event_iso_interrupt *interrupt) { enum raw1394_iso_disposition d; quadlet_t header, *p, *end; @@ -131,7 +176,11 @@ handle_recv_packets(raw1394handle_t handle, p = interrupt->header; end = (void *) interrupt->header + interrupt->header_length; cycle = interrupt->cycle; - data = NULL; + dropped = 0; + + /* FIXME: compute real buffer index. */ + data = handle->iso.buffer + + handle->iso.packet_tail * handle->iso.max_packet_size; while (p < end) { header = be32_to_cpu(*p++); @@ -140,11 +189,18 @@ handle_recv_packets(raw1394handle_t handle, tag = header >> 8; sy = header >> 8; + printf("len=%d, channel=%d, tag=%d, sy=%d\n", + len, channel, tag, sy); + d = handle->iso.recv_handler(handle, data, len, channel, tag, sy, cycle, dropped); + + data += handle->iso.max_packet_size; cycle++; } + queue_recv_packets(handle); + return 0; } @@ -153,6 +209,10 @@ int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle, { struct fw_cdev_start_iso start_iso; + while (handle->iso.packet_index + 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; @@ -173,15 +233,14 @@ static int handle_iso_event(raw1394handle_t handle, return -1; interrupt = (struct fw_cdev_event_iso_interrupt *) handle->buffer; - if (interrupt->type != FW_CDEV_EVENT_BUS_RESET) + if (interrupt->type != FW_CDEV_EVENT_ISO_INTERRUPT) return 0; switch (handle->iso.type) { case FW_CDEV_ISO_CONTEXT_TRANSMIT: - handle->iso.packet_index -= handle->iso.irq_interval; return flush_xmit_packets(handle, handle->iso.buf_packets); case FW_CDEV_ISO_CONTEXT_RECEIVE: - return handle_recv_packets(handle, interrupt); + return flush_recv_packets(handle, interrupt); default: /* Doesn't happen. */ return -1; @@ -227,33 +286,41 @@ int raw1394_iso_recv_flush(raw1394handle_t handle) return 0; } -int raw1394_iso_xmit_init(raw1394handle_t handle, - raw1394_iso_xmit_handler_t handler, - unsigned int buf_packets, - unsigned int max_packet_size, - unsigned char channel, - enum raw1394_iso_speed speed, - int irq_interval) +static int +iso_init(raw1394handle_t handle, int type, + raw1394_iso_xmit_handler_t xmit_handler, + raw1394_iso_recv_handler_t recv_handler, + unsigned int buf_packets, + unsigned int max_packet_size, + unsigned char channel, + enum raw1394_iso_speed speed, + int irq_interval) + { struct fw_cdev_create_iso_context create; struct epoll_event ep; - int retval; + int retval, prot; if (handle->iso.fd != -1) { errno = EBUSY; return -1; } - handle->iso.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; - handle->iso.irq_interval = irq_interval; - handle->iso.xmit_handler = handler; + handle->iso.type = type; + if (irq_interval < 0) + handle->iso.irq_interval = 256; + else + handle->iso.irq_interval = irq_interval; + handle->iso.xmit_handler = xmit_handler; + handle->iso.recv_handler = recv_handler; handle->iso.buf_packets = buf_packets; handle->iso.max_packet_size = max_packet_size; handle->iso.packet_index = 0; handle->iso.packet_phase = 0; + handle->iso.packet_tail = 0; handle->iso.queue_iso.size = 0; handle->iso.packets = - malloc(irq_interval * sizeof handle->iso.packets[0]); + malloc(handle->iso.irq_interval * sizeof handle->iso.packets[0]); if (handle->iso.packets == NULL) return -1; @@ -273,9 +340,10 @@ int raw1394_iso_xmit_init(raw1394handle_t handle, return -1; } - create.type = FW_CDEV_ISO_CONTEXT_TRANSMIT; + create.type = type; create.channel = channel; create.speed = speed; + create.header_size = 4; retval = ioctl(handle->iso.fd, FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create); @@ -285,9 +353,18 @@ int raw1394_iso_xmit_init(raw1394handle_t handle, return retval; } + switch (type) { + case FW_CDEV_ISO_CONTEXT_TRANSMIT: + prot = PROT_READ | PROT_WRITE; + break; + case FW_CDEV_ISO_CONTEXT_RECEIVE: + prot = PROT_READ; + break; + } + handle->iso.buffer = mmap(NULL, buf_packets * max_packet_size, - PROT_READ | PROT_WRITE, MAP_SHARED, handle->iso.fd, 0); + prot, MAP_SHARED, handle->iso.fd, 0); if (handle->iso.buffer == MAP_FAILED) { close(handle->iso.fd); @@ -298,6 +375,19 @@ int raw1394_iso_xmit_init(raw1394handle_t handle, 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, @@ -306,35 +396,9 @@ int raw1394_iso_recv_init(raw1394handle_t handle, 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); + 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, diff --git a/juju/raw1394.c b/juju/raw1394.c index 6bfd7e1..fd5756d 100644 --- a/juju/raw1394.c +++ b/juju/raw1394.c @@ -219,7 +219,7 @@ handle_fcp_request(raw1394handle_t handle, struct address_closure *ac, 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; @@ -718,6 +718,7 @@ struct request_response_block { struct allocation { struct address_closure closure; struct allocation *next; + __u32 handle; byte_t *buffer; octlet_t tag; arm_options_t access_rights; @@ -740,7 +741,7 @@ handle_arm_request(raw1394handle_t handle, struct address_closure *ac, int offset; offset = request->offset - allocation->offset; - response.serial = request->serial; + response.handle = request->handle; switch (request->tcode) { case TCODE_WRITE_QUADLET_REQUEST: @@ -867,6 +868,7 @@ raw1394_arm_register(raw1394handle_t handle, nodeaddr_t start, return -1; } + allocation->handle = request.handle; allocation->next = handle->allocations; handle->allocations = allocation; @@ -903,10 +905,9 @@ raw1394_arm_unregister(raw1394handle_t handle, nodeaddr_t start) return -1; } + request.handle = allocation->handle; free(allocation); - request.offset = start; - return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request); } @@ -1290,6 +1291,8 @@ raw1394_start_fcp_listen(raw1394handle_t handle) if (ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0) return -1; + handle->fcp_allocation_handle = request.handle; + return 0; } @@ -1298,7 +1301,7 @@ raw1394_stop_fcp_listen(raw1394handle_t handle) { 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); }