diff --git a/avmb1/avmcapictrl.c b/avmb1/avmcapictrl.c index d51add17..e0069fce 100644 --- a/avmb1/avmcapictrl.c +++ b/avmb1/avmcapictrl.c @@ -1,11 +1,14 @@ /* - * $Id: avmcapictrl.c,v 1.2 1997/03/20 00:18:57 luethje Exp $ + * $Id: avmcapictrl.c,v 1.3 1997/12/07 20:02:22 calle Exp $ * * AVM-B1-ISDN driver for Linux. (Control-Utility) * * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: avmcapictrl.c,v $ + * Revision 1.3 1997/12/07 20:02:22 calle + * prepared support for cardtype and different protocols + * * Revision 1.2 1997/03/20 00:18:57 luethje * inserted the line #include in avmb1/avmcapictrl.c and imon/imon.c, * some bugfixes, new structure in isdnlog/isdnrep/isdnrep.c. @@ -42,12 +45,146 @@ int arg_ofs; void usage(void) { - fprintf(stderr, "usage: %s add (Add a new card)\n", cmd); - fprintf(stderr, " or: %s load [contrnr] (load firmware)\n", cmd); + fprintf(stderr, "usage: %s add [B1|M1|T1] (Add a new card)\n", cmd); + fprintf(stderr, " or: %s load [contrnr [protocol [P2P]]] (load firmware)\n", cmd); fprintf(stderr, " or: %s reset [contrnr] (reset controller)\n", cmd); exit(1); } +#define DP_NONE 0 +#define DP_DSS1 1 +#define DP_D64S 2 +#define DP_D64S2 3 +#define DP_D64SD 4 +#define DP_DS01 5 +#define DP_DS02 6 +#define DP_CT1 7 +#define DP_VN3 8 +#define DP_AUSTEL 9 +#define DP_5ESS 10 /* need SPID,SPID2,DN,DN2 */ +#define DP_NI1 11 /* need SPID,SPID2,DN,DN2 */ +#define DP_DSS1MOBIL 12 +#define DP_1TR6MOBIL 13 +#define DP_GSM 14 +#define DP_1TR6 15 + +static struct pmap { + char *name; + int protocol; +} pmap[] = { + { "DSS1", DP_DSS1 }, + { "D64S", DP_D64S }, + { "D64S2", DP_D64S2 }, + { "D64SD", DP_D64SD }, + { "DS01", DP_DS01 }, + { "DS02", DP_DS02 }, + { "CT1", DP_CT1 }, + { "VN3", DP_VN3 }, + { "AUSTEL", DP_AUSTEL }, + { "5ESS", DP_5ESS }, + { "NI1", DP_NI1 }, + { "DSS1MOBIL", DP_DSS1MOBIL }, + { "1TR6MOBIL", DP_1TR6MOBIL }, + { "GSM", DP_GSM }, + { "1TR6", DP_1TR6 }, + { 0 }, +}; + +static int dchan_protocol(char *pname) +{ + struct pmap *p; + for (p=pmap; p->name; p++) { + if (strcasecmp(pname, p->name) == 0) + return p->protocol; + } + return DP_NONE; +} + +static char patcharea[2048]; +static int patchlen = 0; + +static void addpatchvalue(char *name, char *value, int len) +{ + int nlen = strlen(name); + if (patchlen + nlen + len + 2 >= sizeof(patcharea)) { + fprintf(stderr, "%s: can't add patchvalue %s\n" , cmd, name); + exit(3); + } + memcpy(&patcharea[patchlen], name, nlen); + patchlen += nlen; + patcharea[patchlen++] = 0; + memcpy(&patcharea[patchlen], value, len); + patcharea[patchlen++] = 0; + patcharea[patchlen+1] = 0; +} + +int set_configuration(avmb1_t4file *t4config, int protocol, int p2p) +{ + addpatchvalue("AutoFrame", "\001", 1); + addpatchvalue("WATCHDOG", "1", 1); + addpatchvalue("CWEnable", "1", 1); + switch (protocol) { + case DP_NONE: + break; + case DP_DSS1: + break; + case DP_D64S: + addpatchvalue("MpriOneChannel", "1", 1); + case DP_D64S2: + case DP_D64SD: + p2p = 0; + addpatchvalue("TEI", "\000", 1); + addpatchvalue("FV2", "2", 1); + addpatchvalue("MpriD64S", "1", 1); + break; + case DP_DS01: + addpatchvalue("MpriOneChannel", "1", 1); + case DP_DS02: + p2p = 0; + addpatchvalue("TEI", "\000", 1); + addpatchvalue("FV2", "1", 1); + break; + case DP_CT1: + addpatchvalue("PROTOCOL", "\001", 1); + break; + case DP_VN3: + addpatchvalue("PROTOCOL", "\002", 1); + break; + case DP_AUSTEL: + addpatchvalue("PROTOCOL", "\004", 1); + break; + case DP_NI1: + addpatchvalue("PROTOCOL", "\003", 1); + break; /* $$$ */ + case DP_5ESS: + addpatchvalue("PROTOCOL", "\005", 1); + break; /* $$$ */ + case DP_DSS1MOBIL: + addpatchvalue("PatchMobileMode", "0", 1); + break; + case DP_1TR6MOBIL: + addpatchvalue("PatchMobileMode", "0", 1); + break; + case DP_GSM: + addpatchvalue("MpriOneChannel", "1", 1); + addpatchvalue("MpriNoV42bis", "1", 1); + break; + case DP_1TR6: + addpatchvalue("MpriSemi", "1", 1); + break; + default: + return -1; + } + if (p2p) { + addpatchvalue("P2P", "\001", 1); + addpatchvalue("TEI", "\000", 1); + addpatchvalue("MpriDDI", "1", 1); + } + t4config->len = patchlen+1; + t4config->data = patcharea; + return 0; +} + int validports[] = {0x150, 0x250, 0x300, 0x340, 0}; int validirqs[] = @@ -58,10 +195,11 @@ int main(int argc, char **argv) int fd; int ac; capi_manufacturer_cmd ioctl_s; - avmb1_carddef newcard; - avmb1_loaddef ldef; + avmb1_extcarddef newcard; + avmb1_loadandconfigdef ldef; avmb1_resetdef rdef; - int port, irq; + avmb1_getdef gdef; + int newdriver; cmd = strrchr(argv[0], '/'); cmd = (cmd == NULL) ? argv[0] : ++cmd; @@ -86,11 +224,39 @@ int main(int argc, char **argv) perror("/dev/capi20"); exit(-1); } - if (!strcmp(argv[arg_ofs], "add")) { + gdef.contr = 0; + ioctl_s.cmd = AVMB1_GET_CARDINFO; + ioctl_s.data = &gdef; + newdriver = 0; + + if ((ioctl(fd, CAPI_MANUFACTURER_CMD, &ioctl_s)) < 0) { + if (errno != EINVAL) + newdriver = 1; + } else { + newdriver = 1; + } + + if (!strcasecmp(argv[arg_ofs], "add")) { + int port, irq, cardtype; if (ac >= 4) { int i; sscanf(argv[arg_ofs + 1], "%i", &port); sscanf(argv[arg_ofs + 2], "%i", &irq); + if (argv[arg_ofs + 3]) { + if (strcasecmp(argv[arg_ofs + 3],"B1") == 0) { + cardtype = AVM_CARDTYPE_B1; + } else if (strcasecmp(argv[arg_ofs + 3],"M1") == 0) { + cardtype = AVM_CARDTYPE_M1; + } else if (strcasecmp(argv[arg_ofs + 3],"T1") == 0) { + cardtype = AVM_CARDTYPE_T1; + } else { + fprintf(stderr, "%s: illegal cardtype \"%s\"\n", cmd, argv[arg_ofs + 3]); + fprintf(stderr, "%s: try one of B1,M1,T1", cmd); + exit(-1); + } + } else { + cardtype = AVM_CARDTYPE_B1; + } for (i = 0; validports[i] && port != validports[i]; i++); if (!validports[i]) { fprintf(stderr, "%s: illegal io-addr 0x%x\n", cmd, port); @@ -111,7 +277,14 @@ int main(int argc, char **argv) } newcard.port = port; newcard.irq = irq; - ioctl_s.cmd = AVMB1_ADDCARD; + newcard.cardtype = cardtype; + if (!newdriver && cardtype != AVM_CARDTYPE_B1) { + fprintf(stderr, "%s: only B1 supported by kernel driver, sorry\n", cmd); + exit(1); + } + if (newdriver) + ioctl_s.cmd = AVMB1_ADDCARD_WITH_TYPE; + else ioctl_s.cmd = AVMB1_ADDCARD; ioctl_s.data = &newcard; if ((ioctl(fd, CAPI_MANUFACTURER_CMD, &ioctl_s)) < 0) { perror("ioctl ADDCARD"); @@ -121,21 +294,47 @@ int main(int argc, char **argv) return 0; } } - if (!strcmp(argv[arg_ofs], "load")) { + if (!strcasecmp(argv[arg_ofs], "load")) { struct stat st; int codefd; int contr = 1; + int protocol = 0; + int p2p = 0; if (ac > 3) contr = atoi(argv[arg_ofs + 2]); + if (ac > 4) { + if (!newdriver) { + fprintf(stderr, "%s: need newer kernel driver to set protocol\n", + cmd); + exit(1); + } + protocol = dchan_protocol(argv[arg_ofs + 3]); + if (protocol < 0) { + fprintf(stderr,"invalid protocol \"%s\"\n", + argv[arg_ofs + 3]); + /* show_protocols(); */ + exit(1); + } + } + if (ac > 5) { + if (strcasecmp(argv[arg_ofs + 4], "P2P") == 0) { + p2p = 1; + } else { + fprintf(stderr,"parameter should be P2P not \"%s\"\n", + argv[arg_ofs + 4]); + exit(1); + } + } + if (stat(argv[arg_ofs + 1], &st)) { perror(argv[arg_ofs + 1]); exit(2); } if (!(codefd = open(argv[arg_ofs + 1], O_RDONLY))) { perror(argv[arg_ofs + 1]); - exit(-1); + exit(2); } ldef.contr = contr; ldef.t4file.len = st.st_size; @@ -144,9 +343,16 @@ int main(int argc, char **argv) perror("mmap"); exit(2); } + + ldef.t4config.len = 0; + ldef.t4config.data = 0; + if (protocol || p2p) + set_configuration(&ldef.t4config, protocol, p2p); printf("Loading Bootcode %s ... ", argv[arg_ofs + 1]); fflush(stdout); - ioctl_s.cmd = AVMB1_LOAD; + if (newdriver) + ioctl_s.cmd = AVMB1_LOAD_AND_CONFIG; + else ioctl_s.cmd = AVMB1_LOAD; ioctl_s.data = &ldef; if ((ioctl(fd, CAPI_MANUFACTURER_CMD, &ioctl_s)) < 0) { perror("\nioctl LOAD"); @@ -158,7 +364,7 @@ int main(int argc, char **argv) printf("done\n"); return 0; } - if (!strcmp(argv[arg_ofs], "reset")) { + if (!strcasecmp(argv[arg_ofs], "reset")) { int contr = 1; if (ac > 2)