isdn4k-utils/eicon/divautil/linload.c

274 lines
6.4 KiB
C

/*
*
* Copyright (C) Eicon Technology Corporation, 2000.
*
* This source file is supplied for the exclusive use with Eicon
* Technology Corporation's range of DIVA Server Adapters.
*
* Eicon File Revision : 1.8
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* Source file for Unix Diva card library
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/*#include <ioctls.h>*/
#include "sys.h"
#include "pc_maint.h"
#include "divas.h"
#include "load.h"
#include "diva.h"
#include "diload.h"
#include "cardtype.h"
#include "linuxcfg.h"
int card_id;
extern byte new_cards[];
extern byte cards[];
/*int sprintf(char *,char *,...);*/
void *malloc(size_t);
/*
* load the specified buffer containing DSP code onto the Diva card
*/
void load_combifile(int card_type, word wFeatures);
int DivaALoad(char *dsp_name, dia_config_t *options, dia_card_t *card, char *msg , int adapter_instance)
{
int loadfd; /* Divas file pointer */
int fd; /* file pointer */
struct stat file_info; /* info about file */
dia_load_t load; /* information to load */
char *microcode_dir = DATADIR "/";
char filename[100];
dia_start_t start;
int rc;
char *pFeatureString;
word wFeatures = 0;
card_id = load.card_id = options->card_id;
start.card_id = options->card_id;
/* open the Divas device */
if ((loadfd = open(DIVAS_DEVICE_DFS, O_RDONLY, 0)) < 0)
if ((loadfd = open(DIVAS_DEVICE, O_RDONLY, 0)) == -1)
{
sprintf(msg,DIVAS_DEVICE);
return(ERR_ETDD_OPEN);
}
card = NULL;
/* if we have command line options configured */
if( card )
{
/* pass them down to the driver. */
if((rc = ioctl(loadfd, DIA_IOCTL_INIT, card)) == -1)
{
fprintf(stderr, "%s INIT Error %d\n", DIVAS_DEVICE, rc);
(void)close(loadfd);
return(ERR_ETDD_IOCTL);
}
}
if ((cards[options->card_id + 1] == 2) &&
(adapter_instance == 4)) // Only on first 4BRI virtual adapter
{
strcpy(filename, microcode_dir);
strcat(filename, "/ds4bri.bit");
if ((fd = open(filename, O_RDONLY, 0)) == -1)
{
sprintf(msg,dsp_name);
(void)close(loadfd);
return(ERR_ETDD_DSP);
}
if (fstat(fd, &file_info))
{
sprintf(msg,dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_ACCESS);
}
if ( file_info.st_size <= 0 )
{
sprintf(msg,"file error (%s)",dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_READ);
}
if (!(load.code = malloc(file_info.st_size)))
{
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_NOMEM);
}
if (read(fd, load.code, file_info.st_size) != file_info.st_size)
{
sprintf(msg,"format error, %s", dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_READ);
}
load.length = file_info.st_size;
load.code_type=DIA_FPGA_CODE;
if((ioctl(loadfd, DIA_IOCTL_LOAD, &load)) == -1)
{
fprintf(stderr, "%s LOAD\n", DIVAS_DEVICE);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_IOCTL);
}
free(load.code);
close(fd);
}
/* open file containing DSP code */
strcpy(filename, microcode_dir);
strcat(filename, dsp_name);
/* open this DSP binary for reading */
if ((fd = open(filename, O_RDONLY, 0)) == -1)
{
sprintf(msg,dsp_name);
(void)close(loadfd);
return(ERR_ETDD_DSP);
}
if (fstat(fd, &file_info))
{
sprintf(msg,dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_ACCESS);
}
if ( file_info.st_size <= 0 )
{
sprintf(msg,"file error (%s)",dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_READ);
}
/* allocate a buffer and read contents of file into buffer */
if (!(load.code = malloc(file_info.st_size)))
{
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_NOMEM);
}
if (read(fd, load.code, file_info.st_size) != file_info.st_size)
{
sprintf(msg,"format error, %s", dsp_name);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_READ);
}
pFeatureString = (char *) strstr(&load.code[0x80], "[F#");
pFeatureString += 3;
wFeatures = strtol(pFeatureString,NULL, 16);
load.length = file_info.st_size;
load.code_type=DIA_CPU_CODE;
/* assign buffers and length and pass ioctl to /dev/Divas */
if((ioctl(loadfd, DIA_IOCTL_LOAD, &load)) == -1)
{
fprintf(stderr, "%s LOAD\n", DIVAS_DEVICE);
(void)close(loadfd);
(void)close(fd);
return(ERR_ETDD_IOCTL);
}
free(load.code);
(void) close(fd);
(void) close(loadfd);
if (cards[options->card_id + 1] == 0)
{
load_combifile(CARDTYPE_DIVASRV_P_9M_PCI, wFeatures);
}
else if (cards[options->card_id + 1] == 1)
{
load_combifile(CARDTYPE_MAESTRA_PCI, wFeatures);
}
else if ((cards[options->card_id + 1] == 2) &&
(adapter_instance == 1)) // Only on last 4BRI virtual adapter
{
load_combifile(CARDTYPE_DIVASRV_Q_8M_PCI, wFeatures);
}
/* open the Divas device */
if ((loadfd = open(DIVAS_DEVICE_DFS, O_RDONLY, 0)) < 0)
if ((loadfd = open(DIVAS_DEVICE, O_RDONLY, 0)) == -1)
{
sprintf(msg,DIVAS_DEVICE);
return(ERR_ETDD_OPEN);
}
if((ioctl(loadfd, DIA_IOCTL_CONFIG, options)) == -1)
{
fprintf(stderr, "%s CONFIG\n", DIVAS_DEVICE);
(void)close(loadfd);
return(ERR_ETDD_IOCTL);
}
/* Inform /dev/Divas that loading is finished */
if (adapter_instance == 1) // only do this once
{
if((ioctl(loadfd, DIA_IOCTL_START, &start)) == -1)
{
fprintf(stderr, "%s START\n", DIVAS_DEVICE);
(void)close(loadfd);
return(ERR_ETDD_IOCTL);
}
}//if (adapter_instance == 1)
(void)close(loadfd);
return(ERR_ETDD_OK);
}