isdn4k-utils/eicon/divautil/linload.c

300 lines
7.3 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[];
extern dword selected_protocol_is_dmlt;
extern char* selected_protocol_code_directory;
extern int selected_bri_code_version;
/*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 bri);
int DivaALoad (char *dsp_name,
dia_config_t *options,
dia_card_t *card,
char *msg , int adapter_instance) {
int card_type = -1;
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 = selected_protocol_code_directory;
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);
}
}
card_type = cards[options->card_id + 1];
#if 0
switch (card_type) {
case 0: printf ("I: PRI Card\n"); break;
case 1: printf ("I: BRI Card\n"); break;
case 2: printf ("I: 4BRI Card\n"); break;
default:
printf ("I: unknown CARD\n");
}
#endif
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);
}
/*
Download protocol code now
*/
if (selected_protocol_is_dmlt & (1 << card_type)) {
char* p = strstr (dsp_name, ".");
strcpy(filename, microcode_dir);
strcat(filename, "te_dmlt");
strcat(filename, p);
if ((fd = open(filename, O_RDONLY, 0)) >= 0) {
close (fd);
} else {
strcpy(filename, microcode_dir);
strcat(filename, dsp_name);
}
} else {
strcpy(filename, microcode_dir);
strcat(filename, dsp_name);
}
/*
Alternative protocol code for BRI ?
*/
if (card_type == 1) {
switch (selected_bri_code_version) {
case 6:
filename[strlen(filename)-1]='6';
break;
default: ;
}
}
// printf ("load %s\n", filename);
/* 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, 0);
} else if (cards[options->card_id + 1] == 1) {
load_combifile(CARDTYPE_MAESTRA_PCI, wFeatures, 1);
} 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, 0);
}
/* 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);
}