emulate legacy ISO reception API on top of new rawiso API
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@99 53a565d1-3bb7-0310-b661-cf11e63c67ab
This commit is contained in:
parent
385413d23e
commit
5bb327dc90
|
@ -11,8 +11,9 @@ libraw1394_la_SOURCES = \
|
|||
errors.c \
|
||||
readwrite.c \
|
||||
iso.c \
|
||||
iso-legacy.c \
|
||||
fcp.c \
|
||||
arm.c \
|
||||
arm.c \
|
||||
version.c \
|
||||
kernel-raw1394.h \
|
||||
raw1394_private.h
|
||||
|
|
|
@ -65,17 +65,8 @@ int raw1394_loop_iterate(struct raw1394_handle *handle)
|
|||
break;
|
||||
|
||||
case RAW1394_REQ_ISO_RECEIVE:
|
||||
channel = (handle->buffer[0] >> 8) & 0x3f;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
handle->buffer[0] = bswap_32(handle->buffer[0]);
|
||||
#endif
|
||||
|
||||
if (handle->iso_handler[channel]) {
|
||||
retval = handle->iso_handler[channel](handle, channel,
|
||||
req->length,
|
||||
handle->buffer);
|
||||
}
|
||||
break;
|
||||
/* obsolete API, not used anymore */
|
||||
break;
|
||||
|
||||
case RAW1394_REQ_FCP_REQUEST:
|
||||
if (handle->fcp_handler) {
|
||||
|
@ -168,39 +159,6 @@ arm_tag_handler_t raw1394_set_arm_tag_handler(struct raw1394_handle *handle,
|
|||
return old;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* raw1394_set_iso_handler - set isochronous packet handler
|
||||
* @new_h: pointer to new handler
|
||||
*
|
||||
* Sets the handler to be called when an isochronous packet is received to
|
||||
* @new_h and returns the old handler. The default handler does nothing.
|
||||
*
|
||||
* In order to actually get iso packet events, receiving on a specific channel
|
||||
* first has to be enabled with raw1394_start_iso_rcv() and can be stopped again
|
||||
* with raw1394_stop_iso_rcv().
|
||||
**/
|
||||
iso_handler_t raw1394_set_iso_handler(struct raw1394_handle *handle,
|
||||
unsigned int channel, iso_handler_t new)
|
||||
{
|
||||
if (channel >= 64) {
|
||||
return (iso_handler_t)-1;
|
||||
}
|
||||
|
||||
if (new == NULL) {
|
||||
iso_handler_t old = handle->iso_handler[channel];
|
||||
handle->iso_handler[channel] = NULL;
|
||||
return old;
|
||||
}
|
||||
|
||||
if (handle->iso_handler[channel] != NULL) {
|
||||
return (iso_handler_t)-1;
|
||||
}
|
||||
|
||||
handle->iso_handler[channel] = new;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* raw1394_set_fcp_handler - set FCP handler
|
||||
* @new_h: pointer to new handler
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
|
||||
*
|
||||
* Copyright (C) 1999,2000,2001,2002 Andreas Bombe
|
||||
* new ISO API by Dan Maas
|
||||
*
|
||||
* This library is licensed under the GNU Lesser General Public License (LGPL),
|
||||
* version 2.1 or later. See the file COPYING.LIB in the distribution for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#include "raw1394.h"
|
||||
#include "kernel-raw1394.h"
|
||||
#include "raw1394_private.h"
|
||||
|
||||
/* legacy ISO API - emulated for backwards compatibility
|
||||
*
|
||||
* (this code emulates the behavior of the old API using
|
||||
* the new "rawiso" API)
|
||||
*/
|
||||
|
||||
static enum raw1394_iso_disposition legacy_iso_handler(raw1394handle_t handle,
|
||||
unsigned char *data,
|
||||
unsigned int len,
|
||||
unsigned char channel,
|
||||
unsigned char tag,
|
||||
unsigned char sy,
|
||||
unsigned int cycle,
|
||||
unsigned int dropped);
|
||||
|
||||
/**
|
||||
* raw1394_set_iso_handler - set isochronous packet handler
|
||||
* @new_h: pointer to new handler
|
||||
*
|
||||
* Sets the handler to be called when an isochronous packet is received to
|
||||
* @new_h and returns the old handler. The default handler does nothing.
|
||||
*
|
||||
* In order to actually get iso packet events, receiving on a specific channel
|
||||
* first has to be enabled with raw1394_start_iso_rcv() and can be stopped again
|
||||
* with raw1394_stop_iso_rcv().
|
||||
**/
|
||||
iso_handler_t raw1394_set_iso_handler(struct raw1394_handle *handle,
|
||||
unsigned int channel, iso_handler_t new)
|
||||
{
|
||||
if (channel >= 64)
|
||||
goto err;
|
||||
|
||||
/* is this channel already being used? */
|
||||
if (handle->iso_handler[channel] != NULL)
|
||||
goto err;
|
||||
|
||||
/* start up the recv context, if necessary */
|
||||
if (!handle->legacy_iso_active) {
|
||||
/* hmm, is there a good average value for max_packet_size? */
|
||||
if (raw1394_iso_multichannel_recv_init(handle,
|
||||
legacy_iso_handler,
|
||||
1024,
|
||||
500,
|
||||
-1))
|
||||
goto err;
|
||||
|
||||
if (raw1394_iso_recv_start(handle, -1)) {
|
||||
raw1394_iso_shutdown(handle);
|
||||
goto err;
|
||||
}
|
||||
|
||||
handle->legacy_iso_active = 1;
|
||||
}
|
||||
|
||||
if (new == NULL) {
|
||||
iso_handler_t old = handle->iso_handler[channel];
|
||||
handle->iso_handler[channel] = NULL;
|
||||
return old;
|
||||
} else {
|
||||
handle->iso_handler[channel] = new;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err:
|
||||
return (iso_handler_t)-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* raw1394_start_iso_rcv - enable isochronous receiving
|
||||
* @channel: channel number to start receiving on
|
||||
*
|
||||
* Enables the reception of isochronous packets in @channel on @handle.
|
||||
* Isochronous packets are then passed to the callback specified with
|
||||
* raw1394_set_iso_handler().
|
||||
**/
|
||||
int raw1394_start_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||
{
|
||||
if (!handle->legacy_iso_active || channel > 63) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return raw1394_iso_recv_listen_channel(handle, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* raw1394_stop_iso_rcv - stop isochronous receiving
|
||||
* @channel: channel to stop receiving on
|
||||
*
|
||||
* Stops the reception of isochronous packets in @channel on @handle.
|
||||
**/
|
||||
int raw1394_stop_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||
{
|
||||
if (!handle->legacy_iso_active || channel > 63) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return raw1394_iso_recv_unlisten_channel(handle, channel);
|
||||
}
|
||||
|
||||
static enum raw1394_iso_disposition legacy_iso_handler(raw1394handle_t handle,
|
||||
unsigned char *data,
|
||||
unsigned int len,
|
||||
unsigned char channel,
|
||||
unsigned char tag,
|
||||
unsigned char sy,
|
||||
unsigned int cycle,
|
||||
unsigned int dropped)
|
||||
{
|
||||
size_t length;
|
||||
quadlet_t *buf;
|
||||
|
||||
if (!handle->iso_handler[channel])
|
||||
return RAW1394_ISO_OK;
|
||||
|
||||
length = len;
|
||||
buf = (quadlet_t*) data;
|
||||
|
||||
/* back up one quadlet to get the ISO header */
|
||||
/* (note: we assume the card is keeping ISO headers!) */
|
||||
buf -= 1;
|
||||
length += 4;
|
||||
|
||||
/* pad length to quadlet boundary */
|
||||
if (length % 4)
|
||||
length += 4 - (length%4);
|
||||
|
||||
/* make the ISO header big-endian, regardless of host byte order */
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
buf[0] = bswap_32(buf[0]);
|
||||
#endif
|
||||
|
||||
if (handle->iso_handler[channel](handle, channel, length, buf))
|
||||
return RAW1394_ISO_ERROR;
|
||||
|
||||
return RAW1394_ISO_OK;
|
||||
}
|
83
src/iso.c
83
src/iso.c
|
@ -12,91 +12,15 @@
|
|||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <byteswap.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "raw1394.h"
|
||||
#include "kernel-raw1394.h"
|
||||
#include "raw1394_private.h"
|
||||
|
||||
/* old ISO API - kept for backwards compatibility */
|
||||
|
||||
static int do_iso_listen(struct raw1394_handle *handle, int channel)
|
||||
{
|
||||
struct sync_cb_data sd = { 0, 0 };
|
||||
struct raw1394_reqhandle rh = { (req_callback_t)_raw1394_sync_cb, &sd };
|
||||
int err;
|
||||
struct raw1394_request *req = &handle->req;
|
||||
|
||||
CLEAR_REQ(req);
|
||||
req->type = RAW1394_REQ_ISO_LISTEN;
|
||||
req->generation = handle->generation;
|
||||
req->misc = channel;
|
||||
req->tag = ptr2int(&rh);
|
||||
req->recvb = ptr2int(handle->buffer);
|
||||
req->length = HBUF_SIZE;
|
||||
|
||||
err = write(handle->fd, req, sizeof(*req));
|
||||
while (!sd.done) {
|
||||
if (err < 0) return err;
|
||||
err = raw1394_loop_iterate(handle);
|
||||
}
|
||||
|
||||
switch (sd.errcode) {
|
||||
case RAW1394_ERROR_ALREADY:
|
||||
errno = EALREADY;
|
||||
return -1;
|
||||
|
||||
case RAW1394_ERROR_INVALID_ARG:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
||||
default:
|
||||
errno = 0;
|
||||
return sd.errcode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* raw1394_start_iso_rcv - enable isochronous receiving
|
||||
* @channel: channel number to start receiving on
|
||||
*
|
||||
* Enables the reception of isochronous packets in @channel on @handle.
|
||||
* Isochronous packets are then passed to the callback specified with
|
||||
* raw1394_set_iso_handler().
|
||||
**/
|
||||
int raw1394_start_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||
{
|
||||
if (channel > 63) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return do_iso_listen(handle, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* raw1394_stop_iso_rcv - stop isochronous receiving
|
||||
* @channel: channel to stop receiving on
|
||||
*
|
||||
* Stops the reception of isochronous packets in @channel on @handle.
|
||||
**/
|
||||
int raw1394_stop_iso_rcv(struct raw1394_handle *handle, unsigned int channel)
|
||||
{
|
||||
if (channel > 63) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return do_iso_listen(handle, ~channel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* new ISO API */
|
||||
|
||||
|
||||
/* reset the dropped counter each time it is seen */
|
||||
static unsigned int _raw1394_iso_dropped(raw1394handle_t handle)
|
||||
{
|
||||
|
@ -105,7 +29,6 @@ static unsigned int _raw1394_iso_dropped(raw1394handle_t handle)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* common code for iso_xmit_init and iso_recv_init */
|
||||
static int do_iso_init(raw1394handle_t handle,
|
||||
unsigned int buf_packets,
|
||||
|
|
|
@ -148,8 +148,9 @@ struct raw1394_handle *raw1394_new_handle(void)
|
|||
handle->bus_reset_handler = bus_reset_default;
|
||||
handle->tag_handler = tag_handler_default;
|
||||
handle->arm_tag_handler = arm_tag_handler_default;
|
||||
memset(handle->iso_handler, 0, sizeof(handle->iso_handler));
|
||||
handle->iso_buffer = NULL;
|
||||
handle->legacy_iso_active = 0;
|
||||
memset(handle->iso_handler, 0, sizeof(handle->iso_handler));
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#ifndef _RAW1394_PRIVATE_H
|
||||
#define _RAW1394_PRIVATE_H
|
||||
|
||||
|
@ -21,8 +20,7 @@ struct raw1394_handle {
|
|||
tag_handler_t tag_handler;
|
||||
arm_tag_handler_t arm_tag_handler;
|
||||
fcp_handler_t fcp_handler;
|
||||
iso_handler_t iso_handler[64];
|
||||
|
||||
|
||||
/* new ISO API */
|
||||
|
||||
/* memory mapping of the DMA buffer */
|
||||
|
@ -30,7 +28,7 @@ struct raw1394_handle {
|
|||
|
||||
/* iso XMIT only: */
|
||||
unsigned int iso_buf_stride; /* offset between successive packets */
|
||||
unsigned int next_packet; /* index of next packet to be transmitted */
|
||||
unsigned int next_packet; /* buffer index of next packet to be transmitted */
|
||||
|
||||
/* status buffer, updated from _raw1394_iso_iterate() */
|
||||
struct raw1394_iso_status iso_status;
|
||||
|
@ -40,6 +38,10 @@ struct raw1394_handle {
|
|||
raw1394_iso_xmit_handler_t iso_xmit_handler;
|
||||
raw1394_iso_recv_handler_t iso_recv_handler;
|
||||
|
||||
/* legacy ISO API emulation */
|
||||
int legacy_iso_active; /* 1 if we are in legacy emulation mode */
|
||||
iso_handler_t iso_handler[64];
|
||||
|
||||
struct raw1394_request req;
|
||||
quadlet_t buffer[HBUF_SIZE/4]; /* 2048 */
|
||||
};
|
||||
|
|
|
@ -110,7 +110,7 @@ int raw1394_start_write(struct raw1394_handle *handle, nodeid_t node,
|
|||
|
||||
|
||||
/**
|
||||
* raw1394_start_read - initiate a lock transaction
|
||||
* raw1394_start_lock - initiate a lock transaction
|
||||
* @node: target node
|
||||
* @addr: address to read from
|
||||
* @extcode: extended transaction code determining the lock operation
|
||||
|
|
Reference in New Issue