update iso API for multi-channel reception and new packet buffer layout
git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@98 53a565d1-3bb7-0310-b661-cf11e63c67ab
This commit is contained in:
parent
1dd7ffd1c8
commit
385413d23e
257
src/iso.c
257
src/iso.c
|
@ -113,34 +113,41 @@ static int do_iso_init(raw1394handle_t handle,
|
||||||
int channel,
|
int channel,
|
||||||
enum raw1394_iso_speed speed,
|
enum raw1394_iso_speed speed,
|
||||||
int irq_interval,
|
int irq_interval,
|
||||||
int xmit)
|
int cmd)
|
||||||
{
|
{
|
||||||
size_t pgsize;
|
unsigned int bufsize, stride;
|
||||||
|
|
||||||
/* already initialized? */
|
/* already initialized? */
|
||||||
if(handle->iso_buffer)
|
if(handle->iso_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* choose a power-of-two stride for the packet data buffer,
|
||||||
|
so that an even number of packets fits on one page */
|
||||||
|
for(stride = 4; stride < max_packet_size; stride *= 2);
|
||||||
|
|
||||||
|
if(stride > getpagesize()) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->iso_buf_stride = stride;
|
||||||
|
|
||||||
|
handle->iso_status.config.data_buf_size = stride * buf_packets;
|
||||||
handle->iso_status.config.buf_packets = buf_packets;
|
handle->iso_status.config.buf_packets = buf_packets;
|
||||||
handle->iso_status.config.max_packet_size = max_packet_size;
|
|
||||||
handle->iso_status.config.channel = channel;
|
handle->iso_status.config.channel = channel;
|
||||||
handle->iso_status.config.speed = speed;
|
handle->iso_status.config.speed = speed;
|
||||||
handle->iso_status.config.irq_interval = irq_interval;
|
handle->iso_status.config.irq_interval = irq_interval;
|
||||||
|
|
||||||
if(ioctl(handle->fd, xmit ? RAW1394_ISO_XMIT_INIT : RAW1394_ISO_RECV_INIT, &handle->iso_status))
|
if(ioctl(handle->fd, cmd, &handle->iso_status))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
handle->iso_buffer_bytes = handle->iso_status.config.buf_packets * handle->iso_status.buf_stride;
|
|
||||||
|
|
||||||
/* make sure buffer is a multiple of the page size (for mmap) */
|
|
||||||
pgsize = getpagesize();
|
|
||||||
if(handle->iso_buffer_bytes % pgsize)
|
|
||||||
handle->iso_buffer_bytes += pgsize - (handle->iso_buffer_bytes % pgsize);
|
|
||||||
|
|
||||||
/* mmap the DMA buffer */
|
/* mmap the DMA buffer */
|
||||||
handle->iso_buffer = mmap(NULL, handle->iso_buffer_bytes, PROT_READ | PROT_WRITE,
|
/* (we assume the kernel sets buf_size to an even number of pages) */
|
||||||
|
handle->iso_buffer = mmap(NULL,
|
||||||
|
handle->iso_status.config.data_buf_size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, handle->fd, 0);
|
MAP_SHARED, handle->fd, 0);
|
||||||
|
|
||||||
if(handle->iso_buffer == (unsigned char*) MAP_FAILED) {
|
if(handle->iso_buffer == (unsigned char*) MAP_FAILED) {
|
||||||
handle->iso_buffer = NULL;
|
handle->iso_buffer = NULL;
|
||||||
ioctl(handle->fd, RAW1394_ISO_SHUTDOWN, 0);
|
ioctl(handle->fd, RAW1394_ISO_SHUTDOWN, 0);
|
||||||
|
@ -149,10 +156,10 @@ static int do_iso_init(raw1394handle_t handle,
|
||||||
|
|
||||||
handle->iso_status.overflows = 0;
|
handle->iso_status.overflows = 0;
|
||||||
handle->iso_packets_dropped = 0;
|
handle->iso_packets_dropped = 0;
|
||||||
|
|
||||||
handle->iso_xmit_handler = NULL;
|
handle->iso_xmit_handler = NULL;
|
||||||
handle->iso_recv_handler = NULL;
|
handle->iso_recv_handler = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,14 +178,17 @@ int raw1394_iso_xmit_init(raw1394handle_t handle,
|
||||||
raw1394_iso_xmit_handler_t handler,
|
raw1394_iso_xmit_handler_t handler,
|
||||||
unsigned int buf_packets,
|
unsigned int buf_packets,
|
||||||
unsigned int max_packet_size,
|
unsigned int max_packet_size,
|
||||||
int channel,
|
unsigned char channel,
|
||||||
enum raw1394_iso_speed speed,
|
enum raw1394_iso_speed speed,
|
||||||
int irq_interval)
|
int irq_interval)
|
||||||
{
|
{
|
||||||
if(do_iso_init(handle, buf_packets, max_packet_size, channel, speed, irq_interval, 1))
|
if(do_iso_init(handle, buf_packets, max_packet_size, channel, speed,
|
||||||
|
irq_interval, RAW1394_ISO_XMIT_INIT))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
handle->iso_xmit_handler = handler;
|
handle->iso_xmit_handler = handler;
|
||||||
|
handle->next_packet = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,17 +207,86 @@ int raw1394_iso_recv_init(raw1394handle_t handle,
|
||||||
raw1394_iso_recv_handler_t handler,
|
raw1394_iso_recv_handler_t handler,
|
||||||
unsigned int buf_packets,
|
unsigned int buf_packets,
|
||||||
unsigned int max_packet_size,
|
unsigned int max_packet_size,
|
||||||
int channel,
|
unsigned char channel,
|
||||||
int irq_interval)
|
int irq_interval)
|
||||||
{
|
{
|
||||||
/* any speed will work */
|
/* any speed will work */
|
||||||
if(do_iso_init(handle, buf_packets, max_packet_size, channel, RAW1394_ISO_SPEED_100, irq_interval, 0))
|
if(do_iso_init(handle, buf_packets, max_packet_size, channel, RAW1394_ISO_SPEED_100,
|
||||||
|
irq_interval, RAW1394_ISO_RECV_INIT))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
handle->iso_recv_handler = handler;
|
handle->iso_recv_handler = handler;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw1394_iso_multichannel_recv_init - initialize multi-channel isochronous reception
|
||||||
|
* @handler: handler function for receiving packets
|
||||||
|
* @buf_packets: number of isochronous packets to buffer
|
||||||
|
* @max_packet_size: largest packet you need to handle, in bytes (not including the isochronous header)
|
||||||
|
* @speed: speed at which to receive
|
||||||
|
* @irq_interval: maximum latency of wake-ups, in packets (-1 if you don't care)
|
||||||
|
*
|
||||||
|
* Allocates all user and kernel resources necessary for isochronous reception.
|
||||||
|
**/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* any speed will work */
|
||||||
|
if(do_iso_init(handle, buf_packets, max_packet_size, -1, RAW1394_ISO_SPEED_100,
|
||||||
|
irq_interval, RAW1394_ISO_RECV_INIT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
handle->iso_recv_handler = handler;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw1394_iso_recv_listen_channel - listen to a specific channel in multi-channel mode
|
||||||
|
**/
|
||||||
|
int raw1394_iso_recv_listen_channel(raw1394handle_t handle, unsigned char channel)
|
||||||
|
{
|
||||||
|
if(!handle->iso_buffer)
|
||||||
|
return -1;
|
||||||
|
if(!handle->iso_recv_handler)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ioctl(handle->fd, RAW1394_ISO_RECV_LISTEN_CHANNEL, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw1394_iso_recv_unlisten_channel - stop listening to a specific channel in multi-channel mode
|
||||||
|
**/
|
||||||
|
int raw1394_iso_recv_unlisten_channel(raw1394handle_t handle, unsigned char channel)
|
||||||
|
{
|
||||||
|
if(!handle->iso_buffer)
|
||||||
|
return -1;
|
||||||
|
if(!handle->iso_recv_handler)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ioctl(handle->fd, RAW1394_ISO_RECV_UNLISTEN_CHANNEL, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* raw1394_iso_recv_set_channel_mask - listen or unlisten to a whole bunch of channels at once
|
||||||
|
* @mask: 64-bit mask of channels, 1 means listen, 0 means unlisten,
|
||||||
|
* channel 0 is LSB, channel 63 is MSB
|
||||||
|
*
|
||||||
|
* for multi-channel reception mode only
|
||||||
|
**/
|
||||||
|
int raw1394_iso_recv_set_channel_mask(raw1394handle_t handle, u_int64_t mask)
|
||||||
|
{
|
||||||
|
if(!handle->iso_buffer)
|
||||||
|
return -1;
|
||||||
|
if(!handle->iso_recv_handler)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ioctl(handle->fd, RAW1394_ISO_RECV_SET_CHANNEL_MASK, (void*) &mask);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* raw1394_iso_recv_start - begin isochronous reception
|
* raw1394_iso_recv_start - begin isochronous reception
|
||||||
* @start_on_cycle: isochronous cycle number on which to start (-1 if you don't care)
|
* @start_on_cycle: isochronous cycle number on which to start (-1 if you don't care)
|
||||||
|
@ -218,7 +297,7 @@ int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle)
|
||||||
return -1;
|
return -1;
|
||||||
if(!handle->iso_recv_handler)
|
if(!handle->iso_recv_handler)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_RECV_START, start_on_cycle))
|
if(ioctl(handle->fd, RAW1394_ISO_RECV_START, start_on_cycle))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -229,67 +308,66 @@ int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle)
|
||||||
static int _raw1394_iso_xmit_queue_packets(raw1394handle_t handle)
|
static int _raw1394_iso_xmit_queue_packets(raw1394handle_t handle)
|
||||||
{
|
{
|
||||||
struct raw1394_iso_status *stat = &handle->iso_status;
|
struct raw1394_iso_status *stat = &handle->iso_status;
|
||||||
int retval = 0, packets_done = 0;
|
struct raw1394_iso_packets packets;
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
if(!handle->iso_buffer)
|
if(!handle->iso_buffer)
|
||||||
return -1;
|
goto out;
|
||||||
|
|
||||||
if(!handle->iso_xmit_handler)
|
if(!handle->iso_xmit_handler)
|
||||||
return -1;
|
goto out;
|
||||||
|
|
||||||
|
/* we could potentially send up to stat->n_packets packets */
|
||||||
|
packets.n_packets = 0;
|
||||||
|
packets.infos = malloc(stat->n_packets * sizeof(struct raw1394_iso_packet_info));
|
||||||
|
if(packets.infos == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
while(stat->n_packets > 0) {
|
while(stat->n_packets > 0) {
|
||||||
enum raw1394_iso_disposition disp;
|
enum raw1394_iso_disposition disp;
|
||||||
unsigned char *packet_data;
|
|
||||||
struct raw1394_iso_packet_info *info;
|
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned char tag, sy;
|
|
||||||
|
|
||||||
packet_data = handle->iso_buffer + stat->first_packet * stat->buf_stride
|
struct raw1394_iso_packet_info *info = &packets.infos[packets.n_packets];
|
||||||
+ stat->packet_data_offset;
|
|
||||||
|
info->offset = handle->iso_buf_stride * handle->next_packet;
|
||||||
info = (struct raw1394_iso_packet_info*) (handle->iso_buffer
|
|
||||||
+ stat->first_packet * stat->buf_stride
|
|
||||||
+ stat->packet_info_offset);
|
|
||||||
|
|
||||||
/* call handler */
|
/* call handler */
|
||||||
disp = handle->iso_xmit_handler(handle,
|
disp = handle->iso_xmit_handler(handle,
|
||||||
packet_data,
|
handle->iso_buffer + info->offset,
|
||||||
&len, &tag, &sy,
|
&len,
|
||||||
info->cycle,
|
&info->tag, &info->sy,
|
||||||
|
stat->xmit_cycle,
|
||||||
_raw1394_iso_dropped(handle));
|
_raw1394_iso_dropped(handle));
|
||||||
|
|
||||||
/* check if packet is too long */
|
|
||||||
if(len > stat->config.max_packet_size) {
|
|
||||||
retval = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set packet metadata */
|
|
||||||
info->len = len;
|
info->len = len;
|
||||||
info->tag = tag;
|
|
||||||
info->sy = sy;
|
|
||||||
|
|
||||||
/* advance packet cursors and cycle counter */
|
/* advance packet cursors and cycle counter */
|
||||||
stat->n_packets--;
|
stat->n_packets--;
|
||||||
stat->first_packet = (stat->first_packet + 1) % stat->config.buf_packets;
|
handle->next_packet = (handle->next_packet + 1) % stat->config.buf_packets;
|
||||||
packets_done++;
|
if(stat->xmit_cycle != -1)
|
||||||
|
stat->xmit_cycle = (stat->xmit_cycle + 1) % 8000;
|
||||||
|
packets.n_packets++;
|
||||||
|
|
||||||
if(disp == RAW1394_ISO_DEFER) {
|
if(disp == RAW1394_ISO_DEFER) {
|
||||||
/* queue an event so that we don't hang in the next read() */
|
/* queue an event so that we don't hang in the next read() */
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_QUEUE_ACTIVITY, 0))
|
if(ioctl(handle->fd, RAW1394_ISO_QUEUE_ACTIVITY, 0))
|
||||||
return -1;
|
goto out_produce;
|
||||||
break;
|
break;
|
||||||
} else if(disp == RAW1394_ISO_ERROR) {
|
} else if(disp == RAW1394_ISO_ERROR) {
|
||||||
retval = -1;
|
goto out_produce;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(packets_done > 0) {
|
/* success */
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_PRODUCE_CONSUME, packets_done))
|
retval = 0;
|
||||||
return -1;
|
|
||||||
|
out_produce:
|
||||||
|
if(packets.n_packets > 0) {
|
||||||
|
if(ioctl(handle->fd, RAW1394_ISO_XMIT_PACKETS, &packets))
|
||||||
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
out_free:
|
||||||
|
free(packets.infos);
|
||||||
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +380,7 @@ static int _raw1394_iso_xmit_queue_packets(raw1394handle_t handle)
|
||||||
int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, int prebuffer_packets)
|
int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, int prebuffer_packets)
|
||||||
{
|
{
|
||||||
int args[2];
|
int args[2];
|
||||||
|
|
||||||
if(!handle->iso_buffer)
|
if(!handle->iso_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
if(!handle->iso_xmit_handler)
|
if(!handle->iso_xmit_handler)
|
||||||
|
@ -310,10 +388,10 @@ int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, int prebu
|
||||||
|
|
||||||
args[0] = start_on_cycle;
|
args[0] = start_on_cycle;
|
||||||
args[1] = prebuffer_packets;
|
args[1] = prebuffer_packets;
|
||||||
|
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_XMIT_START, &args[0]))
|
if(ioctl(handle->fd, RAW1394_ISO_XMIT_START, &args[0]))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +402,7 @@ void raw1394_iso_stop(raw1394handle_t handle)
|
||||||
{
|
{
|
||||||
if(!handle->iso_buffer)
|
if(!handle->iso_buffer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ioctl(handle->fd, RAW1394_ISO_STOP, 0);
|
ioctl(handle->fd, RAW1394_ISO_STOP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +413,7 @@ void raw1394_iso_shutdown(raw1394handle_t handle)
|
||||||
{
|
{
|
||||||
if(handle->iso_buffer) {
|
if(handle->iso_buffer) {
|
||||||
raw1394_iso_stop(handle);
|
raw1394_iso_stop(handle);
|
||||||
munmap(handle->iso_buffer, handle->iso_buffer_bytes);
|
munmap(handle->iso_buffer, handle->iso_status.config.data_buf_size);
|
||||||
ioctl(handle->fd, RAW1394_ISO_SHUTDOWN, 0);
|
ioctl(handle->fd, RAW1394_ISO_SHUTDOWN, 0);
|
||||||
handle->iso_buffer = NULL;
|
handle->iso_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
@ -344,31 +422,34 @@ void raw1394_iso_shutdown(raw1394handle_t handle)
|
||||||
static int _raw1394_iso_recv_packets(raw1394handle_t handle)
|
static int _raw1394_iso_recv_packets(raw1394handle_t handle)
|
||||||
{
|
{
|
||||||
struct raw1394_iso_status *stat = &handle->iso_status;
|
struct raw1394_iso_status *stat = &handle->iso_status;
|
||||||
struct raw1394_iso_packet_info *info;
|
struct raw1394_iso_packets packets;
|
||||||
|
|
||||||
|
int retval = -1, packets_done = 0;
|
||||||
|
|
||||||
int retval = 0, packets_done = 0;
|
|
||||||
|
|
||||||
if(!handle->iso_buffer)
|
if(!handle->iso_buffer)
|
||||||
return -1;
|
goto out;
|
||||||
|
|
||||||
if(!handle->iso_recv_handler)
|
if(!handle->iso_recv_handler)
|
||||||
return -1;
|
goto out;
|
||||||
|
|
||||||
|
/* ask the kernel to fill an array with packet info structs */
|
||||||
|
packets.n_packets = stat->n_packets;
|
||||||
|
packets.infos = malloc(packets.n_packets * sizeof(struct raw1394_iso_packet_info));
|
||||||
|
if(packets.infos == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if(ioctl(handle->fd, RAW1394_ISO_RECV_PACKETS, &packets) < 0)
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
while(stat->n_packets > 0) {
|
while(stat->n_packets > 0) {
|
||||||
unsigned char *packet_data;
|
|
||||||
struct raw1394_iso_packet_info *info;
|
struct raw1394_iso_packet_info *info;
|
||||||
enum raw1394_iso_disposition disp;
|
enum raw1394_iso_disposition disp;
|
||||||
|
|
||||||
packet_data = handle->iso_buffer + stat->first_packet * stat->buf_stride
|
|
||||||
+ stat->packet_data_offset;
|
|
||||||
|
|
||||||
info = (struct raw1394_iso_packet_info*) (handle->iso_buffer
|
info = &packets.infos[packets_done];
|
||||||
+ stat->first_packet * stat->buf_stride
|
|
||||||
+ stat->packet_info_offset);
|
|
||||||
|
|
||||||
/* call handler */
|
/* call handler */
|
||||||
disp = handle->iso_recv_handler(handle,
|
disp = handle->iso_recv_handler(handle,
|
||||||
packet_data,
|
handle->iso_buffer + info->offset,
|
||||||
info->len, info->channel,
|
info->len, info->channel,
|
||||||
info->tag, info->sy,
|
info->tag, info->sy,
|
||||||
info->cycle,
|
info->cycle,
|
||||||
|
@ -376,25 +457,29 @@ static int _raw1394_iso_recv_packets(raw1394handle_t handle)
|
||||||
|
|
||||||
/* advance packet cursors */
|
/* advance packet cursors */
|
||||||
stat->n_packets--;
|
stat->n_packets--;
|
||||||
stat->first_packet = (stat->first_packet + 1) % stat->config.buf_packets;
|
|
||||||
packets_done++;
|
packets_done++;
|
||||||
|
|
||||||
if(disp == RAW1394_ISO_DEFER) {
|
if(disp == RAW1394_ISO_DEFER) {
|
||||||
/* queue an event so that we don't hang in the next read() */
|
/* queue an event so that we don't hang in the next read() */
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_QUEUE_ACTIVITY, 0))
|
if(ioctl(handle->fd, RAW1394_ISO_QUEUE_ACTIVITY, 0))
|
||||||
return -1;
|
goto out_consume;
|
||||||
break;
|
break;
|
||||||
} else if(disp == RAW1394_ISO_ERROR) {
|
} else if(disp == RAW1394_ISO_ERROR) {
|
||||||
retval = -1;
|
goto out_consume;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
out_consume:
|
||||||
if(packets_done > 0) {
|
if(packets_done > 0) {
|
||||||
if(ioctl(handle->fd, RAW1394_ISO_PRODUCE_CONSUME, packets_done))
|
if(ioctl(handle->fd, RAW1394_ISO_RECV_RELEASE_PACKETS, packets_done))
|
||||||
return -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
out_free:
|
||||||
|
free(packets.infos);
|
||||||
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +502,7 @@ int _raw1394_iso_iterate(raw1394handle_t handle)
|
||||||
} else if(handle->iso_recv_handler) {
|
} else if(handle->iso_recv_handler) {
|
||||||
return _raw1394_iso_recv_packets(handle);
|
return _raw1394_iso_recv_packets(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,31 +118,53 @@ typedef struct arm_request_response {
|
||||||
/* rawiso API */
|
/* rawiso API */
|
||||||
|
|
||||||
/* ioctls */
|
/* ioctls */
|
||||||
#define RAW1394_ISO_XMIT_INIT 1 /* arg: raw1394_iso_status* */
|
#define RAW1394_ISO_XMIT_INIT 1 /* arg: raw1394_iso_status* */
|
||||||
#define RAW1394_ISO_RECV_INIT 2 /* arg: raw1394_iso_status* */
|
#define RAW1394_ISO_RECV_INIT 2 /* arg: raw1394_iso_status* */
|
||||||
#define RAW1394_ISO_RECV_START 3 /* arg: int, starting cycle */
|
#define RAW1394_ISO_RECV_START 3 /* arg: int, starting cycle */
|
||||||
#define RAW1394_ISO_XMIT_START 8 /* arg: int[2], { starting cycle, prebuffer } */
|
#define RAW1394_ISO_XMIT_START 8 /* arg: int[2], { starting cycle, prebuffer } */
|
||||||
#define RAW1394_ISO_STOP 4
|
#define RAW1394_ISO_STOP 4
|
||||||
#define RAW1394_ISO_GET_STATUS 5 /* arg: raw1394_iso_status* */
|
#define RAW1394_ISO_GET_STATUS 5 /* arg: raw1394_iso_status* */
|
||||||
#define RAW1394_ISO_PRODUCE_CONSUME 6 /* arg: int, # of packets */
|
#define RAW1394_ISO_PRODUCE_CONSUME 6 /* no longer used */
|
||||||
#define RAW1394_ISO_SHUTDOWN 7
|
#define RAW1394_ISO_SHUTDOWN 7
|
||||||
#define RAW1394_ISO_QUEUE_ACTIVITY 9
|
#define RAW1394_ISO_QUEUE_ACTIVITY 9
|
||||||
|
#define RAW1394_ISO_RECV_LISTEN_CHANNEL 10 /* arg: channel number */
|
||||||
|
#define RAW1394_ISO_RECV_UNLISTEN_CHANNEL 11 /* arg: channel number */
|
||||||
|
#define RAW1394_ISO_RECV_SET_CHANNEL_MASK 12 /* arg: pointer to 64-bit mask */
|
||||||
|
#define RAW1394_ISO_RECV_PACKETS 13 /* arg: struct raw1394_iso_packets* */
|
||||||
|
#define RAW1394_ISO_RECV_RELEASE_PACKETS 14 /* arg: int n_packets */
|
||||||
|
#define RAW1394_ISO_XMIT_PACKETS 15 /* arg: struct raw1394_iso_packets* */
|
||||||
|
|
||||||
/* per-packet metadata embedded in the ringbuffer */
|
/* per-packet metadata embedded in the ringbuffer */
|
||||||
/* must be identical to hpsb_iso_packet_info in iso.h! */
|
/* must be identical to hpsb_iso_packet_info in iso.h! */
|
||||||
struct raw1394_iso_packet_info {
|
struct raw1394_iso_packet_info {
|
||||||
|
__u32 offset;
|
||||||
__u16 len;
|
__u16 len;
|
||||||
__u16 cycle;
|
__u16 cycle; /* recv only */
|
||||||
__u8 channel; /* recv only */
|
__u8 channel; /* recv only */
|
||||||
__u8 tag;
|
__u8 tag;
|
||||||
__u8 sy;
|
__u8 sy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* argument for RAW1394_ISO_RECV/XMIT_PACKETS ioctls */
|
||||||
|
struct raw1394_iso_packets {
|
||||||
|
__u32 n_packets;
|
||||||
|
struct raw1394_iso_packet_info *infos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct raw1394_iso_config {
|
struct raw1394_iso_config {
|
||||||
|
/* size of packet data buffer, in bytes (will be rounded up to PAGE_SIZE) */
|
||||||
|
__u32 data_buf_size;
|
||||||
|
|
||||||
|
/* # of packets to buffer */
|
||||||
__u32 buf_packets;
|
__u32 buf_packets;
|
||||||
__u32 max_packet_size;
|
|
||||||
__u32 channel;
|
/* iso channel (set to -1 for multi-channel recv) */
|
||||||
__u32 speed; /* xmit only */
|
__s32 channel;
|
||||||
|
|
||||||
|
/* xmit only - iso transmission speed */
|
||||||
|
__u8 speed;
|
||||||
|
|
||||||
|
/* max. latency of buffer, in packets (-1 if you don't care) */
|
||||||
__s32 irq_interval;
|
__s32 irq_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,19 +172,6 @@ struct raw1394_iso_config {
|
||||||
struct raw1394_iso_status {
|
struct raw1394_iso_status {
|
||||||
/* current settings */
|
/* current settings */
|
||||||
struct raw1394_iso_config config;
|
struct raw1394_iso_config config;
|
||||||
|
|
||||||
/* byte offset between successive packets in the buffer */
|
|
||||||
__s32 buf_stride;
|
|
||||||
|
|
||||||
/* byte offset of data payload within each packet */
|
|
||||||
__s32 packet_data_offset;
|
|
||||||
|
|
||||||
/* byte offset of struct iso_packet_info within each packet */
|
|
||||||
__s32 packet_info_offset;
|
|
||||||
|
|
||||||
/* index of next packet to fill with data (ISO transmission)
|
|
||||||
or next packet containing data recieved (ISO reception) */
|
|
||||||
__u32 first_packet;
|
|
||||||
|
|
||||||
/* number of packets waiting to be filled with data (ISO transmission)
|
/* number of packets waiting to be filled with data (ISO transmission)
|
||||||
or containing data received (ISO reception) */
|
or containing data received (ISO reception) */
|
||||||
|
@ -172,6 +181,10 @@ struct raw1394_iso_status {
|
||||||
underflow of the packet buffer (a value of zero guarantees
|
underflow of the packet buffer (a value of zero guarantees
|
||||||
that no packets have been dropped) */
|
that no packets have been dropped) */
|
||||||
__u32 overflows;
|
__u32 overflows;
|
||||||
|
|
||||||
|
/* cycle number at which next packet will be transmitted;
|
||||||
|
-1 if not known */
|
||||||
|
__s16 xmit_cycle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* IEEE1394_RAW1394_H */
|
#endif /* IEEE1394_RAW1394_H */
|
||||||
|
|
|
@ -55,7 +55,7 @@ enum raw1394_iso_speed {
|
||||||
RAW1394_ISO_SPEED_400 = 2,
|
RAW1394_ISO_SPEED_400 = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* return values from xmit/recv handlers */
|
/* return values from isochronous xmit/recv handlers */
|
||||||
|
|
||||||
enum raw1394_iso_disposition {
|
enum raw1394_iso_disposition {
|
||||||
/* continue on to the next packet */
|
/* continue on to the next packet */
|
||||||
|
@ -72,14 +72,16 @@ enum raw1394_iso_disposition {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* handlers for transmitting/receiving isochronous packets */
|
||||||
|
|
||||||
typedef enum raw1394_iso_disposition (*raw1394_iso_xmit_handler_t)(raw1394handle_t,
|
typedef enum raw1394_iso_disposition (*raw1394_iso_xmit_handler_t)(raw1394handle_t,
|
||||||
unsigned char *data,
|
unsigned char *data,
|
||||||
unsigned int *len,
|
unsigned int *len,
|
||||||
unsigned char *tag,
|
unsigned char *tag,
|
||||||
unsigned char *sy,
|
unsigned char *sy,
|
||||||
unsigned int cycle,
|
int cycle, /* -1 if unknown */
|
||||||
unsigned int dropped);
|
unsigned int dropped);
|
||||||
|
|
||||||
typedef enum raw1394_iso_disposition (*raw1394_iso_recv_handler_t)(raw1394handle_t,
|
typedef enum raw1394_iso_disposition (*raw1394_iso_recv_handler_t)(raw1394handle_t,
|
||||||
unsigned char *data,
|
unsigned char *data,
|
||||||
unsigned int len,
|
unsigned int len,
|
||||||
|
@ -93,7 +95,7 @@ int raw1394_iso_xmit_init(raw1394handle_t handle,
|
||||||
raw1394_iso_xmit_handler_t handler,
|
raw1394_iso_xmit_handler_t handler,
|
||||||
unsigned int buf_packets,
|
unsigned int buf_packets,
|
||||||
unsigned int max_packet_size,
|
unsigned int max_packet_size,
|
||||||
int channel,
|
unsigned char channel,
|
||||||
enum raw1394_iso_speed speed,
|
enum raw1394_iso_speed speed,
|
||||||
int irq_interval);
|
int irq_interval);
|
||||||
|
|
||||||
|
@ -101,13 +103,23 @@ int raw1394_iso_recv_init(raw1394handle_t handle,
|
||||||
raw1394_iso_recv_handler_t handler,
|
raw1394_iso_recv_handler_t handler,
|
||||||
unsigned int buf_packets,
|
unsigned int buf_packets,
|
||||||
unsigned int max_packet_size,
|
unsigned int max_packet_size,
|
||||||
int channel,
|
unsigned char channel,
|
||||||
int irq_interval);
|
int 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);
|
||||||
|
|
||||||
|
/* listen/unlisten on a specific channel (multi-channel mode ONLY) */
|
||||||
|
int raw1394_iso_recv_listen_channel(raw1394handle_t handle, unsigned char channel);
|
||||||
|
int raw1394_iso_recv_unlisten_channel(raw1394handle_t handle, unsigned char channel);
|
||||||
|
int raw1394_iso_recv_set_channel_mask(raw1394handle_t handle, u_int64_t mask);
|
||||||
|
|
||||||
int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, int prebuffer_packets);
|
int raw1394_iso_xmit_start(raw1394handle_t handle, int start_on_cycle, int prebuffer_packets);
|
||||||
int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle);
|
int raw1394_iso_recv_start(raw1394handle_t handle, int start_on_cycle);
|
||||||
|
|
||||||
void raw1394_iso_stop(raw1394handle_t handle);
|
void raw1394_iso_stop(raw1394handle_t handle);
|
||||||
void raw1394_iso_shutdown(raw1394handle_t handle);
|
void raw1394_iso_shutdown(raw1394handle_t handle);
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,11 @@ struct raw1394_handle {
|
||||||
|
|
||||||
/* memory mapping of the DMA buffer */
|
/* memory mapping of the DMA buffer */
|
||||||
unsigned char *iso_buffer;
|
unsigned char *iso_buffer;
|
||||||
unsigned long iso_buffer_bytes;
|
|
||||||
|
/* iso XMIT only: */
|
||||||
|
unsigned int iso_buf_stride; /* offset between successive packets */
|
||||||
|
unsigned int next_packet; /* index of next packet to be transmitted */
|
||||||
|
|
||||||
/* status buffer, updated from _raw1394_iso_iterate() */
|
/* status buffer, updated from _raw1394_iso_iterate() */
|
||||||
struct raw1394_iso_status iso_status;
|
struct raw1394_iso_status iso_status;
|
||||||
unsigned int iso_packets_dropped;
|
unsigned int iso_packets_dropped;
|
||||||
|
@ -36,7 +39,7 @@ struct raw1394_handle {
|
||||||
/* user-supplied handlers */
|
/* user-supplied handlers */
|
||||||
raw1394_iso_xmit_handler_t iso_xmit_handler;
|
raw1394_iso_xmit_handler_t iso_xmit_handler;
|
||||||
raw1394_iso_recv_handler_t iso_recv_handler;
|
raw1394_iso_recv_handler_t iso_recv_handler;
|
||||||
|
|
||||||
struct raw1394_request req;
|
struct raw1394_request req;
|
||||||
quadlet_t buffer[HBUF_SIZE/4]; /* 2048 */
|
quadlet_t buffer[HBUF_SIZE/4]; /* 2048 */
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue