|
Packit |
0bbbb1 |
/*
|
|
Packit |
0bbbb1 |
* libiec61883 - Linux IEEE 1394 streaming media library.
|
|
Packit |
0bbbb1 |
* Copyright (C) 2004 Kristian Hogsberg, Dan Dennedy, and Dan Maas.
|
|
Packit |
0bbbb1 |
* This file written by Dan Dennedy.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* Bits of raw1394 ARM handling borrowed from
|
|
Packit |
0bbbb1 |
* Christian Toegel's <christian.toegel@gmx.at> demos.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
0bbbb1 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
0bbbb1 |
* License as published by the Free Software Foundation; either
|
|
Packit |
0bbbb1 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
0bbbb1 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0bbbb1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0bbbb1 |
* Lesser General Public License for more details.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
0bbbb1 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
0bbbb1 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
0bbbb1 |
#include <config.h>
|
|
Packit |
0bbbb1 |
#endif
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#include "iec61883.h"
|
|
Packit |
0bbbb1 |
#include "iec61883-private.h"
|
|
Packit |
0bbbb1 |
#include "cooked.h"
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#include <sys/types.h>
|
|
Packit |
0bbbb1 |
#include <unistd.h>
|
|
Packit |
0bbbb1 |
#include <string.h>
|
|
Packit |
0bbbb1 |
#include <stdio.h>
|
|
Packit |
0bbbb1 |
#include <stdlib.h>
|
|
Packit |
0bbbb1 |
#include <stdint.h>
|
|
Packit |
0bbbb1 |
#include <errno.h>
|
|
Packit |
0bbbb1 |
#include <netinet/in.h>
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
#include <libraw1394/csr.h>
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/*
|
|
Packit |
0bbbb1 |
* Plug register access functions
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* Please see the convenience macros defined in iec61883.h.
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_get(raw1394handle_t h, nodeid_t n, nodeaddr_t a, quadlet_t *value)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
quadlet_t temp; /* register value */
|
|
Packit |
0bbbb1 |
int result;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
result = iec61883_cooked_read( h, n, CSR_REGISTER_BASE + a, sizeof(quadlet_t), &temp);
|
|
Packit |
0bbbb1 |
if (result >= 0)
|
|
Packit |
0bbbb1 |
*value = ntohl(temp); /* endian conversion */
|
|
Packit |
0bbbb1 |
return result;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_set(raw1394handle_t h, nodeid_t n, nodeaddr_t a, quadlet_t value)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
quadlet_t compare, swap, new;
|
|
Packit |
0bbbb1 |
int result;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* get the current register value for comparison */
|
|
Packit |
0bbbb1 |
result = iec61883_plug_get( h, n, a, &compare );
|
|
Packit |
0bbbb1 |
if (result >= 0)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* convert endian */
|
|
Packit |
0bbbb1 |
compare = htonl(compare);
|
|
Packit |
0bbbb1 |
swap = htonl(value);
|
|
Packit |
0bbbb1 |
result = raw1394_lock( h, n, CSR_REGISTER_BASE + a, EXTCODE_COMPARE_SWAP, swap, compare, &new;;
|
|
Packit |
0bbbb1 |
if (new != compare)
|
|
Packit |
0bbbb1 |
result = -EAGAIN;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
return result;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/*
|
|
Packit |
0bbbb1 |
* Local host plugs implementation
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This requires the address range mapping feature of libraw1394 1.0.
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* ARM context identifiers */
|
|
Packit |
0bbbb1 |
static char g_arm_callback_context_out[] = "libiec61883 output context";
|
|
Packit |
0bbbb1 |
static char g_arm_callback_context_in[] = "libiec61883 input context";
|
|
Packit |
0bbbb1 |
static struct raw1394_arm_reqhandle g_arm_reqhandle_out;
|
|
Packit |
0bbbb1 |
static struct raw1394_arm_reqhandle g_arm_reqhandle_in;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* register space */
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* Please note that this is host global. Each port (host adapter)
|
|
Packit |
0bbbb1 |
does not get its own register space. Also, this is only intended
|
|
Packit |
0bbbb1 |
for use by a single application. It appears that when multiple processes
|
|
Packit |
0bbbb1 |
host these plugs, it still works; as long as the application uses the
|
|
Packit |
0bbbb1 |
plug access functions above, then it should work. */
|
|
Packit |
0bbbb1 |
static struct output_registers {
|
|
Packit |
0bbbb1 |
struct iec61883_oMPR mpr;
|
|
Packit |
0bbbb1 |
struct iec61883_oPCR pcr[IEC61883_PCR_MAX];
|
|
Packit |
0bbbb1 |
} g_data_out;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
static struct input_registers {
|
|
Packit |
0bbbb1 |
struct iec61883_iMPR mpr;
|
|
Packit |
0bbbb1 |
struct iec61883_iPCR pcr[IEC61883_PCR_MAX];
|
|
Packit |
0bbbb1 |
} g_data_in;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/** Send an async packet in response to a register read.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This function handles host to bus endian conversion.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* \param handle A raw1394 handle.
|
|
Packit |
0bbbb1 |
* \param arm_req A pointer to an arm_request struct from the ARM callback
|
|
Packit |
0bbbb1 |
* handler.
|
|
Packit |
0bbbb1 |
* \param a The CSR offset address of the register.
|
|
Packit |
0bbbb1 |
* \param data The base address of the register space to read.
|
|
Packit |
0bbbb1 |
* \return 0 for success, -1 on error.
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
static int
|
|
Packit |
0bbbb1 |
do_arm_read(raw1394handle_t handle, struct raw1394_arm_request *arm_req,
|
|
Packit |
0bbbb1 |
nodeaddr_t a, quadlet_t *data)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
quadlet_t *response;
|
|
Packit |
0bbbb1 |
int num=4, offset;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* allocate response packet */
|
|
Packit |
0bbbb1 |
response = malloc(num * sizeof(quadlet_t));
|
|
Packit |
0bbbb1 |
if (!response)
|
|
Packit |
0bbbb1 |
FAIL("unable to allocate response packet");
|
|
Packit |
0bbbb1 |
memset(response, 0x00, num * sizeof(quadlet_t));
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* fill data of response */
|
|
Packit |
0bbbb1 |
response[0] =
|
|
Packit |
0bbbb1 |
((arm_req->source_nodeid & 0xFFFF) << 16) +
|
|
Packit |
0bbbb1 |
((arm_req->tlabel & 0x3F) << 10) +
|
|
Packit |
0bbbb1 |
(6 << 4); /* tcode = 6 */
|
|
Packit |
0bbbb1 |
response[1] = ((arm_req->destination_nodeid & 0xFFFF) << 16);
|
|
Packit |
0bbbb1 |
/* rcode = resp_complete implied */
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
DEBUG (" destination_offset=%d",
|
|
Packit |
0bbbb1 |
arm_req->destination_offset - CSR_REGISTER_BASE - a);
|
|
Packit |
0bbbb1 |
offset = (arm_req->destination_offset - CSR_REGISTER_BASE - a)/4;
|
|
Packit |
0bbbb1 |
response[3] = htonl(data[offset]);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
DEBUG(" response: 0x%8.8X",response[0]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[1]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[2]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[3]);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* send response */
|
|
Packit |
0bbbb1 |
raw1394_start_async_send(handle, 16 , 16, 0, response, 0);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
free (response);
|
|
Packit |
0bbbb1 |
return 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/** Update a local register value, and send a response packet.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* This function performs a compare/swap lock operation only.
|
|
Packit |
0bbbb1 |
* This function handles host to bus endian conversion.
|
|
Packit |
0bbbb1 |
*
|
|
Packit |
0bbbb1 |
* \param handle A raw1394 handle.
|
|
Packit |
0bbbb1 |
* \param arm_req A pointer to an arm_request struct from the ARM callback
|
|
Packit |
0bbbb1 |
* handler.
|
|
Packit |
0bbbb1 |
* \param a The CSR offset address of the register.
|
|
Packit |
0bbbb1 |
* \param data The base address of the register space to update.
|
|
Packit |
0bbbb1 |
* \return 0 for success, -1 on error.
|
|
Packit |
0bbbb1 |
*/
|
|
Packit |
0bbbb1 |
static int
|
|
Packit |
0bbbb1 |
do_arm_lock(raw1394handle_t handle, struct raw1394_arm_request *arm_req,
|
|
Packit |
0bbbb1 |
nodeaddr_t a, quadlet_t *data)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
quadlet_t *response = NULL;
|
|
Packit |
0bbbb1 |
int num, offset;
|
|
Packit |
0bbbb1 |
int rcode = RCODE_COMPLETE;
|
|
Packit |
0bbbb1 |
int requested_length = 4;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (arm_req->extended_transaction_code == EXTCODE_COMPARE_SWAP)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
quadlet_t arg_q, data_q, old_q, new_q;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* allocate response packet */
|
|
Packit |
0bbbb1 |
num = 4 + requested_length;
|
|
Packit |
0bbbb1 |
response = malloc(num * sizeof(quadlet_t));
|
|
Packit |
0bbbb1 |
if (!response)
|
|
Packit |
0bbbb1 |
FAIL("unable to allocate response packet");
|
|
Packit |
0bbbb1 |
memset(response, 0x00, num * sizeof(quadlet_t));
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* load data */
|
|
Packit |
0bbbb1 |
offset = (arm_req->destination_offset - CSR_REGISTER_BASE - a)/4;
|
|
Packit |
0bbbb1 |
response[4] = htonl(data[offset]);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* compare */
|
|
Packit |
0bbbb1 |
arg_q = *(quadlet_t *) (&arm_req->buffer[0]);
|
|
Packit |
0bbbb1 |
data_q = *(quadlet_t *) (&arm_req->buffer[4]);
|
|
Packit |
0bbbb1 |
old_q = *(quadlet_t *) (&response[4]);
|
|
Packit |
0bbbb1 |
new_q = (old_q == arg_q) ? data_q : old_q;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* swap */
|
|
Packit |
0bbbb1 |
data[offset] = ntohl(new_q);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
rcode = RCODE_TYPE_ERROR;
|
|
Packit |
0bbbb1 |
requested_length = 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* fill data of response */
|
|
Packit |
0bbbb1 |
response[0] =
|
|
Packit |
0bbbb1 |
((arm_req->source_nodeid & 0xFFFF) << 16) +
|
|
Packit |
0bbbb1 |
((arm_req->tlabel & 0x3F) << 10) +
|
|
Packit |
0bbbb1 |
(0xB << 4); /* tcode = B */
|
|
Packit |
0bbbb1 |
response[1] =
|
|
Packit |
0bbbb1 |
((arm_req->destination_nodeid & 0xFFFF) << 16) +
|
|
Packit |
0bbbb1 |
((rcode & 0xF) << 12);
|
|
Packit |
0bbbb1 |
response[3] =
|
|
Packit |
0bbbb1 |
((requested_length & 0xFFFF) << 16) +
|
|
Packit |
0bbbb1 |
(arm_req->extended_transaction_code & 0xFF);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
DEBUG(" response: 0x%8.8X",response[0]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[1]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[2]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[3]);
|
|
Packit |
0bbbb1 |
DEBUG(" 0x%8.8X",response[4]);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* send response */
|
|
Packit |
0bbbb1 |
raw1394_start_async_send(handle, requested_length + 16, 16, 0, response, 0);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
free (response);
|
|
Packit |
0bbbb1 |
return 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* local plug ARM handler */
|
|
Packit |
0bbbb1 |
static int
|
|
Packit |
0bbbb1 |
iec61883_arm_callback (raw1394handle_t handle,
|
|
Packit |
0bbbb1 |
struct raw1394_arm_request_response *arm_req_resp,
|
|
Packit |
0bbbb1 |
unsigned int requested_length,
|
|
Packit |
0bbbb1 |
void *pcontext, byte_t request_type)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
struct raw1394_arm_request *arm_req = arm_req_resp->request;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
DEBUG( "request type=%d tcode=%d length=%d", request_type, arm_req->tcode, requested_length);
|
|
Packit |
0bbbb1 |
DEBUG( "context = %s", (char *) pcontext);
|
|
Packit |
0bbbb1 |
fflush(stdout);
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
if (pcontext == g_arm_callback_context_out && requested_length == 4)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
if (request_type == RAW1394_ARM_READ && arm_req->tcode == 4)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
do_arm_read( handle, arm_req, CSR_O_MPR, (quadlet_t *) &g_data_out );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else if (request_type == RAW1394_ARM_LOCK)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
do_arm_lock( handle, arm_req, CSR_O_MPR, (quadlet_t *) &g_data_out );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* error response */
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else if (pcontext == g_arm_callback_context_in && requested_length == 4)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
if (request_type == RAW1394_ARM_READ)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
do_arm_read( handle, arm_req, CSR_I_MPR, (quadlet_t *) &g_data_in );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else if (request_type == RAW1394_ARM_LOCK)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
do_arm_lock( handle, arm_req, CSR_I_MPR, (quadlet_t *) &g_data_in );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* error response */
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
else
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* error response */
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
fflush(stdout);
|
|
Packit |
0bbbb1 |
return 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_impr_init (raw1394handle_t h, unsigned int data_rate)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* validate parameters */
|
|
Packit |
0bbbb1 |
if (data_rate >> 2 != 0)
|
|
Packit |
0bbbb1 |
errno = -EINVAL;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* initialize data */
|
|
Packit |
0bbbb1 |
memset (&g_data_in, 0, sizeof (g_data_in));
|
|
Packit |
0bbbb1 |
g_data_in.mpr.data_rate = data_rate;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* initialize host environment */
|
|
Packit |
0bbbb1 |
memset (&g_arm_reqhandle_in, 0, sizeof(g_arm_reqhandle_in));
|
|
Packit |
0bbbb1 |
g_arm_reqhandle_in.arm_callback = (arm_req_callback_t) iec61883_arm_callback;
|
|
Packit |
0bbbb1 |
g_arm_reqhandle_in.pcontext = g_arm_callback_context_in;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* register callback */
|
|
Packit |
0bbbb1 |
return raw1394_arm_register( h, CSR_REGISTER_BASE + CSR_I_MPR, sizeof(g_data_in),
|
|
Packit |
0bbbb1 |
(byte_t *) &g_data_in, (unsigned long) &g_arm_reqhandle_in,
|
|
Packit |
0bbbb1 |
0, 0, ( RAW1394_ARM_READ | RAW1394_ARM_LOCK ) );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
void
|
|
Packit |
0bbbb1 |
iec61883_plug_impr_clear (raw1394handle_t h)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
g_data_in.mpr.n_plugs = 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_impr_close (raw1394handle_t h)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
g_data_in.mpr.n_plugs = 0;
|
|
Packit |
0bbbb1 |
return raw1394_arm_unregister(h, CSR_REGISTER_BASE + CSR_I_MPR);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_ipcr_add (raw1394handle_t h, unsigned int online)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
int i = g_data_in.mpr.n_plugs;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* validate parameters */
|
|
Packit |
0bbbb1 |
if (g_arm_reqhandle_in.arm_callback == NULL)
|
|
Packit |
0bbbb1 |
return -EPERM;
|
|
Packit |
0bbbb1 |
if (i + 1 > IEC61883_PCR_MAX)
|
|
Packit |
0bbbb1 |
return -ENOSPC;
|
|
Packit |
0bbbb1 |
if (online >> 1 != 0)
|
|
Packit |
0bbbb1 |
return -EINVAL;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* update data */
|
|
Packit |
0bbbb1 |
g_data_in.pcr[i].online = online;
|
|
Packit |
0bbbb1 |
g_data_in.mpr.n_plugs++;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* return which plug is added */
|
|
Packit |
0bbbb1 |
return i;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_ompr_init (raw1394handle_t h, unsigned int data_rate,
|
|
Packit |
0bbbb1 |
unsigned int bcast_channel)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
/* validate parameters */
|
|
Packit |
0bbbb1 |
if (data_rate >> 2 != 0)
|
|
Packit |
0bbbb1 |
errno = -EINVAL;
|
|
Packit |
0bbbb1 |
if (bcast_channel >> 6 != 0)
|
|
Packit |
0bbbb1 |
errno = -EINVAL;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* initialize data */
|
|
Packit |
0bbbb1 |
memset (&g_data_out, 0, sizeof (g_data_out));
|
|
Packit |
0bbbb1 |
g_data_out.mpr.data_rate = data_rate;
|
|
Packit |
0bbbb1 |
g_data_out.mpr.bcast_channel = bcast_channel;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* initialize host environment */
|
|
Packit |
0bbbb1 |
memset (&g_arm_reqhandle_out, 0, sizeof(g_arm_reqhandle_out));
|
|
Packit |
0bbbb1 |
g_arm_reqhandle_out.arm_callback = (arm_req_callback_t) iec61883_arm_callback;
|
|
Packit |
0bbbb1 |
g_arm_reqhandle_out.pcontext = g_arm_callback_context_out;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* register callback */
|
|
Packit |
0bbbb1 |
return raw1394_arm_register( h, CSR_REGISTER_BASE + CSR_O_MPR, sizeof(g_data_out),
|
|
Packit |
0bbbb1 |
(byte_t *) &g_data_out, (unsigned long) &g_arm_reqhandle_out,
|
|
Packit |
0bbbb1 |
0, 0, ( RAW1394_ARM_READ | RAW1394_ARM_LOCK ) );
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
void
|
|
Packit |
0bbbb1 |
iec61883_plug_ompr_clear (raw1394handle_t h)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
g_data_out.mpr.n_plugs = 0;
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_ompr_close (raw1394handle_t h)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
g_data_out.mpr.n_plugs = 0;
|
|
Packit |
0bbbb1 |
return raw1394_arm_unregister(h, CSR_REGISTER_BASE + CSR_O_MPR);
|
|
Packit |
0bbbb1 |
}
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
int
|
|
Packit |
0bbbb1 |
iec61883_plug_opcr_add (raw1394handle_t h, unsigned int online,
|
|
Packit |
0bbbb1 |
unsigned int overhead_id, unsigned int payload)
|
|
Packit |
0bbbb1 |
{
|
|
Packit |
0bbbb1 |
int i = g_data_out.mpr.n_plugs;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* validate parameters */
|
|
Packit |
0bbbb1 |
if (g_arm_reqhandle_out.arm_callback == NULL)
|
|
Packit |
0bbbb1 |
return -EPERM;
|
|
Packit |
0bbbb1 |
if (i + 1 > IEC61883_PCR_MAX)
|
|
Packit |
0bbbb1 |
return -ENOSPC;
|
|
Packit |
0bbbb1 |
if (online >> 1 != 0)
|
|
Packit |
0bbbb1 |
return -EINVAL;
|
|
Packit |
0bbbb1 |
if (overhead_id >> 4 != 0)
|
|
Packit |
0bbbb1 |
return -EINVAL;
|
|
Packit |
0bbbb1 |
if (payload >> 10 != 0)
|
|
Packit |
0bbbb1 |
return -EINVAL;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* update plug */
|
|
Packit |
0bbbb1 |
g_data_out.pcr[i].online = online;
|
|
Packit |
0bbbb1 |
g_data_out.pcr[i].overhead_id = overhead_id;
|
|
Packit |
0bbbb1 |
g_data_out.pcr[i].payload = payload;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* increment the number of plugs available */
|
|
Packit |
0bbbb1 |
g_data_out.mpr.n_plugs++;
|
|
Packit |
0bbbb1 |
|
|
Packit |
0bbbb1 |
/* return which plug is added */
|
|
Packit |
0bbbb1 |
return i;
|
|
Packit |
0bbbb1 |
}
|