Enscript Output

extractedLnx/linux-2.5.9/drivers/isdn/icn/icn.c_icn_command.c

static int
icn_command(isdn_ctrl * c, icn_card * card)
{
	ulong a;
	ulong flags;
	int i;
	char cbuf[60];
	isdn_ctrl cmd;
	icn_cdef cdef;

	switch (c->command) {
		case ISDN_CMD_IOCTL:
			memcpy(&a, c->parm.num, sizeof(ulong));
			switch (c->arg) {
				case ICN_IOCTL_SETMMIO:
					if (dev.memaddr != (a & 0x0ffc000)) {
						if (check_mem_region(a & 0x0ffc000, 0x4000)) {
							printk(KERN_WARNING
							       "icn: memory at 0x%08lx in use.\n",
							       a & 0x0ffc000);
							return -EINVAL;
						}
						icn_stopallcards();
						save_flags(flags);
						cli();
						if (dev.mvalid) {
							iounmap(dev.shmem);
							release_mem_region(dev.memaddr, 0x4000);
						}
						dev.mvalid = 0;
						dev.memaddr = a & 0x0ffc000;
						restore_flags(flags);
						printk(KERN_INFO
						       "icn: (%s) mmio set to 0x%08lx\n",
						       CID,
						       dev.memaddr);
					}
					break;
				case ICN_IOCTL_GETMMIO:
					return (long) dev.memaddr;
				case ICN_IOCTL_SETPORT:
					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) {
						if (card->port != (unsigned short) a) {
							if (check_region((unsigned short) a, ICN_PORTLEN)) {
								printk(KERN_WARNING
								       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
								       CID, (int) a, (int) a + ICN_PORTLEN);
								return -EINVAL;
							}
							icn_stopcard(card);
							save_flags(flags);
							cli();
							if (card->rvalid)
								release_region(card->port, ICN_PORTLEN);
							card->port = (unsigned short) a;
							card->rvalid = 0;
							if (card->doubleS0) {
								card->other->port = (unsigned short) a;
								card->other->rvalid = 0;
							}
							restore_flags(flags);
							printk(KERN_INFO
							       "icn: (%s) port set to 0x%03x\n",
							CID, card->port);
						}
					} else
						return -EINVAL;
					break;
				case ICN_IOCTL_GETPORT:
					return (int) card->port;
				case ICN_IOCTL_GETDOUBLE:
					return (int) card->doubleS0;
				case ICN_IOCTL_DEBUGVAR:
					if ((i = copy_to_user((char *) a,
					  (char *) &card, sizeof(ulong))))
						return i;
					a += sizeof(ulong);
					{
						ulong l = (ulong) & dev;
						if ((i = copy_to_user((char *) a,
							     (char *) &l, sizeof(ulong))))
							return i;
					}
					return 0;
				case ICN_IOCTL_LOADBOOT:
					if (dev.firstload) {
						icn_disable_cards();
						dev.firstload = 0;
					}
					icn_stopcard(card);
					return (icn_loadboot((u_char *) a, card));
				case ICN_IOCTL_LOADPROTO:
					icn_stopcard(card);
					if ((i = (icn_loadproto((u_char *) a, card))))
						return i;
					if (card->doubleS0)
						i = icn_loadproto((u_char *) (a + ICN_CODE_STAGE2), card->other);
					return i;
					break;
				case ICN_IOCTL_ADDCARD:
					if (!dev.firstload)
						return -EBUSY;
					if ((i = copy_from_user((char *) &cdef, (char *) a, sizeof(cdef))))
						return i;
					return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
					break;
				case ICN_IOCTL_LEASEDCFG:
					if (a) {
						if (!card->leased) {
							card->leased = 1;
							while (card->ptype == ISDN_PTYPE_UNKNOWN) {
								schedule_timeout(ICN_BOOT_TIMEOUT1);
							}
							schedule_timeout(ICN_BOOT_TIMEOUT1);
							sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
								(a & 1)?'1':'C', (a & 2)?'2':'C');
							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
							printk(KERN_INFO
							       "icn: (%s) Leased-line mode enabled\n",
							       CID);
							cmd.command = ISDN_STAT_RUN;
							cmd.driver = card->myid;
							cmd.arg = 0;
							card->interface.statcallb(&cmd);
						}
					} else {
						if (card->leased) {
							card->leased = 0;
							sprintf(cbuf, "00;FV2OFF\n");
							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
							printk(KERN_INFO
							       "icn: (%s) Leased-line mode disabled\n",
							       CID);
							cmd.command = ISDN_STAT_RUN;
							cmd.driver = card->myid;
							cmd.arg = 0;
							card->interface.statcallb(&cmd);
						}
					}
					return 0;
				default:
					return -EINVAL;
			}
			break;
		case ISDN_CMD_DIAL:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (card->leased)
				break;
			if ((c->arg & 255) < ICN_BCH) {
				char *p;
				char dial[50];
				char dcode[4];

				a = c->arg;
				p = c->parm.setup.phone;
				if (*p == 's' || *p == 'S') {
					/* Dial for SPV */
					p++;
					strcpy(dcode, "SCA");
				} else
					/* Normal Dial */
					strcpy(dcode, "CAL");
				strcpy(dial, p);
				sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
					dcode, dial, c->parm.setup.si1,
				c->parm.setup.si2, c->parm.setup.eazmsn);
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_ACCEPTD:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (c->arg < ICN_BCH) {
				a = c->arg + 1;
				if (card->fw_rev >= 300) {
					switch (card->l2_proto[a - 1]) {
						case ISDN_PROTO_L2_X75I:
							sprintf(cbuf, "%02d;BX75\n", (int) a);
							break;
						case ISDN_PROTO_L2_HDLC:
							sprintf(cbuf, "%02d;BTRA\n", (int) a);
							break;
					}
					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
				}
				sprintf(cbuf, "%02d;DCON_R\n", (int) a);
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_ACCEPTB:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (c->arg < ICN_BCH) {
				a = c->arg + 1;
				if (card->fw_rev >= 300)
					switch (card->l2_proto[a - 1]) {
						case ISDN_PROTO_L2_X75I:
							sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
							break;
						case ISDN_PROTO_L2_HDLC:
							sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
							break;
				} else
					sprintf(cbuf, "%02d;BCON_R\n", (int) a);
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_HANGUP:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (c->arg < ICN_BCH) {
				a = c->arg + 1;
				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_SETEAZ:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (card->leased)
				break;
			if (c->arg < ICN_BCH) {
				a = c->arg + 1;
				if (card->ptype == ISDN_PTYPE_EURO) {
					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
						c->parm.num[0] ? "N" : "ALL", c->parm.num);
				} else
					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
						c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_CLREAZ:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if (card->leased)
				break;
			if (c->arg < ICN_BCH) {
				a = c->arg + 1;
				if (card->ptype == ISDN_PTYPE_EURO)
					sprintf(cbuf, "%02d;MSNC\n", (int) a);
				else
					sprintf(cbuf, "%02d;EAZC\n", (int) a);
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_SETL2:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if ((c->arg & 255) < ICN_BCH) {
				a = c->arg;
				switch (a >> 8) {
					case ISDN_PROTO_L2_X75I:
						sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
						break;
					case ISDN_PROTO_L2_HDLC:
						sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
						break;
					default:
						return -EINVAL;
				}
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
				card->l2_proto[a & 255] = (a >> 8);
			}
			break;
		case ISDN_CMD_GETL2:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if ((c->arg & 255) < ICN_BCH)
				return card->l2_proto[c->arg & 255];
			else
				return -ENODEV;
		case ISDN_CMD_SETL3:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			return 0;
		case ISDN_CMD_GETL3:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			if ((c->arg & 255) < ICN_BCH)
				return ISDN_PROTO_L3_TRANS;
			else
				return -ENODEV;
		case ISDN_CMD_GETEAZ:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			break;
		case ISDN_CMD_SETSIL:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			break;
		case ISDN_CMD_GETSIL:
			if (!card->flags & ICN_FLAGS_RUNNING)
				return -ENODEV;
			break;
		case ISDN_CMD_LOCK:
			MOD_INC_USE_COUNT;
			break;
		case ISDN_CMD_UNLOCK:
			MOD_DEC_USE_COUNT;
			break;
		default:
			return -EINVAL;
	}
	return 0;
}

Generated by GNU enscript 1.6.4.