/* $Id: icnctrl.c,v 1.6 2007/03/05 18:04:35 keil Exp $ * ICN-ISDN driver for Linux. (Control-Utility) * * Copyright 1994,95 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995 Thinking Objects Software GmbH Wuerzburg * * This file is part of Isdn4Linux. * * 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; without even the 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. * * $Log: icnctrl.c,v $ * Revision 1.6 2007/03/05 18:04:35 keil * Small fixes to avoid warnings with newer gcc * * Revision 1.5 2002/01/31 18:55:45 paul * #include for prototypes against warnings. * * Revision 1.4 1999/09/06 08:03:24 fritz * Changed my mail-address. * * Revision 1.3 1997/06/21 14:38:22 fritz * Added option for enabling only one channel in leased mode. * * Revision 1.2 1997/05/17 12:23:29 fritz * Corrected some Copyright notes to refer to GPL. * * Revision 1.1 1997/02/17 00:08:53 fritz * New CVS tree * * Revision 1.2 1996/11/22 15:04:25 fritz * Minor cosmetix fix. * * Revision 1.1.1.1 1996/10/08 10:03:12 fritz * First Import. * * Revision 1.6 1995/12/18 18:25:24 fritz * Support for ICN-4B Cards. * * Revision 1.5 1995/10/29 21:44:02 fritz * Changed to support DriverId's. * Added support for leased lines. * * Revision 1.4 1995/04/23 13:43:02 fritz * Changed Copyright. * * Revision 1.3 1995/02/01 11:03:26 fritz * Added Messages, when loading bootcode and protocol. * * Revision 1.2 1995/01/09 07:41:59 fritz * Added GPL-Notice * * */ #include #include #include #include #include #include #include #include #ifdef __DEBUGVAR__ #define __KERNEL__ #endif #include #ifdef __DEBUGVAR__ typedef struct dbgstruct { ulong card; ulong dev; } dbgstruct; dbgstruct dbg; #endif int mem_fd; char *cmd; char *ctrldev; int arg_ofs; #if 0 /* #ifdef _POSIX_MAPPED_FILES */ #define DO_VIA_MMAP #else #include #endif void usage() { fprintf(stderr, "usage: %s [-d driverId] io [mmio port] (get/set hw-io)\n", cmd); #ifdef __DEBUGVAR__ fprintf(stderr, " or: %s [-d driverId] dump (dump driver data)\n", cmd); #endif fprintf(stderr, " or: %s [-d driverId] add [id1 [id2]] (Add a new card\n", cmd); fprintf(stderr, " or: %s [-d driverId] load (load firmware)\n", cmd); fprintf(stderr, " or: %s [-d driverId] leased <1|2|on|off> (Switch interface,\n",cmd); fprintf(stderr, " Channel n\n"); fprintf(stderr, " into Leased-Line-Mode)\n"); exit(-1); } #ifdef __DEBUGVAR__ u_char * mapmem(ulong where, long size) { u_char *addr; #ifdef DO_VIA_MMAP ulong realw; long ofs; #endif if ((mem_fd = open("/dev/mem", O_RDWR)) < 0) { perror("open /dev/mem"); exit(1); } #ifdef DO_VIA_MMAP size = ((size / PAGE_SIZE) + 2) * PAGE_SIZE; realw = PAGE_ALIGN(where) - PAGE_SIZE; ofs = where - realw; printf("%08lx - %08lx = %08x\n", where, realw, ofs); addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, mem_fd, realw); if ((int) addr < 0) { perror("mmap"); exit(1); } return (addr + ofs); #else addr = malloc(size); lseek(mem_fd, where, SEEK_SET); read(mem_fd, addr, size); return addr; #endif } void dump_dev(icn_dev * p) { printf("dev struct at: %p\n", p); printf("phys. dev struct at: 0x%08lx\n", dbg.dev); printf("shmem: %p\n", p->shmem); printf("mvalid: %d\n", p->mvalid); printf("channel: %d\n", p->channel); printf("mcard: %p\n", p->mcard); printf("chanlock: %d\n", p->chanlock); printf("firstload: %d\n", p->firstload); } void qdump(ulong queue) { struct sk_buff_head *p; p = (struct sk_buff_head *) mapmem(queue, sizeof(struct sk_buff_head)); printf(" len: %d\n", p->qlen); } void dump_card(icn_card * p) { printf("card struct at: %p\n", p); printf("phys. card struct at: 0x%08lx\n", dbg.card); printf("next: %p\n", p->next); printf("other: %p\n", p->other); printf("port: 0x%04x\n", p->port); printf("myid: %d\n", p->myid); printf("rvalid: %d\n", p->rvalid); printf("leased: %d\n", p->leased); printf("flags: 0x%04x\n", p->flags); printf("doubleS0: %d\n", p->doubleS0); printf("secondhalf: %d\n", p->secondhalf); printf("fw_rev: %d\n", p->fw_rev); printf("ptype: %d\n", p->ptype); printf("st_timer\n"); printf("rb_timer\n"); printf("rcvbuf\n"); printf("rcvidx[0]: %d\n", p->rcvidx[0]); printf("rcvidx[1]: %d\n", p->rcvidx[1]); printf("l2_proto[0] %d\n", p->l2_proto[0]); printf("l2_proto[1] %d\n", p->l2_proto[1]); printf("interface:\n"); printf("iptr: %d\n", p->iptr); printf("imsg: %s\n", p->imsg); printf("msg_buf: %p\n", p->msg_buf); printf("msg_buf_write: %p\n", p->msg_buf_write); printf("msg_buf_read: %p\n", p->msg_buf_read); printf("msg_buf_end: %p\n", p->msg_buf_end); printf("sndcount[0]: %d\n", p->sndcount[0]); printf("sndcount[1]: %d\n", p->sndcount[1]); printf("spqueue[0]: %p\n", &p->spqueue[0]); qdump((ulong) & p->spqueue[0]); printf("spqueue[1]: %p\n", &p->spqueue[1]); qdump((ulong) & p->spqueue[1]); printf("regname: %s\n", p->regname); printf("xmit_lock[0]: %d\n", p->xmit_lock[0]); printf("xmit_lock[1]: %d\n", p->xmit_lock[1]); } #endif int main(int argc, char **argv) { int fd; FILE *code; int mmio, port; int ac; int a; u_char buf[0x20000]; isdn_ioctl_struct ioctl_s; icn_cdef newcard; cmd = strrchr(argv[0], '/'); cmd = (cmd == NULL) ? argv[0] : cmd + 1; if (argc > 1) { if (!strcmp(argv[1], "-d")) { strcpy(ioctl_s.drvid, argv[2]); arg_ofs = 3; } else { ioctl_s.drvid[0] = '\0'; arg_ofs = 1; } } else usage(); ac = argc - (arg_ofs - 1); fd = open("/dev/isdnctrl", O_RDWR); if (fd < 0) { perror(ctrldev); exit(-1); } #ifdef __DEBUGVAR__ if (!strcmp(argv[arg_ofs], "dump")) { char *p; ioctl_s.arg = (ulong) & dbg; if ((ioctl(fd, ICN_IOCTL_DEBUGVAR + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl DEBUGVAR"); exit(-1); } close(fd); p = mapmem(dbg.dev, sizeof(icn_dev)); dump_dev((icn_dev *) p); p = mapmem(dbg.card, sizeof(icn_card)); dump_card((icn_card *) p); return 0; } #endif if (!strcmp(argv[arg_ofs], "leased")) { if (ac == 3) { ioctl_s.arg = 0; if ((!strcmp(argv[arg_ofs + 1], "on")) || (!strcmp(argv[arg_ofs + 1], "2")) || (!strcmp(argv[arg_ofs + 1], "yes"))) ioctl_s.arg = 3; if (!strcmp(argv[arg_ofs + 1], "1")) ioctl_s.arg = 1; if ((ioctl(fd, ICN_IOCTL_LEASEDCFG + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl LEASEDCFG"); exit(-1); } close(fd); return 0; } } if (!strcmp(argv[arg_ofs], "add")) { if (ac >= 3) { sscanf(argv[arg_ofs + 1], "%i", &a); if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330 || a == 0x340 || a == 0x350 || a == 0x360 || a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338 || a == 0x348 || a == 0x358 || a == 0x368) { ioctl_s.arg = (unsigned long) &newcard; newcard.port = a; newcard.id1[0] = 0; newcard.id2[0] = 0; if (ac >= 4) strncpy(newcard.id1, argv[arg_ofs + 2], sizeof(newcard.id1) - 1); if (ac == 5) strncpy(newcard.id2, argv[arg_ofs + 3], sizeof(newcard.id2) - 1); if ((ioctl(fd, ICN_IOCTL_ADDCARD + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl ADDCARD"); exit(-1); } close(fd); return 0; } } } if (!strcmp(argv[arg_ofs], "io")) { if (ac == 4) { if (sscanf(argv[arg_ofs + 1], "%i", &mmio) != 1) usage(); if (sscanf(argv[arg_ofs + 2], "%i", &port) != 1) usage(); ioctl_s.arg = mmio; if ((mmio = ioctl(fd, ICN_IOCTL_SETMMIO + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl SETMMIO"); exit(-1); } ioctl_s.arg = port; if ((port = ioctl(fd, ICN_IOCTL_SETPORT + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl SETPORT"); exit(-1); } } if ((mmio = ioctl(fd, ICN_IOCTL_GETMMIO + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl GETMMIO"); exit(-1); } if ((port = ioctl(fd, ICN_IOCTL_GETPORT + IIOCDRVCTL, &ioctl_s)) < 0) { perror("ioctl GETPORT"); exit(-1); } printf("Memory-mapped io at 0x%08lx, port 0x%03x\n", (unsigned long) mmio, (unsigned short) port); close(fd); return 0; } if (!strcmp(argv[arg_ofs], "load")) { int needed; switch (ioctl(fd, ICN_IOCTL_GETDOUBLE + IIOCDRVCTL, &ioctl_s)) { case 0: needed = 4; break; case 1: needed = 5; break; default: perror("ioctl GETDOUBLE"); exit(-1); } if (ac == needed) { if (!(code = fopen(argv[arg_ofs + 1], "r"))) { perror(argv[arg_ofs + 1]); exit(-1); } if (fread(buf, 4096, 1, code) < 1) { fprintf(stderr, "Read error on %s\n", argv[arg_ofs + 1]); exit(-1); } printf("Loading Bootcode %s ... ", argv[arg_ofs + 1]); fflush(stdout); ioctl_s.arg = (ulong) buf; if (ioctl(fd, ICN_IOCTL_LOADBOOT + IIOCDRVCTL, &ioctl_s) < 0) { perror("\nioctl LOADBOOT"); exit(-1); } fclose(code); printf("done\n"); if (!(code = fopen(argv[arg_ofs + 2], "r"))) { perror(argv[arg_ofs + 2]); exit(-1); } if (fread(buf, 65536, 1, code) < 1) { fprintf(stderr, "Read error on %s\n", argv[arg_ofs + 2]); exit(-1); } fclose(code); if (needed == 5) { if (!(code = fopen(argv[arg_ofs + 3], "r"))) { perror(argv[arg_ofs + 3]); exit(-1); } if (fread(buf + 65536, 65536, 1, code) < 1) { fprintf(stderr, "Read error on %s\n", argv[arg_ofs + 3]); exit(-1); } fclose(code); printf("Loading Protocols %s\n", argv[arg_ofs + 2]); printf(" and %s ... ", argv[arg_ofs + 3]); } else printf("Loading Protocol %s ... ", argv[arg_ofs + 2]); fflush(stdout); ioctl_s.arg = (ulong) buf; if (ioctl(fd, ICN_IOCTL_LOADPROTO + IIOCDRVCTL, &ioctl_s) < 0) { perror("\nioctl LOADPROTO"); exit(-1); } printf("done\n"); close(fd); return 0; } usage(); } usage(); return 0; }